[PATCH 0/2] semver aware cargo refresh

  • Done
  • quality assurance status badge
Details
2 participants
  • David Elsing
  • Efraim Flashner
Owner
unassigned
Submitted by
Efraim Flashner
Severity
normal
E
E
Efraim Flashner wrote on 9 Jan 2024 14:05
(address . guix-patches@gnu.org)
cover.1704805408.git.efraim@flashner.co.il
These patches make 'guix refresh' take into account the semver of the
crate and only suggest upgrading to one which still matches the semver
constraints and isn't yanked. Then I went and used the functions to
factor out some of the other code.

Efraim Flashner (2):
import: crate: Update to latest semver version.
import: crate: Simplify find-crate-version.

guix/import/crate.scm | 59 +++++++++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 22 deletions(-)


base-commit: b26926189e5bf253093050f9a73f2d9d7555cc3e
--
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
E
E
Efraim Flashner wrote on 9 Jan 2024 14:07
[PATCH 1/2] import: crate: Update to latest semver version.
(address . 68346@debbugs.gnu.org)
95ec7b98522617a6e033bfba98384b88c5535264.1704805408.git.efraim@flashner.co.il
* guix/import/crate.scm (max-crate-version-of-semver,
nonyanked-crate-versions): New procedures.
(import-release)[version]: Update to the requested version or the newest
semver-compatible version.

Change-Id: I72b081147c4eb9faf482f159b7145aaaf9f91f29
---
guix/import/crate.scm | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)

