build-system: cargo: Add ‘cargo-inputs’.

* gnu/packages/rust-crates.scm: New file.
* gnu/packages/rust-sources.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Regisiter them.
* guix/build-system/cargo.scm (define-cargo-inputs): New macro.
(crate-source, cargo-inputs): New procedures.
* guix/import/crate.scm: Hide ‘crate-source’ from (guix build-system cargo).
* etc/teams/rust/audit-rust-crates: New file.
* etc/teams/rust/cleanup-crates.sh: New file.
* etc/teams/rust/rust-crates.tmpl: New file.
* etc/teams/rust/unpack-new-crates.sh: New file.

Change-Id: I2f2d705a3e376ed3c646f31b824052a2278d4fb3
This commit is contained in:
Hilton Chain 2025-02-26 12:58:20 +08:00
parent a51c34a22a
commit b1440e1f37
No known key found for this signature in database
GPG key ID: ACC66D09CA528292
9 changed files with 319 additions and 2 deletions

View file

@ -0,0 +1,70 @@
#!/usr/bin/env -S gawk -f
# GNU Guix --- Functional package management for GNU
# Copyright © 2025 Efraim Flashner <efraim@flashner.co.il>
#
# This file is part of GNU Guix.
#
# GNU Guix is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GNU Guix is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
# To run:
# ./etc/teams/rust/audit-rust-crates ./path/to/file.scm
# Prints the output of cargo-audit to the shell.
# Make sure we have cargo-audit in our PATH
BEGIN {
if (system("which cargo-audit 1> /dev/null"))
exit 1;
# Parse a record at a time.
RS = "\n\n"
cargoAudit = "cargo-audit audit --file -"
}
# Check the crate-source origin-only inputs
/crate-source/ {
for(i=3; i <= NF-2; i++) {
if($i == "(crate-source") {
cargoLock = cargoLock "[[package]]\nname = " $(i+1) "\nversion = " $(i+2) "\n"
next
}
}
}
# Check the crates packaged from crates.io tarballs
/crate-uri/ {
for(i=3; i <= NF; i++) {
if($i == "(version")
crateVersion = $(i+1)
if($i == "(crate-uri")
crateName = $(i+1)
}
gsub(/)/, "", crateVersion)
cargoLock = cargoLock "[[package]]\nname = " crateName "\nversion = " crateVersion "\n"
}
# The xxxx-cargo-input variables have a set style
# TODO: Replace the last dash between the name and the version with a space!
# This doesn't take into account swapping between "-" and "_" so we skip it.
#( $2 ~ /-cargo-inputs/ ) {
# sub(/-cargo-inputs/, "", $2)
# gsub(/)/, "", $0)
# gsub(/rust-/, "", $0)
# #gensub(/([[:alpha:]])-([[:digit:]]+)/, "\\1 \\2", "g", $i)
# print "[[package]]\nname = \"" $2 "\"\nversion = \"1.0.0\"\ndependencies = ["
# for (i = 4; i <= NF; i++) {
# print "\"" $i "\","
# }
# print "]"
#}
END { print cargoLock | cargoAudit }

View file

@ -0,0 +1,37 @@
#!/bin/sh
# GNU Guix --- Functional package management for GNU
# Copyright © 2025 Hilton Chain <hako@ultrarare.space>
#
# This file is part of GNU Guix.
#
# GNU Guix is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GNU Guix is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
FILE=gnu/packages/rust-crates.scm
PATTERN='^(define rust-'
grep "$PATTERN" $FILE | cut -d' ' -f2 | while IFS= read -r crate
do
if [ "$(grep -wc "$crate" $FILE)" -eq 1 ]; then
echo "\
(begin
(use-modules (guix utils))
(let ((source-properties
(find-definition-location \"$FILE\" '$crate #:define-prefix 'define)))
(and=> source-properties delete-expression)))" |
guix repl -t machine
fi
done
# Delete extra newlines.
sed --in-place ':a;N;$!ba;s/\n\n\+/\n\n/g' $FILE

View file

@ -0,0 +1,46 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2025 Hilton Chain <hako@ultrarare.space>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu packages rust-crates)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix git-download)
#:use-module (guix build-system cargo)
#:use-module (gnu packages rust-sources)
#:export (lookup-cargo-inputs))
;;;
;;; This file is managed by guix import. Do NOT add definitions manually.
;;;
;;;
;;; Rust libraries fetched from crates.io and non-workspace development
;;; snapshots.
;;;
(define qqqq-separator 'begin-of-crates)
(define ssss-separator 'end-of-crates)
;;;
;;; Cargo inputs.
;;;
(define-cargo-inputs lookup-cargo-inputs)

View file

@ -0,0 +1,45 @@
#!/bin/sh
# GNU Guix --- Functional package management for GNU
# Copyright © 2025 Hilton Chain <hako@ultrarare.space>
#
# This file is part of GNU Guix.
#
# GNU Guix is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GNU Guix is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
# Usage: ./etc/teams/rust/unpack-new-crates.sh <DIR>
# Then inspect DIR with your tool of choice.
#
# For example:
# ./etc/teams/rust/unpack-new-crates.sh tmp-rust-crates &&
# emacs --eval '(find-dired "tmp-rust-crates" "")'
#
# Note this uses git diff, only unstaged one are unpacked.
UNPACK_DIR="$1"
CHANGES="$(git diff gnu/packages/rust-crates.scm | grep -E '^\+\(define rust-' | cut -f2 -d' ')"
rm -rf "$UNPACK_DIR"
mkdir -p "$UNPACK_DIR"
for crate in $CHANGES
do
built="$(./pre-inst-env guix build -e "(@@ (gnu packages rust-crates) "$crate")" -v0 2>/dev/null)"
if [[ -n $built ]]; then
if [[ -d $built ]]; then
cp -r "$built" "$UNPACK_DIR"
else
tar xf "$built" -C "$UNPACK_DIR"
fi
fi
done

View file

@ -629,6 +629,8 @@ GNU_SYSTEM_MODULES = \
%D%/packages/rush.scm \ %D%/packages/rush.scm \
%D%/packages/rust.scm \ %D%/packages/rust.scm \
%D%/packages/rust-apps.scm \ %D%/packages/rust-apps.scm \
%D%/packages/rust-crates.scm \
%D%/packages/rust-sources.scm \
%D%/packages/samba.scm \ %D%/packages/samba.scm \
%D%/packages/sagemath.scm \ %D%/packages/sagemath.scm \
%D%/packages/sawfish.scm \ %D%/packages/sawfish.scm \

View file

@ -0,0 +1,44 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2025 Hilton Chain <hako@ultrarare.space>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu packages rust-crates)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix git-download)
#:use-module (guix build-system cargo)
#:use-module (gnu packages rust-sources)
#:export (lookup-cargo-inputs))
;;;
;;; This file is managed by guix import. Do NOT add definitions manually.
;;;
;;;
;;; Rust libraries fetched from crates.io and non-workspace development
;;; snapshots.
;;;
(define qqqq-separator 'begin-of-crates)
(define ssss-separator 'end-of-crates)
;;;
;;; Cargo inputs.
;;;

View file

@ -0,0 +1,29 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2025 Hilton Chain <hako@ultrarare.space>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu packages rust-sources)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix git-download)
#:use-module (guix build-system cargo))
;;;
;;; Cargo workspaces and Rust libraries requiring external inputs to unbundle.
;;; These packages are hidden, as they are not interesting to users.
;;;

