Pkg.jl

Mengelola proyek dengan Pkg.jl, meliputi Project.toml, Manifest.toml, dan resolusi dependensi.

Daftar isi

Pkg.jl adalah manajer package bawaan Julia yang mengatur seluruh pekerjaan instalasi, pemuatan, dan pembaruan pustaka. Topik ini membahas dua berkas yang membentuk sebuah proyek, yaitu Project.toml dan Manifest.toml, perintah-perintah dasar pada mode package REPL, serta cara resolusi dependensi menetapkan versi package. Setelah topik ini dipraktikkan, sebuah proyek dapat dibuat, diisi package, dan dipindahkan ke mesin lain dengan versi yang persis sama.

Proyek sebagai unit kerja#

Proyek Julia adalah folder yang berisi Project.toml dan Manifest.toml. Project.toml mencatat identitas proyek beserta daftar package yang dipakai langsung, sedangkan Manifest.toml mencatat seluruh graf dependensi dengan versi persis untuk setiap package. Pembagian ini memisahkan kebutuhan yang dinyatakan secara eksplisit (Project) dari keadaan yang ditetapkan resolusi (Manifest).

toml Project.toml
name = "AlatRapiah"
uuid = "7a1f4d3e-9c2b-4a5e-b8f0-1d2e3f4a5b6c"
version = "0.1.0"

[deps]

Berkas Project.toml di atas memuat tiga informasi dasar. Nilai name menyatakan nama proyek, uuid menyatakan pengenal unik universal yang dihasilkan Pkg saat proyek dibuat, dan version menyatakan nomor versi. Bagian [deps] yang kosong menyatakan bahwa proyek belum memakai package apa pun. UUID pada contoh hanya untuk ilustrasi format, karena nilai sebenarnya dihasilkan oleh Pkg dan berbeda untuk setiap proyek.

Manifest.toml tidak ditulis dengan tangan. Berkas ini dihasilkan Pkg setiap kali operasi add, remove, atau update dijalankan, dan isinya mencakup UUID, nomor versi, dan checksum setiap package dalam graf dependensi. Karena seluruh graf tercatat, proyek yang dibagikan beserta Manifest-nya dapat diinstal ulang pada mesin lain dalam keadaan yang persis sama melalui perintah instantiate.

Mode package pada REPL#

Perintah Pkg yang paling sering dipakai diakses melalui mode package REPL, yaitu mode yang dimasuki dengan menekan ] pada prompt. Pada mode ini, perintah ditulis tanpa tanda kurung dan berlaku untuk lingkungan yang sedang aktif.

text Transkrip REPL
julia> ]
(@v1.13) pkg> status
Status `~/proyek/Project.toml` (empty project)

(@v1.13) pkg> activate .
Activating project at `~/proyek`

(@kerja) pkg> status
Status `~/proyek/Project.toml` (empty project)

Transkrip di atas memperlihatkan tiga langkah yang berulang pada pekerjaan sehari-hari. Perintah status menampilkan isi lingkungan yang aktif dan pesan (empty project) berarti belum ada package tercatat. Perintah activate . mengaktifkan proyek pada folder saat ini, dan prompt berubah menjadi (@kerja) pkg> untuk menandai bahwa lingkungan yang aktif sudah bukan lingkungan bawaan. Mode package ditinggalkan dengan menekan Backspace pada prompt kosong atau Ctrl+C.

Mengoperasikan package dengan Pkg API#

Seluruh perintah mode package juga tersedia sebagai fungsi pada modul Pkg, sehingga dapat dipanggil dari skrip. Contoh berikut membuat proyek sementara, mengaktifkannya, lalu menampilkan isi berkasnya. Panggilan Pkg.activate menampilkan pesan yang memuat jalur sementara yang berubah-ubah, sehingga pesan itu diredam dengan redirect_stdout agar keluaran contoh tetap dapat dibandingkan dari satu eksekusi ke eksekusi lain.

julia Contoh: membuat dan membaca proyek sementara
using Pkg

proyek = mktempdir()
redirect_stdout(devnull) do
    Pkg.activate(proyek)
end

tulis = """
name = "AlatRapiah"
uuid = "7a1f4d3e-9c2b-4a5e-b8f0-1d2e3f4a5b6c"
version = "0.1.0"
"""
write(joinpath(proyek, "Project.toml"), tulis)
println(read(joinpath(proyek, "Project.toml"), String))
text Keluaran
name = "AlatRapiah"
uuid = "7a1f4d3e-9c2b-4a5e-b8f0-1d2e3f4a5b6c"
version = "0.1.0"