Toggle diff (67 lines)
diff --git a/guix/import/crate.scm b/guix/import/crate.scm
index c57bd0bc6a..43f80f3fb7 100644
--- a/guix/import/crate.scm
+++ b/guix/import/crate.scm
@@ -5,7 +5,7 @@
;;; Copyright © 2021 Nicolas Goaziou <mail@nicolasgoaziou.fr>
;;; Copyright © 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2023 Simon Tournier <zimon.toutoune@gmail.com>
-;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2023, 2024 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2023 David Elsing <david.elsing@posteo.net>
;;;
;;; This file is part of GNU Guix.
@@ -233,6 +233,27 @@ (define (string->license string)
'unknown-license!)))
(string-split string (string->char-set " /"))))
+(define (max-crate-version-of-semver semver-range range)
+ "Returns a <crate-version> of the highest version within the semver range."
+ (let ((matching-crates
+ (sort
+ (filter (lambda (entry)
+ (semver-range-contains?
+ semver-range
+ (string->semver (crate-version-number entry))))
+ range)
+ (lambda (entry1 entry2)
+ (version>? (crate-version-number entry1)
+ (crate-version-number entry2))))))
+ (and (not (null-list? matching-crates))
+ (first matching-crates))))
+
+(define (nonyanked-crate-versions crate)
+ "Returns a list of <crate-version>s which are not yanked by upstream."
+ (filter (lambda (entry)
+ (not (crate-version-yanked? entry)))
+ (crate-versions crate)))
+
(define* (crate->guix-package
crate-name
#:key version include-dev-deps? allow-yanked? #:allow-other-keys)
@@ -427,6 +448,7 @@ (define (guix-package->crate-name package)
(define (crate-name->package-name name)
(guix-name "rust-" name))
+
;;;
;;; Updater
@@ -440,7 +462,12 @@ (define* (import-release package #:key (version #f))
include a VERSION string to fetch a specific version."
(let* ((crate-name (guix-package->crate-name package))
(crate (lookup-crate crate-name))
- (version (or version (crate-latest-version crate)))
+ (version (or version
+ (crate-version-number
+ (max-crate-version-of-semver
+ (string->semver-range
+ (string-append "^" (package-version package)))
+ (nonyanked-crate-versions crate)))))
(url (crate-uri crate-name version)))
(upstream-source
(package (package-name package))
--
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
E
E
Efraim Flashner wrote on 9 Jan 2024 14:07
[PATCH 2/2] import: crate: Simplify find-crate-version.
(address . 68346@debbugs.gnu.org)
3caa53187f36dbc95f7b9ef982632cc284981e28.1704805408.git.efraim@flashner.co.il
* guix/import/crate.scm (find-crate-version): Reuse
nonyanked-crate-versions, max-crate-version-of-semver.

Change-Id: I976a3b5a397f0d6a7d723804a98356544bfc7da3
---
guix/import/crate.scm | 28 ++++++++--------------------
1 file changed, 8 insertions(+), 20 deletions(-)

Toggle diff (43 lines)
diff --git a/guix/import/crate.scm b/guix/import/crate.scm
index 43f80f3fb7..ba2bc1573e 100644
--- a/guix/import/crate.scm
+++ b/guix/import/crate.scm
@@ -310,26 +310,14 @@ (define* (crate->guix-package
;; If no matching non-yanked version has been found and allow-yanked? is #t,
;; also consider yanked packages.
(define (find-crate-version crate range)
- (let* ((semver-range (string->semver-range range))
- (versions
- (sort
- (filter (lambda (entry)
- (and
- (or allow-yanked?
- (not (crate-version-yanked? (second entry))))
- (semver-range-contains? semver-range (first entry))))
- (map (lambda (ver)
- (list (string->semver (crate-version-number ver))
- ver))
- (crate-versions crate)))
- (match-lambda* (((semver ver) ...)
- (match-let (((yanked1 yanked2)
- (map crate-version-yanked? ver)))
- (or (and yanked1 (not yanked2))
- (and (eq? yanked1 yanked2)
- (apply semver<? semver)))))))))
- (and (not (null-list? versions))
- (second (last versions)))))
+ (let ((semver-range (string->semver-range range))
+ (versions (nonyanked-crate-versions crate)))
+ (or (and (not (null-list? versions))
+ (max-crate-version-of-semver semver-range versions))
+ (and allow-yanked?
+ (not (null-list? (crate-versions crate)))
+ (max-crate-version-of-semver semver-range
+ (crate-versions crate))))))
;; If no non-yanked existing package version was found, check the upstream
;; versions. If a non-yanked upsteam version exists, use it instead,
--
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
D
D
David Elsing wrote on 14 Jan 2024 13:54
Re: [PATCH 0/2] semver aware cargo refresh
86mst8vzwc.fsf@posteo.net
Hello,

Efraim Flashner <efraim@flashner.co.il> writes:
Toggle quote (5 lines)
> These patches make 'guix refresh' take into account the semver of the
> crate and only suggest upgrading to one which still matches the semver
> constraints and isn't yanked. Then I went and used the functions to
> factor out some of the other code.

thanks for cleaning this up a bit! I tested your patches and only found
the (minor) issue that an exception is thrown instead of returning #f if
there is no non-yanked package available. The minimum element can also
be found without sorting, so I would suggest something like the
following changes:


Toggle diff (134 lines)
diff --git a/guix/import/crate.scm b/guix/import/crate.scm
index ba2bc1573e..76b7c05072 100644
--- a/guix/import/crate.scm
+++ b/guix/import/crate.scm
@@ -104,7 +104,7 @@ (define-json-mapping <crate-dependency> make-crate-dependency
;; Autoload Guile-Semver so we only have a soft dependency.
(module-autoload! (current-module)
- '(semver) '(string->semver semver->string semver<? semver=?))
+ '(semver) '(string->semver semver->string semver<? semver=? semver>?))
(module-autoload! (current-module)
'(semver ranges) '(string->semver-range semver-range-contains?))
@@ -233,20 +233,32 @@ (define (string->license string)
'unknown-license!)))
(string-split string (string->char-set " /"))))
+(define (min-element l less)
+ "Returns the smallest element of l according to less or #f if l is empty."
+
+ (let loop ((curr #f)
+ (remaining l))
+ (if (null-list? remaining)
+ curr
+ (let ((next (car remaining))
+ (remaining (cdr remaining)))
+ (if (and curr
+ (not (less next curr)))
+ (loop curr remaining)
+ (loop next remaining))))))
+
(define (max-crate-version-of-semver semver-range range)
"Returns a <crate-version> of the highest version within the semver range."
- (let ((matching-crates
- (sort
- (filter (lambda (entry)
- (semver-range-contains?
- semver-range
- (string->semver (crate-version-number entry))))
- range)
- (lambda (entry1 entry2)
- (version>? (crate-version-number entry1)
- (crate-version-number entry2))))))
- (and (not (null-list? matching-crates))
- (first matching-crates))))
+
+ (define (crate->semver crate)
+ (string->semver (crate-version-number crate)))
+
+ (min-element
+ (filter (lambda (crate)
+ (semver-range-contains? semver-range (crate->semver crate)))
+ range)
+ (lambda args
+ (apply semver>? (map crate->semver args)))))
(define (nonyanked-crate-versions crate)
"Returns a list of <crate-version>s which are not yanked by upstream."
@@ -284,8 +296,8 @@ (define version-number
;; Packages previously marked as yanked take lower priority.
(define (find-package-version name range)
(let* ((semver-range (string->semver-range range))
- (package-versions
- (sort
+ (version
+ (min-element
(filter (match-lambda ((semver yanked)
(and
(or allow-yanked? (not yanked))
@@ -293,17 +305,17 @@ (define (find-package-version name range)
(map (lambda (pkg)
(let ((version (package-version pkg)))
(list
- (string->semver version)
- (assoc-ref (package-properties pkg)
- 'crate-version-yanked?))))
+ (string->semver version)
+ (assoc-ref (package-properties pkg)
+ 'crate-version-yanked?))))
(find-packages-by-name
(crate-name->package-name name))))
(match-lambda* (((semver1 yanked1) (semver2 yanked2))
- (or (and yanked1 (not yanked2))
- (and (eq? yanked1 yanked2)
- (semver<? semver1 semver2))))))))
- (and (not (null-list? package-versions))
- (match-let (((semver yanked) (last package-versions)))
+ (and (or (not yanked1) yanked2)
+ (or (not (eq? yanked1 yanked2))
+ (semver>? semver1 semver2))))))))
+ (and (not (eq? #f version))
+ (match-let (((semver yanked) version))
(list (semver->string semver) yanked)))))
;; Find the highest version of a crate that fulfills the semver <range>.
@@ -449,18 +461,22 @@ (define* (import-release package #:key (version #f))
"Return an <upstream-source> for the latest release of PACKAGE. Optionally
include a VERSION string to fetch a specific version."
(let* ((crate-name (guix-package->crate-name package))
- (crate (lookup-crate crate-name))
- (version (or version
- (crate-version-number
- (max-crate-version-of-semver
- (string->semver-range
- (string-append "^" (package-version package)))
- (nonyanked-crate-versions crate)))))
- (url (crate-uri crate-name version)))
- (upstream-source
- (package (package-name package))
- (version version)
- (urls (list url)))))
+ (crate (lookup-crate crate-name))
+ (version
+ (or version
+ (let ((max-crate-version
+ (max-crate-version-of-semver
+ (string->semver-range
+ (string-append "^" (package-version package)))
+ (nonyanked-crate-versions crate))))
+ (and max-crate-version
+ (crate-version-number max-crate-version))))))
+ (if version
+ (upstream-source
+ (package (package-name package))
+ (version version)
+ (urls (list (crate-uri crate-name version))))
+ #f)))
(define %crate-updater
(upstream-updater


Cheers,
David
E
E
Efraim Flashner wrote on 16 Jan 2024 13:26
(name . David Elsing)(address . david.elsing@posteo.net)
ZaZ17dDKOuBLQJup@3900XT
On Sun, Jan 14, 2024 at 12:54:27PM +0000, David Elsing wrote:
Toggle quote (14 lines)
> Hello,
>
> Efraim Flashner <efraim@flashner.co.il> writes:
> > These patches make 'guix refresh' take into account the semver of the
> > crate and only suggest upgrading to one which still matches the semver
> > constraints and isn't yanked. Then I went and used the functions to
> > factor out some of the other code.
>
> thanks for cleaning this up a bit! I tested your patches and only found
> the (minor) issue that an exception is thrown instead of returning #f if
> there is no non-yanked package available. The minimum element can also
> be found without sorting, so I would suggest something like the
> following changes:

I still think I like sort better, but it definitely doesn't do as good a
job of taking care of the #f case as your code does. I incorporated
your changes and pushed them.

--
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
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEoov0DD5VE3JmLRT3Qarn3Mo9g1EFAmWmde0ACgkQQarn3Mo9
g1Fe2w/9HOngHFw9Kk2pp3OFX3OUYeNyo3GrAG4LmITBZhHUGzAhgcpdpsF+m6D0
S24H9UxQ1jA5hKs7/T92811SqdUUYKkgk6yz/nF+phTNgx00htxS0azEF0R1l/FX
2Iq1llu2XD8vmreBxoPxJolHN3DLFxo328vBei42USNJpU9RM7Ejc0o2j//GCUqU
QiZJVqRa8wIj/N3T5EwBRf+1GzmGRFZOLgw0eXR5nzp/HRJcrFcp6pMNOhedoFXp
mf92okG/0KQ08drG3A3bDnHCJloSthJ0E7+N/RkvSyKWFP+io0Qx6xFUzu/Xfcrm
wiqcDLCGrjw3qoX6pBQt5XFjDQLdB8AZWZXzTdVc6DyuFZdPTwTJerE40WCiWMEG
F1QhATFWmPAlbmwie885I9hmQ59aOpuGzBZWk4krFGuI3KGOJEZDup1xMnDtANhX
2NWcfUbyjtmV7OxOEWRghKGsU+LBADgxrVT2NtpAQnGRUoZJBibuC3QGgFtUg6IX
cxld5XUSHGa/bSFV/zaG7ru7/tPoxtOYcQ1YNv2fKyLDTOp+X2WQAopKgbC6dTrf
KRTpkCnOlOrYHRaNzcQgnnDipauSKTJJn/1ysLGkBGtP/bUKM9fyWuD3I7arxaow
31zlsIf54ihMnhhMrJ8/lGRF0R5SU6Z0fiXN0fO2p2lbgcv1V0c=
=e0EK
-----END PGP SIGNATURE-----


Closed
?
Your comment

This issue is archived.

To comment on this conversation send an email to 68346@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 68346
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch