unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Efraim Flashner <efraim@flashner.co.il>
To: guix-devel@gnu.org
Subject: Re: rust-team branch merged
Date: Thu, 14 Dec 2023 17:10:16 +0200	[thread overview]
Message-ID: <ZXsa2Hls1PVAmFEe@3900XT> (raw)
In-Reply-To: <ZXlsg1E6PvDHga_G@3900XT>


[-- Attachment #1.1: Type: text/plain, Size: 1878 bytes --]

On Wed, Dec 13, 2023 at 10:34:11AM +0200, Efraim Flashner wrote:
> * Compiled rust packages currently have a 'package' phase, which runs
> the command used to crate a 'crate tarball', and is installed in
> %output/share/cargo/registry, with unpacked sources in
> %output/share/cargo/src.  In theory it should be possible to use these
> for local rust development.  The benefits include everything that comes
> with being a guix package, including pre-patched shebangs.  Currently no
> index file is created in $GUIX_ENVIRONMENT/share/cargo/registry/index,
> which is likely necessary to actually make use of this.  Additionally, I
> am unsure how to use '$GUIX_ENVIRONMENT' in ~/.cargo/config so that it
> is expanded and not taken as a literal string.

In the Guix London meetup someone mentioned that they were interested in
playing around with using Guix for rust development.  I've adjusted the
cargo-build-system to produce the registry index files and I added a
profile hook to generate the config.json to locate the packaged crates.

toml files can't process environment variables (which is probably a good
thing ...) but that means its a little harder to test out.

with the two patches applied create an environment with the crates you
want and get the location of GUIX_ENVIRONMENT:
`env | grep GUIX_ENVIRONMENT | cut -f2 -d=`

in ~/.cargo/config:
[source.crates-io]
local-registry = '<location of GUIX_ENVIRONMENT>/share/cargo/registry'

'cargo build' should pull from the local crates in the GUIX_ENVIRONMENT.
I'm not sure what happens if it doesn't have those crates available and
would need to get them from crates.io.


-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #1.2: 0001-build-cargo-build-system-Produce-registry-index-file.patch --]
[-- Type: text/plain, Size: 8648 bytes --]

From 84d2f06e9facec9a1646afd53adcbf2b95da4da0 Mon Sep 17 00:00:00 2001
Message-ID: <84d2f06e9facec9a1646afd53adcbf2b95da4da0.1702565894.git.efraim@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efraim@flashner.co.il>
References: <cover.1702565894.git.efraim@flashner.co.il>
From: Efraim Flashner <efraim@flashner.co.il>
Date: Thu, 14 Dec 2023 16:49:58 +0200
Subject: [PATCH 1/2] build: cargo-build-system: Produce registry index files.

* guix/build/cargo-build-system.scm (rewrite-deps): New procedure.
(package): Obtain output from 'cargo manifest' of the current package
when the package will be installed.
(install): Don't install cargo crates and source.
(install-source): New phase.  Install cargo crates.  Generate cargo
registry index files and install them in a known location.
(%standard-phases): Add 'install-source phase after 'install.

Change-Id: I6ce6c5b33fe3eb7667f86964daef798320724a25
---
 guix/build/cargo-build-system.scm | 102 +++++++++++++++++++++++++-----
 1 file changed, 87 insertions(+), 15 deletions(-)

diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
index ffb2ec898e..f1e35a5c65 100644
--- a/guix/build/cargo-build-system.scm
+++ b/guix/build/cargo-build-system.scm
@@ -73,6 +73,21 @@ (define (crate-src? path)
                                             " | cut -d/ -f2"
                                             " | grep -q '^Cargo.toml$'")))))
 