Fungsi Pkg.generate menawarkan cara lain untuk membuat proyek. Fungsi ini membuat folder bernama sesuai package, mengisi Project.toml dengan UUID yang sah, dan menyediakan folder src dengan berkas modulnya. Nilai kembalinya adalah kamus yang memasangkan nama package dengan UUID-nya. Contoh berikut memanggil Pkg.generate pada folder sementara dan menampilkan isi proyek yang dihasilkan.

julia Contoh: menghasilkan proyek dengan Pkg.generate
using Pkg

dir = mktempdir()
hasil = redirect_stdout(devnull) do
    Pkg.generate(joinpath(dir, "AlatRapiah"))
end
println(first(keys(hasil)))
println(join(readdir(joinpath(dir, "AlatRapiah")), ", "))
text Keluaran
AlatRapiah
Project.toml, src

Pada proyek nyata, Pkg.activate("path/proyek") dan Pkg.instantiate() dipasangkan sebagai langkah awal sebelum pekerjaan dimulai. Kombinasi ini memastikan seluruh package pada Manifest diunduh dan di-precompile sesuai catatan proyek, bukan menurut keadaan terkini registry.

Resolusi dependensi#

Resolusi dependensi adalah proses memilih satu versi untuk setiap package sehingga seluruh kendala terpenuhi. Kendala bersumber dari dua tempat, yaitu bagian [compat] pada Project.toml yang menyatakan rentang versi yang diterima, serta persyaratan antar package pada registry. Pemilih versi (resolver) mencari kombinasi yang memenuhi semuanya, lalu hasilnya ditulis ke Manifest.toml.

Operasi add menjalankan resolusi lalu memasang versi yang terpilih, sedangkan update menjalankan resolusi ulang agar versi dapat naik ke batas yang masih diizinkan oleh [compat]. Perintah remove mengeluarkan package dari Project.toml dan menghapus entri yang tidak lagi dipakai dari Manifest. Selama berkas Manifest tidak diubah manual, proyek yang sama menghasilkan graf versi yang sama pada setiap eksekusi resolusi.

text Transkrip REPL
(@kerja) pkg> add DataFrames
   Resolving package versions...
    Updating `~/proyek/Project.toml`
  [a93c6f00] + DataFrames v1.8.0
    Updating `~/proyek/Manifest.toml`
  [a93c6f00] + DataFrames v1.8.0
  ⋮ (enam belas dependensi lain tercatat)

(@kerja) pkg> status
Status `~/proyek/Project.toml`
  [a93c6f00] DataFrames v1.8.0

Transkrip di atas menunjukkan pola keluaran add: entri ditambahkan pada Project.toml dan seluruh dependensinya tercatat pada Manifest.toml. Nomor versi pada transkrip bergantung pada keadaan registry saat perintah dijalankan, sehingga nilai persisnya dapat berbeda pada masa lain. Bagian [compat] yang disebutkan pada proyek jangka panjang menjaga rentang versi agar kenaikan versi tidak mengubah perilaku secara tiba-tiba.

Kesalahan umum#

Kesalahan yang paling sering terjadi adalah memasang package pada lingkungan bawaan. Bila add dijalankan tanpa mengaktifkan proyek terlebih dahulu, package tercatat pada lingkungan @v1.13 yang dipakai bersama oleh semua proyek, sehingga proyek kehilangan peta dependensinya dan pemindahan ke mesin lain tidak lengkap. Kebiasaan yang benar adalah menjalankan activate . pada folder proyek sebelum operasi apa pun, dan memeriksa status sebagai verifikasi.

Kesalahan berikutnya adalah mengedit Manifest.toml secara manual. Berkas ini dihitung oleh proses resolusi, sehingga suntingan tangan dapat membuat berkas tidak konsisten dan instantiate gagal dengan pesan checksum atau versi yang tidak cocok. Perubahan dependensi selalu dilakukan melalui add, remove, atau update. Terakhir, proyek yang dipindahkan tanpa Manifest.toml kehilangan determinisme versinya, karena add ulang akan menjalankan resolusi baru terhadap registry terkini. Pada proyek aplikasi, bagikan kedua berkas tersebut bersama kode sumber.

Ringkasan#

  • Proyek Julia terdiri atas Project.toml yang menyatakan kebutuhan dan Manifest.toml yang mencatat seluruh graf dependensi dengan versi persis.
  • Mode package REPL (]) dan modul Pkg menawarkan perintah yang sama, dengan activate, add, remove, update, instantiate, dan status sebagai perintah inti.
  • Resolusi dependensi memilih versi yang memenuhi [compat] dan persyaratan registry, lalu hasilnya ditulis ke Manifest sehingga proyek dapat diinstal ulang secara identik.

Referensi#