View file

@ -25,12 +25,15 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix build-system cargo) (define-module (guix build-system cargo)
#:use-module (guix diagnostics)
#:use-module (guix i18n)
#:use-module (guix search-paths) #:use-module (guix search-paths)
#:use-module (guix store) #:use-module (guix store)
#:use-module (guix utils) #:use-module (guix utils)
#:use-module (guix gexp) #:use-module (guix gexp)
#:use-module (guix monads) #:use-module (guix monads)
#:use-module (guix packages) #:use-module (guix packages)
#:use-module (guix download)
#:use-module (guix platform) #:use-module (guix platform)
#:use-module (guix build-system) #:use-module (guix build-system)
#:use-module (guix build-system gnu) #:use-module (guix build-system gnu)
@ -45,7 +48,10 @@
crate-url crate-url
crate-url? crate-url?
crate-uri crate-uri
crate-name->package-name)) crate-name->package-name
crate-source
define-cargo-inputs
cargo-inputs))
(define %crate-base-url (define %crate-base-url
(make-parameter "https://crates.io")) (make-parameter "https://crates.io"))
@ -62,6 +68,44 @@ to NAME and VERSION."
(define (crate-name->package-name name) (define (crate-name->package-name name)
(downstream-package-name "rust-" name)) (downstream-package-name "rust-" name))
;; NOTE: Only use this procedure in (gnu packages rust-crates).
(define* (crate-source name version hash #:key (patches '()) (snippet #f))
(origin
(method url-fetch)
(uri (crate-uri name version))
(file-name
(string-append (crate-name->package-name name) "-" version ".tar.gz"))
(sha256 (base32 hash))
(modules '((guix build utils)))
(patches patches)
(snippet snippet)))
(define-syntax define-cargo-inputs
(syntax-rules (=>)
((_ lookup inputs ...)
(define lookup
(let ((table (make-hash-table)))
(letrec-syntax ((record
(syntax-rules (=>)
((_) #t)
((_ (name => lst) rest (... ...))
(begin
(hashq-set! table 'name (filter identity lst))
(record rest (... ...)))))))
(record inputs ...)
(lambda (name)
"Return the inputs for NAME."
(hashq-ref table name))))))))
(define* (cargo-inputs name #:key (module '(gnu packages rust-crates)))
"Lookup Cargo inputs for NAME defined in MODULE, return an empty list if
unavailable."
(let ((lookup (module-ref (resolve-interface module) 'lookup-cargo-inputs)))
(or (lookup name)
(begin
(warning (G_ "no Cargo inputs available for '~a'~%") name)
'()))))
(define (default-rust target) (define (default-rust target)
"Return the default Rust package." "Return the default Rust package."
;; Lazily resolve the binding to avoid a circular dependency. ;; Lazily resolve the binding to avoid a circular dependency.

View file

@ -27,7 +27,7 @@
(define-module (guix import crate) (define-module (guix import crate)
#:use-module (guix base32) #:use-module (guix base32)
#:use-module (guix build-system cargo) #:use-module ((guix build-system cargo) #:hide (crate-source))
#:use-module (guix diagnostics) #:use-module (guix diagnostics)
#:use-module (gcrypt hash) #:use-module (gcrypt hash)
#:use-module (guix http-client) #:use-module (guix http-client)