+(define (rewrite-deps cargo-deps)
+  (map (lambda (dependency)
+         `(@ ("name" . ,(assoc-ref dependency "name"))
+             ("req" . ,(assoc-ref dependency "req"))
+             ("features" . ,(assoc-ref dependency "features"))
+             ("optional" . ,(assoc-ref dependency "optional"))
+             ("default_features" . ,(assoc-ref dependency
+                                               "uses_default_features"))
+             ("target" . ,(assoc-ref dependency "target"))
+             ("kind" . ,(match (assoc-ref dependency "kind")
+                               (null? "normal")
+                               (kind kind)))
+             ("registry" . ,(assoc-ref dependency "registry"))))
+       cargo-deps))
+
 (define* (unpack-rust-crates #:key inputs vendor-dir #:allow-other-keys)
   (define (inputs->rust-inputs inputs)
     "Filter using the label part from INPUTS."
@@ -271,7 +286,8 @@ (define* (package #:key
                   install-source?
                   (cargo-package-flags '("--no-metadata" "--no-verify"))
                   #:allow-other-keys)
-  "Run 'cargo-package' for a given Cargo package."
+  "Run 'cargo-package' for a given Cargo package.  Also generate metadata so we can
+create a package index for the crates."
   (if install-source?
     (if skip-build?
       (begin
@@ -322,19 +338,24 @@ (define* (package #:key
                 (delete-file-recursively dir)))
             (find-files "." "\\.crate$")))))
     (format #t "Not installing cargo sources, skipping `cargo package`.~%"))
-  #t)
+
+  (when install-source?
+    ;; First generate the metadata so we can create the index file.
+    ;; https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#json-format
+    (with-output-to-file "cargo-metadata.json"
+      (lambda _
+        (invoke "cargo" "metadata"
+                "--manifest-path" "Cargo.toml"
+                "--format-version" "1"
+                "--no-deps")))))
 
 (define* (install #:key
-                  inputs
                   outputs
                   skip-build?
-                  install-source?
                   features
                   #:allow-other-keys)
   "Install a given Cargo package."
-  (let* ((out      (assoc-ref outputs "out"))
-         (registry (string-append out "/share/cargo/registry"))
-         (sources  (string-append out "/share/cargo/src")))
+  (let ((out (assoc-ref outputs "out")))
     (mkdir-p out)
 
     ;; Make cargo reuse all the artifacts we just built instead
@@ -346,21 +367,71 @@ (define* (install #:key
     (or skip-build?
         (not (has-executable-target?))
         (invoke "cargo" "install" "--no-track" "--path" "." "--root" out
-                "--features" (string-join features)))
+                "--features" (string-join features)))))
+
+(define* (install-sources #:key
+                          name
+                          outputs
+                          install-source?
+                          #:allow-other-keys)
+  "Install a given Cargo package."
+  (let* ((out      (assoc-ref outputs "out"))
+         (registry (string-append out "/share/cargo/registry/"))
+         (name+ver (if (string-prefix? "rust-" name)
+                       (string-drop name 5)
+                       name))
+         ;; Strip the version if it exists.
+         (pkgname  (if (char-set-every
+                         (lambda (item)
+                           (char-set-contains?
+                             (list->char-set (list #\- #\.) char-set:digit) item))
+                         (string->char-set
+                           (string-drop name+ver (string-index-right name+ver #\-))))
+                     (string-take name+ver (string-index-right name+ver #\-))
+                     name+ver)))
 
     (when install-source?
       ;; Install crate tarballs and unpacked sources for later use.
-      ;; TODO: Is there a better format/directory for these files?
-      (mkdir-p sources)
       (for-each (lambda (crate)
                   (install-file crate registry))
                 (find-files "target/package" "\\.crate$"))
 
-      (for-each (lambda (crate)
-                  (invoke "tar" "xzf" crate "-C" sources))
-                (find-files registry "\\.crate$")))
+      (let ((path (match (string-length pkgname)
+                         (1 "1")
+                         (2 "2")
+                         (3 (string-append "3/" (string-take pkgname 1)))
+                         (else (string-append (substring pkgname 0 2) "/"
+                                              (substring pkgname 2 4)))))
+            (cargo-metadata (match (call-with-input-file
+                                     "cargo-metadata.json" read-json)
+                                   (('@ . alist) alist)))
+            (sha256sum (read-delimited
+                         " "
+                         (open-pipe* OPEN_READ
+                                     "sha256sum" "--"
+                                     (first (find-files registry pkgname))))))
 
-    #t))
+        ;; Now it's time to generate the actual index file:
+        ;; https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema
+        (call-with-output-file pkgname
+          (lambda (out)
+            (write-json
+              `(@ ("name" . ,(assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "name"))
+                  ("vers" . ,(assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "version"))
+                  ("deps" . ,(rewrite-deps (assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "dependencies")))
+                  ("cksum" . ,sha256sum)
+                  ("features" . ,(assoc-ref
+                                   (first (assoc-ref cargo-metadata "packages"))
+                                   "features"))
+                  ("yanked" . #f))
+              out)))
+        (install-file pkgname (string-append registry "/index/" path))))))
 
 (define %standard-phases
   (modify-phases gnu:%standard-phases
@@ -372,7 +443,8 @@ (define %standard-phases
     (add-after 'build 'package package)
     (add-after 'unpack 'check-for-pregenerated-files check-for-pregenerated-files)
     (add-after 'check-for-pregenerated-files 'unpack-rust-crates unpack-rust-crates)
-    (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch-cargo-checksums)))
+    (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch-cargo-checksums)
+    (add-after 'install 'install-sources install-sources)))
 
 (define* (cargo-build #:key inputs (phases %standard-phases)
                       #:allow-other-keys #:rest args)
-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted


[-- Attachment #1.3: 0002-guix-profiles-Add-cargo-registry-profile-hook.patch --]
[-- Type: text/plain, Size: 2913 bytes --]

From 1dca2772f81df7d9a66f7a97668c3f9acca141a8 Mon Sep 17 00:00:00 2001
Message-ID: <1dca2772f81df7d9a66f7a97668c3f9acca141a8.1702565894.git.efraim@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efraim@flashner.co.il>
References: <cover.1702565894.git.efraim@flashner.co.il>
From: Efraim Flashner <efraim@flashner.co.il>
Date: Thu, 14 Dec 2023 16:54:11 +0200
Subject: [PATCH 2/2] guix: profiles: Add cargo-registry profile hook.

* guix/profiles.scm (cargo-registry): New profile-hook.
(%default-profile-hooks): Add cargo-registry.

Change-Id: I8642e116e7ff7df2ae2dde77c98d5cfeed85f99d
---
 guix/profiles.scm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/guix/profiles.scm b/guix/profiles.scm
index ce2f8337bf..129448b2b1 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -13,6 +13,7 @@
 ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
 ;;; Copyright © 2014 David Thompson <davet@gnu.org>
 ;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1193,6 +1194,29 @@ (define* (ca-certificate-bundle manifest #:optional system)
                     `((type . profile-hook)
                       (hook . ca-certificate-bundle))))
 
+(define* (cargo-registry manifest #:optional system)
+  (define build
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils))
+          (let ((registry (string-append #$output "/share/cargo/registry")))
+            (mkdir-p registry)
+            ;; https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration
+            (with-output-to-file (string-append registry "/config.json")
+              (lambda _
+                (format #t "{~@
+                        \"dl\": \"~a/{crate}-{version}.crate\",~@
+                        }~%"
+                        registry)))))))
+
+  (gexp->derivation "cargo-registry" build
+                    #:system system
+                    #:local-build? #t
+                    #:substitutable? #f
+                    #:properties
+                    `((type . profile-hook)
+                      (hook . cargo-registry))))
+
 (define* (emacs-subdirs manifest #:optional system)
   (define build
     (with-imported-modules (source-module-closure
@@ -1932,6 +1956,7 @@ (define %default-profile-hooks
         fonts-dir-file
         ghc-package-cache-file
         ca-certificate-bundle
+        cargo-registry
         emacs-subdirs
         gdk-pixbuf-loaders-cache-file
         glib-schemas
-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2023-12-14 15:11 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-13  8:34 rust-team branch merged Efraim Flashner
2023-12-13 14:02 ` Maxim Cournoyer
2023-12-14 15:10 ` Efraim Flashner [this message]
2024-02-27  2:24   ` Jason Conroy
2024-03-06  9:06     ` Efraim Flashner
2024-03-06 17:53       ` Jason Conroy
2024-03-07  8:08         ` Efraim Flashner
2024-03-07 16:48           ` Jason Conroy
2024-03-12 15:12             ` Efraim Flashner
2024-03-13 15:06               ` Jason Conroy
2024-04-18 16:54       ` Jason Conroy
2024-04-24 15:39         ` Efraim Flashner
2024-04-24 15:58           ` Jason Conroy
2024-04-24 16:23             ` Efraim Flashner
2024-05-06 14:00               ` Jason Conroy
2023-12-14 23:09 ` Csepp
  -- strict thread matches above, loose matches on Subject: below --
2023-05-09  7:32 Efraim Flashner
2023-05-09  8:33 ` Christopher Baines
2023-05-09  8:54   ` Efraim Flashner
2023-05-09  9:27     ` Andreas Enge
2023-05-09  9:28       ` Andreas Enge
2023-05-09 13:22       ` Christopher Baines
2023-05-09 14:04         ` Efraim Flashner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZXsa2Hls1PVAmFEe@3900XT \
    --to=efraim@flashner.co.il \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).