Package: guix-patches;
Reported by: Attila Lendvai <attila <at> lendvai.name>
Date: Tue, 28 Sep 2021 21:45:02 UTC
Severity: normal
Tags: patch
View this message in rfc822 format
From: Attila Lendvai <attila <at> lendvai.name> To: 50878 <at> debbugs.gnu.org Cc: Attila Lendvai <attila <at> lendvai.name> Subject: [bug#50878] [PATCH 4/4] WIP guix: build: Add resolve-collision/alphanumeric-last for union. Date: Sun, 3 Oct 2021 14:43:04 +0200
It is currently not used anywhere, only exported. The tests are boken, because guile is too old in the test environment, at least on 'x86_64-linux' (guile 2.0.9 doesn't have srfi-43, aka vectors). Probably it's also broken because testing errors with `no code for module (guix build utils)`. * guix/build/union.scm (resolve-collision/alphanumeric-last): New function. * guix/build/utils.scm (compare-strings-ignoring-store-path-prefix): New function. --- I think the previous 3 patches in this patchset are worthy of inclusion, but this one is more of a good idea than a worked out change, to be picked up later, if at all. The primary issue is that the test framework uses a guile that is too old, but it's also not used anywhere. It would be nice if this was used for resolving conflicts for profiles, i.e. for the user's bin/ directory. guix/build/union.scm | 12 ++++++++++++ guix/build/utils.scm | 27 +++++++++++++++++++++++++++ tests/union.scm | 9 +++++++++ 3 files changed, 48 insertions(+) diff --git a/guix/build/union.scm b/guix/build/union.scm index 9e8c2af4f5..339af7576c 100644 --- a/guix/build/union.scm +++ b/guix/build/union.scm @@ -19,15 +19,18 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix build union) + #:use-module (guix build utils) #:use-module (ice-9 match) #:use-module (ice-9 format) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-43) #:use-module (rnrs bytevectors) #:use-module (rnrs io ports) #:export (union-build default-collision-resolver + resolve-collision/alphanumeric-last relative-file-name symlink-relative)) @@ -102,6 +105,15 @@ identical, #f otherwise." ;; applications via 'glib-or-gtk-build-system'. '("icon-theme.cache" "gschemas.compiled")) +(define (resolve-collision/alphanumeric-last files) + ;; Let's do a stable-sort, so that multiple foo-1.2.3/bin/foo variants will + ;; predictably resolve to the highest versioned one. + (let ((files-vector (list->vector files))) + (stable-sort! files-vector + (lambda (a b) + (> 0 (compare-strings-ignoring-store-path-prefix a b)))) + (vector-ref files-vector 0))) + (define (resolve-collision/pick-first files) (first files)) diff --git a/guix/build/utils.scm b/guix/build/utils.scm index 4009c137b8..1ae0244b04 100644 --- a/guix/build/utils.scm +++ b/guix/build/utils.scm @@ -47,6 +47,7 @@ %store-hash-string-length store-file-name? strip-store-file-name + compare-strings-ignoring-store-path-prefix package-name->name+version parallel-job-count @@ -171,6 +172,32 @@ is typically a \"PACKAGE-VERSION\" string." (string-drop file (store-path-prefix-length))) +(define (compare-strings-ignoring-store-path-prefix a b) + (let ((a-length (string-length a)) + (b-length (string-length b))) + (do ((i (store-path-prefix-length) (+ i 1))) + ((not (and (< i a-length) + (< i b-length) + (char=? (string-ref a i) + (string-ref b i)))) + (cond + ((= a-length b-length) + (if (= i a-length) ; we reached the end without any difference + 0 + (- (char->integer (string-ref a i)) + (char->integer (string-ref b i))))) + ((> a-length b-length) + (if (= i b-length) ; we reached the end of B without a difference + 1 + (- (char->integer (string-ref a i)) + (char->integer (string-ref b i))))) + (else ; i.e. (< a-length b-length) + (if (= i a-length) ; we reached the end of A without a difference + -1 + (- (char->integer (string-ref a i)) + (char->integer (string-ref b i))))))) + '()))) + (define (package-name->name+version name) "Given NAME, a package name like \"foo-0.9.1b\", return two values: \"foo\" and \"0.9.1b\". When the version part is unavailable, NAME and diff --git a/tests/union.scm b/tests/union.scm index a8387edf42..cbf8840793 100644 --- a/tests/union.scm +++ b/tests/union.scm @@ -204,4 +204,13 @@ ("/a/b" "/a/b/c/d" => "c/d") ("/a/b/c" "/a/d/e/f" => "../../d/e/f"))) +(test-assert "resolve-collision/alphanumeric-last sorts alphanumerically" + (string= + ((@@ (guix build union) resolve-collision/alphanumeric-last) + (list "/gnu/store/c0000000000000000000000000000000-idris-0.0.0/bin/idris" + "/gnu/store/60000000000000000000000000000000-idris-2.0.0/bin/idris" + "/gnu/store/z0000000000000000000000000000000-idris-1.3.5/bin/idris" + "/gnu/store/00000000000000000000000000000000-idris-1.3.3/bin/idris")) + "/gnu/store/60000000000000000000000000000000-idris-2.0.0/bin/idris")) + (test-end) -- 2.33.0
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.