summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Graves <ngraves@ngraves.fr>2026-03-18 08:17:47 +0100
committerMaxim Cournoyer <maxim@guixotic.coop>2026-08-27 10:59:20 +0900
commite8f00c0baf929185950bc9bbcb5cc7dbe5e3445c (patch)
treea8e785fb79711b740ba0d0180c35e55eaa0b7ec5
parentdf5313ba673f87ceb567c266bc1d175ea822d07a (diff)
guix: json-utils: Rewrite and deprecate modify-json, delete-fields.
This commit is pushing for the drop of the optional file argument in modify-json which is confusing too specific for such a general function. Still support but deprecate the old style. * guix/build-system/node.scm (not-config?): New helper procedure. (%node-build-system-modules): Add modules necessary for deprecation. * guix/build/json-utils.scm (modify-json*, delkw): New procedures. (modify-json): Warn in the case of the former syntax. (delete-fields): Deprecate in favor of... (delete-json-fields): ... deprecated from delete-fields. (replace-fields): Deprecate in favor of... (replace-json-fields): ... deprecated from replace-fields. (add-fields): Deprecate in favor of... (add-json-fields): ... deprecated from replace-fields. Change-Id: Ieb0642cfb8274bd1d044d0539cbfa0fe02793f2d Signed-off-by: Jelle Licht <jlicht@fsfe.org>
-rw-r--r--guix/build-system/node.scm14
-rw-r--r--guix/build/json-utils.scm92
-rw-r--r--guix/build/node-build-system.scm4
3 files changed, 81 insertions, 29 deletions
diff --git a/guix/build-system/node.scm b/guix/build-system/node.scm
index 596e2cb3e47..4fdd03ade16 100644
--- a/guix/build-system/node.scm
+++ b/guix/build-system/node.scm
@@ -22,14 +22,17 @@
22;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. 22;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
23 23
24(define-module (guix build-system node) 24(define-module (guix build-system node)
25 #:use-module ((guix self) #:select (make-config.scm))
25 #:use-module (guix store) 26 #:use-module (guix store)
26 #:use-module (guix utils) 27 #:use-module (guix utils)
27 #:use-module (guix packages) 28 #:use-module (guix packages)
28 #:use-module (guix gexp) 29 #:use-module (guix gexp)
30 #:use-module (guix modules)
29 #:use-module (guix monads) 31 #:use-module (guix monads)
30 #:use-module (guix search-paths) 32 #:use-module (guix search-paths)
31 #:use-module (guix build-system) 33 #:use-module (guix build-system)
32 #:use-module (guix build-system gnu) 34 #:use-module (guix build-system gnu)
35 #:use-module (ice-9 match)
33 #:export (%default-lockfiles 36 #:export (%default-lockfiles
34 %node-build-system-modules 37 %node-build-system-modules
35 node-build 38 node-build
@@ -40,9 +43,20 @@
40 "yarn.lock" 43 "yarn.lock"
41 "npm-shrinkwrap.json")) 44 "npm-shrinkwrap.json"))
42 45
46(define not-config?
47 ;; Select (guix …) and (gnu …) modules, except (guix config).
48 (match-lambda
49 (('guix 'config) #f)
50 (('guix _ ...) #t)
51 (('gnu _ ...) #t)
52 (_ #f)))
53
43(define %node-build-system-modules 54(define %node-build-system-modules
44 ;; Build-side modules imported by default. 55 ;; Build-side modules imported by default.
45 `((guix build node-build-system) 56 `((guix build node-build-system)
57 ((guix config) => ,(make-config.scm))
58 ,@(source-module-closure '((guix deprecation))
59 #:select? not-config?)
46 (guix build json-utils) 60 (guix build json-utils)
47 ,@%default-gnu-imported-modules)) 61 ,@%default-gnu-imported-modules))
48 62
diff --git a/guix/build/json-utils.scm b/guix/build/json-utils.scm
index f80b1176e4d..ad31dcb8dac 100644
--- a/guix/build/json-utils.scm
+++ b/guix/build/json-utils.scm
@@ -32,12 +32,16 @@
32 #:use-module (ice-9 regex) 32 #:use-module (ice-9 regex)
33 #:use-module (json) 33 #:use-module (json)
34 #:use-module (srfi srfi-1) 34 #:use-module (srfi srfi-1)
35 #:use-module (srfi srfi-26)
35 #:export (with-atomic-json-file-replacement 36 #:export (with-atomic-json-file-replacement
36 modify-json 37 modify-json
37 modify-json-fields 38 modify-json-fields
38 delete-fields 39 delete-fields
40 delete-json-fields
39 replace-fields 41 replace-fields
40 add-fields)) 42 replace-json-fields
43 add-fields
44 add-json-fields))
41 45
42;;; 46;;;
43;;; JSON modification procedures 47;;; JSON modification procedures
@@ -52,21 +56,48 @@ a value to be written as JSON to the replacement FILE."
52 (lambda (in out) 56 (lambda (in out)
53 (scm->json (proc (json->scm in #:ordered #t)) out #:pretty #t)))) 57 (scm->json (proc (json->scm in #:ordered #t)) out #:pretty #t))))
54 58
55(define* (modify-json #:key (file "package.json") #:rest all-arguments) 59;; This is the function we eventually want to migrate to.
56 "Provide package.json modifying callbacks such as (delete-dependencies ...)" 60(define* (modify-json* file #:rest modifications)
57 (let ((modifications 61 "Modify JSON FILE with successive callbacks."
58 (let loop ((arguments all-arguments)) 62 (with-atomic-json-file-replacement file
59 (cond 63 (apply compose modifications)))
60 ((null? arguments) '()) 64
61 ((keyword? (car arguments)) (loop (cddr arguments))) 65;; Copied and adapted from (guix utils).
62 (else (cons (car arguments) (loop (cdr arguments)))))))) 66;; To be removed after modify-json deprecation period.
63 (with-atomic-json-file-replacement 67(define (delkw kw lst)
64 (lambda (package) 68 "Remove KW and its associated value from LST, a keyword/value list such
65 (fold (lambda (modification package) 69as '(#:foo 1 #:bar 2)."
66 (modification package)) 70 (let loop ((lst lst)
67 package 71 (result '()))
68 modifications)) 72 (match lst
69 file))) 73 (()
74 (reverse result))
75 (((? (cute eq? <> kw)) value . rest)
76 (append (reverse result) rest))
77 ((head . tail)
78 (loop tail (cons* head result))))))
79
80;; This is a deprecated version of the function that ought to be
81;; removed in favor of modify-json*'s content eventually.
82;; On removal, also remove the (guix deprecation) modules and their closures
83;; from node-build-system imported-modules.
84(define modify-json
85 (lambda* args
86 (cond
87 ;; Syntax from modify-json*
88 ((and (pair? args) (string? (car args)) (file-exists? (car args)))
89 (apply modify-json* args))
90 ;; Former syntax, #:file set.
91 ((memq '#:file args)
92 => (lambda (file-args)
93 (warning (G_ "'modify-json' 'file' keyword argument is deprecated,\
94 pass the file as the first argument instead~%"))
95 (let-keywords (take file-args 2) #f ((file "unreached-default"))
96 (apply modify-json* file (delkw #:file args)))))
97 ;; Former syntax, #:file unset.
98 (else
99 (warning (G_ "'modify-json' requires a file as the first argument~%"))
100 (apply modify-json* "package.json" args)))))
70 101
71(define* (modify-json-fields fields field-modifier 102(define* (modify-json-fields fields field-modifier
72 #:key 103 #:key
@@ -122,13 +153,13 @@ invalid field value provided, expected string or list of strings, got ~s~%"
122 package 153 package
123 fields))) 154 fields)))
124 155
125(define* (delete-fields fields #:key (strict? #t)) 156(define* (delete-json-fields fields #:key (strict? #t))
126 "Provides a lambda to supply to modify-json which deletes the specified 157 "Provides a lambda to supply to modify-json which deletes the specified
127 `fields` which is a list of field-paths as mentioned in `modify-json-fields`. 158 `fields` which is a list of field-paths as mentioned in `modify-json-fields`.
128 Examples: 159 Examples:
129 (delete-fields '( 160 (delete-json-fields
130 (\"path\" \"to\" \"field\") 161 '((\"path\" \"to\" \"field\")
131 \"path.to.other.field\"))" 162 \"path.to.other.field\"))"
132 (modify-json-fields 163 (modify-json-fields
133 fields 164 fields
134 (lambda (_ data key) 165 (lambda (_ data key)
@@ -137,14 +168,16 @@ invalid field value provided, expected string or list of strings, got ~s~%"
137 (assoc-remove! data key)) 168 (assoc-remove! data key))
138 #:strict? strict?)) 169 #:strict? strict?))
139 170
140(define* (replace-fields fields #:key (strict? #t) insert?) 171(define-deprecated/alias delete-fields delete-json-fields)
172
173(define* (replace-json-fields fields #:key (strict? #t) insert?)
141 "Provides a lambda to supply to modify-json which replaces the value of the 174 "Provides a lambda to supply to modify-json which replaces the value of the
142 supplied field. `fields` is a list of pairs, where the first element is the 175 supplied field. `fields` is a list of pairs, where the first element is the
143 field-path and the second element is the value to replace the target with. 176 field-path and the second element is the value to replace the target with.
144 Examples: 177 Examples:
145 (replace-fields '( 178 (replace-json-fields
146 ((\"path\" \"to\" \"field\") \"new field value\") 179 '(((\"path\" \"to\" \"field\") \"new field value\")
147 (\"path.to.other.field\" \"new field value\")))" 180 (\"path.to.other.field\" \"new field value\")))"
148 (modify-json-fields 181 (modify-json-fields
149 fields 182 fields
150 (lambda (field data key) 183 (lambda (field data key)
@@ -155,10 +188,15 @@ invalid field value provided, expected string or list of strings, got ~s~%"
155 #:insert? insert? 188 #:insert? insert?
156 #:strict? strict?)) 189 #:strict? strict?))
157 190
158(define* (add-fields fields) 191(define-deprecated/alias replace-fields replace-json-fields)
159 "Like `replace-fields', but can insert new fields as well." 192
160 (replace-fields fields #:insert? #t)) 193(define* (add-json-fields fields)
194 "Like `replace-json-fields', but can insert new fields as well."
195 (replace-json-fields fields #:insert? #t))
196
197(define-deprecated/alias add-fields add-json-fields)
161 198
162;;; Local Variables: 199;;; Local Variables:
163;;; eval: (put 'with-atomic-json-file-replacement 'scheme-indent-function 1) 200;;; eval: (put 'with-atomic-json-file-replacement 'scheme-indent-function 1)
201;;; eval: (put 'modify-json* 'scheme-indent-function 1)
164;;; End: 202;;; End:
diff --git a/guix/build/node-build-system.scm b/guix/build/node-build-system.scm
index 00384da2d41..42dfa9918d9 100644
--- a/guix/build/node-build-system.scm
+++ b/guix/build/node-build-system.scm
@@ -96,8 +96,8 @@ dependencies."
96 #:dependency-keys %dev-dependency-keys)) 96 #:dependency-keys %dev-dependency-keys))
97 97
98(define (delete-dev-dependencies) 98(define (delete-dev-dependencies)
99 (delete-fields (list "devDependencies" "peerDependencies") 99 (delete-json-fields (list "devDependencies" "peerDependencies")
100 #:strict? #f)) 100 #:strict? #f))
101 101
102;;; 102;;;
103;;; Phases. 103;;; Phases.