diff --git a/doc/guix-cookbook.texi b/doc/guix-cookbook.texi index eea1f96bf1b..e47e9e4c508 100644 --- a/doc/guix-cookbook.texi +++ b/doc/guix-cookbook.texi @@ -146,6 +146,7 @@ Packaging Rust Crates * Common Workflow for Rust Packaging:: * Cargo Workspaces and Development Snapshots:: * Using Rust Libraries in Other Build Systems:: +* Common Workflow for Updating Existing Rust Packages:: System Configuration @@ -1644,6 +1645,7 @@ $ guix shell rust rust:cargo cargo-audit cargo-license * Common Workflow for Rust Packaging:: * Cargo Workspaces and Development Snapshots:: * Using Rust Libraries in Other Build Systems:: +* Common Workflow for Updating Existing Rust Packages:: @end menu @node Common Workflow for Rust Packaging @@ -1984,6 +1986,157 @@ method, one of the most popular choices for Traditional Chinese users.") (license license:lgpl2.1+))) @end lisp +@node Common Workflow for Updating Existing Rust Packages +@subsubsection Common Workflow for Updating Existing Rust Packages + +For this example, we'll update @code{niri}. The package definition looks like +this initially: + +@lisp +(define-public niri + (package + (name "niri") + (version "25.08") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/YaLTeR/niri") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "09nsxd211mly8r1ys2lq6ia4jxgb980h1axrbgw748r0knfbbj7n")))) + (build-system cargo-build-system) +... +@end lisp + +We start by running the usual @command{guix refresh -u niri}. + +The @command{-u} flag will update in place the version and hash for the +@code{niri} package. + +The package definition will then look like this: + +@lisp +(define-public niri + (package + (name "niri") + (version "25.11") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/YaLTeR/niri") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 + "0752qm245wc2gak0jhp0fnr0rdj3z54m2h97k3cxbjym9pcn658n")))) + (build-system cargo-build-system) +... +@end lisp + +This means the source field was updated successfully, thus we can now proceed to +get the updated source with @command{guix build --source niri} as follows: + +@example shell +$ cp -r $(./pre-inst-env guix build --source niri) /tmp +$ cd 8frb34ffybxshq4146nz68zbv7fljk45-niri-25.11-checkout/ +@end example + +@quotation Note +In this specific example, the source is a git checkout, thus a directory. If the +package source is a compressed archive, you would at this point extract it to a +directory to proceed. +@end quotation + +Now, given that we have access to the @code{Cargo.toml} file, we can now run +the following inside the checkout: + +@example shell +$ guix shell rust rust:cargo -- cargo generate-lockfile +$ guix shell rust rust:cargo -- cargo audit +$ guix shell rust rust:cargo -- cargo license +@end example + +@quotation Note +Sometimes, the package will require a more up-to-date version of rust, that is +not yet the default rust on guix. For these cases you can use: +@example shell +$ guix shell -e "(@ (gnu packages rust) rust-1.90)" \ + -e '`(,(@ (gnu packages rust) rust-1.90) "cargo")' +@end example +@end quotation + +The first command will ensure that all cargo dependencies are up to date +and semver compatible, while also providing some other benefits, as further +explained in @ref{Common Workflow for Rust Packaging}. + +The following command will warn if there are any known vulnerabilities in the +crates being imported, and the latter will output the license information of all +the dependent crates. + +If everything looks good, we can now replace the contents of the +@code{niri} indentifier, inside @code{lookup-cargo-inputs} on +@code{gnu/packages/rust-crates.scm}, with the newer updated crates by running +the importer on the lockfile as follows: + +@example shell +$ guix import -i /path/to/gnu/packages/rust-crates.scm \ + crate -f Cargo.lock niri +@end example + +@quotation Note +For the purpose of contributing a package to Guix (@pxref{Contributing,,, guix, GNU Guix Reference Manual}), +there is no need to cleanup the leftover crates as a result of the +package update. This is tasked to the rust-team (@pxref{Teams,,, guix, GNU Guix Reference Manual}) +to periodically run a convenient script in @code{etc/teams/rust} to cleanup +unused crates from @code{gnu/packages/rust-crates.scm}. +@end quotation + +After that, we look at @code{gnu/packages/rust-crates.scm} and check if there +are any TODO's generated by the importer. In our example, there are a few +occurrences like so: + +@lisp +(define rust-libdisplay-info-sys-0.3.0 + ;; TODO: Check bundled sources. + (crate-source "libdisplay-info-sys" "0.3.0" + "07xmkc2aqcdn6d58321y87rd3gzdr4nx3ncm1mmrr7w1p1ahsn96")) + +(define rust-smithay-0.7.0.d743e1a + ;; TODO: Define standalone package if this is a workspace. + (origin + (method git-fetch) + (uri (git-reference (url "https://github.com/Smithay/smithay.git") + (commit "d743e1a317fa0f01d1c4cadd96d277a1ec7b59d9"))) + (file-name (git-file-name "rust-smithay" "0.7.0.d743e1a")) + (sha256 (base32 "11327mhxxf844bs0v5bw1g9bzjssnzhidsissywy6kwng16x727v")))) +@end lisp + +We then check the first for bundled sources, and since there are none, we remove +the TODO line. Continuing, after verifying that the latter is not a workspace, +we also remove its TODO line. + +If there were any problems, we would patch the crates with snippets, and then +also remove the TODO line after solving the problem. + +We then try to build the package with @command{guix build niri}, and make sure +if it builds successfully, which it does. + +As a good practice, we can further check the output of the +@code{check-for-pregenerated-files} phase to ensure there are no extraneous +pregenerated files inside the crates. If there are any, it is important to +snippet them out like so: + +@lisp +(define rust-winapi-x86-64-pc-windows-gnu-0.4.0 + (crate-source "winapi-x86_64-pc-windows-gnu" "0.4.0" + "0gqq64czqb64kskjryj8isp62m2sgvx25yyj3kpc2myh85w24bki" + ;; This removes a bunch of ".a" pregenerated binaries + ;; that were hinted on the check-for-pregenerated-files + ;; phase. + #:snippet '(delete-file-recursively "lib"))) +@end lisp @c ********************************************************************* @node System Configuration