From: Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
To: 74900@debbugs.gnu.org
Subject: [bug#74900] [PATCH 2/2] Introduce (modify-json), (delete-fields), and (replace-fields) to node-build-system
Date: Sun, 29 Dec 2024 21:58:35 +0000 [thread overview]
Message-ID: <CAADuFnLa3g3NFk4+uRvs2P1nz+PFp_qFscGFQpAGv79-WL_9+w@mail.gmail.com> (raw)
In-Reply-To: <CAADuFnKAGHb2=rTFiwD9yXN3=OKbZdragGaCJJ0BkOhofDb2KQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 43431 bytes --]
This change introduces helper procedures (modify-json) which takes in lambdas
which modify the target json #:file which defaults to package.json
This change also includes (delete-fields) and (replace-fields) to help deleting
and replacing the value of fields in a package.json file.
Signed-off-by: Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
Change-Id: I957f7ca814078d2136d5261985174820235f1369
---
gnu/packages/node-xyz.scm | 324 ++++++++++++++-----------------
gnu/packages/node.scm | 86 ++++----
guix/build/node-build-system.scm | 198 +++++++++++++++----
3 files changed, 355 insertions(+), 253 deletions(-)
diff --git a/gnu/packages/node-xyz.scm b/gnu/packages/node-xyz.scm
index ec3f9fbfb1..cdc69de0c1 100644
--- a/gnu/packages/node-xyz.scm
+++ b/gnu/packages/node-xyz.scm
@@ -69,18 +69,7 @@ (define-public node-acorn
;; We need to remove the prepare script from "package.json", as
;; it would try to use the build environment and would block the
;; automatic building by other packages making use of node-acorn.
- ;; TODO: Add utility function
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("prepare" . _) #f)
- (_ #t))
- scripts-alist)))
- (other other))
- pkg-meta-alist)))))
+ (modify-json (delete-fields '(("scripts" "prepare"))))))
(replace 'build
(lambda* (#:key inputs native-inputs #:allow-other-keys)
(let ((esbuild (search-input-file (or native-inputs inputs)
@@ -136,38 +125,26 @@ (define-public node-addon-api
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- `("benchmark"
- "bindings"
- "clang-format"
- "eslint"
- "eslint-config-semistandard"
- "eslint-config-standard"
- "eslint-plugin-import"
- "eslint-plugin-node"
- "eslint-plugin-promise"
- "fs-extra"
- "neostandard"
- "path"
- "pre-commit"
- "semver"))))
- (add-after 'unpack 'skip-js-tests
- ;; We can't run the js-based tests,
- ;; but we can still do the C++ parts
- (lambda args
- (define new-test-script
- "echo stopping after pretest on Guix")
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (map
- (match-lambda
- (("test" . _) (cons "test" new-test-script))
- (other other))
- scripts-alist)))
- (other other))
- pkg-meta-alist))))))))
+ (modify-json
+ (delete-dependencies `(
+ "benchmark"
+ "bindings"
+ "clang-format"
+ "eslint"
+ "eslint-config-semistandard"
+ "eslint-config-standard"
+ "eslint-plugin-import"
+ "eslint-plugin-node"
+ "eslint-plugin-promise"
+ "fs-extra"
+ "neostandard"
+ "path"
+ "pre-commit"
+ "semver"))
+ ;; We can't run the js-based tests,
+ ;; but we can still do the C++ parts
+ (replace-fields (list (cons
+ "scripts.test" "echo stopping after pretest on Guix")))))))))
(home-page "https://github.com/nodejs/node-addon-api")
(synopsis "Node.js API (Node-API) header-only C++ wrappers")
(description "This module contains header-only C++ wrapper classes which
@@ -232,7 +209,7 @@ (define-public node-buffer-crc32
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/brianloveswords/buffer-crc32")
(synopsis "CRC32 implementation in Javascript")
(description
@@ -288,14 +265,15 @@ (define-public node-crx3
"minimist"))))
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("c8"
- "docdash"
- "eslint"
- "eslint-plugin-jsdoc"
- "jsdoc"
- "tap-diff"
- "tape"
- "tape-catch")))))))
+ (modify-json (delete-dependencies
+ '("c8"
+ "docdash"
+ "eslint"
+ "eslint-plugin-jsdoc"
+ "jsdoc"
+ "tap-diff"
+ "tape"
+ "tape-catch"))))))))
(inputs (list node-minimist node-pbf node-yazl))
(home-page "https://github.com/ahwayakchih/crx3")
(synopsis "Create CRXv3 browser extensions with Javascript")
@@ -325,18 +303,19 @@ (define-public node-debug
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("brfs"
- "browserify"
- "coveralls"
- "istanbul"
- "karma"
- "karma-browserify"
- "karma-chrome-launcher"
- "karma-mocha"
- "mocha"
- "mocha-lcov-reporter"
- "xo"
- "supports-color")))))
+ (modify-json (delete-dependencies
+ `("brfs"
+ "browserify"
+ "coveralls"
+ "istanbul"
+ "karma"
+ "karma-browserify"
+ "karma-chrome-launcher"
+ "karma-mocha"
+ "mocha"
+ "mocha-lcov-reporter"
+ "xo"
+ "supports-color"))))))
#:tests? #f))
(home-page "https://github.com/debug-js/debug")
(synopsis "Debugging utility for Node.js")
@@ -421,21 +400,22 @@ (define-public node-file-uri-to-path
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/mocha"
- "@types/node"
- "@typescript-eslint/eslint-plugin"
- "@typescript-eslint/parser"
- "cpy-cli"
- "eslint"
- "eslint-config-airbnb"
- "eslint-config-prettier"
- "eslint-import-resolver-typescript"
- "eslint-plugin-import"
- "eslint-plugin-jsx-a11y"
- "eslint-plugin-react"
- "mocha"
- "rimraf"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/mocha"
+ "@types/node"
+ "@typescript-eslint/eslint-plugin"
+ "@typescript-eslint/parser"
+ "cpy-cli"
+ "eslint"
+ "eslint-config-airbnb"
+ "eslint-config-prettier"
+ "eslint-import-resolver-typescript"
+ "eslint-plugin-import"
+ "eslint-plugin-jsx-a11y"
+ "eslint-plugin-react"
+ "mocha"
+ "rimraf"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs native-inputs #:allow-other-keys)
(copy-recursively "src" "dist")
@@ -497,7 +477,8 @@ (define-public node-ieee754
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("airtap" "standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("airtap" "standard" "tape"))))))))
(home-page "https://github.com/feross/ieee754")
(synopsis "Read/write IEEE754 floating point numbers in Javascript")
(description "This package can read and write IEEE754 floating point
@@ -524,7 +505,7 @@ (define-public node-inherits
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(home-page "https://github.com/isaacs/inherits")
@@ -553,8 +534,8 @@ (define-public node-irc
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- `("ansi-color" "faucet" "jscs" "tape")))))
+ (modify-json (delete-dependencies
+ `("ansi-color" "faucet" "jscs" "tape"))))))
#:tests? #f))
(inputs
(list node-irc-colors))
@@ -583,7 +564,7 @@ (define-public node-irc-colors
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("istanbul" "vows")))))
+ (modify-json (delete-dependencies `("istanbul" "vows"))))))
#:tests? #f))
(home-page "https://github.com/fent/irc-colors.js")
(synopsis "Node.js module providing color and formatting for IRC")
@@ -657,7 +638,8 @@ (define-public node-minimist
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("covert" "tap" "tape")))))))
+ (modify-json (delete-dependencies
+ '("covert" "tap" "tape"))))))))
(home-page "https://github.com/substack/minimist")
(synopsis "Parse CLI arguments in Javascript")
(description "This package can scan for CLI flags and arguments in
@@ -683,12 +665,13 @@ (define-public node-ms
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("eslint"
- "expect.js"
- "husky"
- "lint-staged"
- "mocha"
- "prettier")))))
+ (modify-json (delete-dependencies
+ `("eslint"
+ "expect.js"
+ "husky"
+ "lint-staged"
+ "mocha"
+ "prettier"))))))
#:tests? #f))
(home-page "https://github.com/vercel/ms")
(synopsis "Convert time to milliseconds")
@@ -716,14 +699,14 @@ (define-public node-nan
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
+ (modify-json (delete-dependencies
'("bindings"
"commander"
"glob"
"request"
"node-gyp" ;; would be needed for tests
"tap"
- "xtend")))))
+ "xtend"))))))
;; tests need tap and other dependencies
#:tests? #f))
(inputs
@@ -755,7 +738,8 @@ (define-public node-normalize-path
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("gulp-format-md" "mocha")))))))
+ (modify-json (delete-dependencies
+ '("gulp-format-md" "mocha"))))))))
(native-inputs (list node-minimist))
(home-page "https://github.com/jonschlinkert/normalize-path")
(synopsis "Normalize slashes in a file path")
@@ -784,7 +768,7 @@ (define-public node-once
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(inputs
@@ -841,7 +825,8 @@ (define-public node-path-key
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("@types/node" "ava"
"tsd" "xo")))))))
+ (modify-json (delete-dependencies
+ '("@types/node" "ava" "tsd" "xo"))))))))
(home-page "https://github.com/sindresorhus/path-key")
(synopsis "Cross-platform utility to compute the PATH environment
variable key")
(description "@code{path-key} provides an implementation to compute the
@@ -867,7 +852,7 @@ (define-public node-pbf
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies
+ (modify-json (delete-dependencies
'("benchmark"
"browserify"
"eslint"
@@ -877,7 +862,7 @@ (define-public node-pbf
"protocol-buffers"
"tap"
"tile-stats-runner"
- "uglify-js")))))))
+ "uglify-js"))))))))
(inputs (list node-ieee754 node-resolve-protobuf-schema))
(home-page "https://github.com/mapbox/pbf")
(synopsis "Decode and encode protocol buffers in Javascript")
@@ -908,7 +893,8 @@ (define-public node-protocol-buffers-schema
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("standard" "tape"))))))))
(home-page "https://github.com/mafintosh/protocol-buffers-schema")
(synopsis "Protocol buffers schema parser written in Javascript")
(description "This package provides a protocol buffers schema parser
@@ -935,26 +921,27 @@ (define-public node-readable-stream
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@babel/cli"
- "@babel/core"
- "@babel/polyfill"
- "@babel/preset-env"
- "airtap"
- "assert"
- "bl"
- "deep-strict-equal"
- "events.once"
- "glob"
- "gunzip-maybe"
- "hyperquest"
- "lolex"
- "nyc"
- "pump"
- "rimraf"
- "tap"
- "tape"
- "tar-fs"
- "util-promisify")))))
+ (modify-json (delete-dependencies
+ `("@babel/cli"
+ "@babel/core"
+ "@babel/polyfill"
+ "@babel/preset-env"
+ "airtap"
+ "assert"
+ "bl"
+ "deep-strict-equal"
+ "events.once"
+ "glob"
+ "gunzip-maybe"
+ "hyperquest"
+ "lolex"
+ "nyc"
+ "pump"
+ "rimraf"
+ "tap"
+ "tape"
+ "tar-fs"
+ "util-promisify"))))))
#:tests? #f))
(inputs (list node-util-deprecate node-string-decoder node-inherits))
(home-page "https://github.com/nodejs/readable-stream")
@@ -983,7 +970,8 @@ (define-public node-resolve-protobuf-schema
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("standard" "tape"))))))))
(inputs (list node-protocol-buffers-schema))
(home-page "https://github.com/mafintosh/resolve-protobuf-schema")
(synopsis "Resolve protobuf imports")
@@ -1012,7 +1000,7 @@ (define-public node-safe-buffer
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tape" "standard")))))
+ (modify-json (delete-dependencies '("tape" "standard"))))))
#:tests? #f))
(home-page "https://github.com/feross/safe-buffer")
(synopsis "Buffer creation with explicit semantics")
@@ -1040,20 +1028,21 @@ (define-public node-safe-stable-stringify
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("benchmark" "clone"
- "fast-json-stable-stringify"
- "fast-safe-stringify"
- "fast-stable-stringify"
- "faster-stable-stringify"
- "fastest-stable-stringify"
- "json-stable-stringify"
- "json-stringify-deterministic"
- "json-stringify-safe"
- "standard"
- "tap"
- "typescript"
- "@types/node"
-
"@types/json-stable-stringify")))))))
+ (modify-json (delete-dependencies
+ '("benchmark" "clone"
+ "fast-json-stable-stringify"
+ "fast-safe-stringify"
+ "fast-stable-stringify"
+ "faster-stable-stringify"
+ "fastest-stable-stringify"
+ "json-stable-stringify"
+ "json-stringify-deterministic"
+ "json-stringify-safe"
+ "standard"
+ "tap"
+ "typescript"
+ "@types/node"
+ "@types/json-stable-stringify"))))))))
(home-page "https://github.com/BridgeAR/safe-stable-stringify")
(synopsis "Serialization of javascript objects")
(description
@@ -1111,7 +1100,7 @@ (define-public node-semver
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(home-page "https://github.com/npm/node-semver")
@@ -1151,7 +1140,8 @@ (define-public node-serialport
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@serialport/binding-mock"))))
+ (modify-json (delete-dependencies
+ `("@serialport/binding-mock")))))
(add-after 'unpack 'chdir
(lambda args
(chdir "packages/serialport"))))
@@ -1210,25 +1200,10 @@ (define-public node-serialport-bindings
(chdir "packages/bindings")))
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("prebuild-install"
- ;; devDependencies
- "@serialport/binding-mock"
- "node-abi"))))
- (add-after 'chdir 'avoid-prebuild-install
- (lambda args
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("install" . _) #f)
- (_ #t))
- scripts-alist)))
- (("gypfile" . _)
- (cons "gypfile" #f))
- (other other))
- pkg-meta-alist))))))
+ (modify-json
+ (delete-dependencies `(
+ ;; devDependencies
+ "node-abi"))))))
#:tests? #f))
(synopsis "Abstract base class for Node SerialPort bindings")
(description "Node SerialPort is a modular suite of Node.js packages for
@@ -1409,8 +1384,9 @@ (define-public node-serialport-stream
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `(;; devDependencies
- "@serialport/binding-mock"))))
+ (modify-json
+ (delete-dependencies ;; devDependencies
+ `("@serialport/binding-mock")))))
(add-after 'unpack 'chdir
(lambda args
(chdir "packages/stream"))))
@@ -1461,7 +1437,7 @@ (define-public node-sqlite3
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
+ (modify-json (delete-dependencies
`(;; Normally, this is "built" using @mapbox/node-pre-gyp,
;; which publishes or downloads pre-built binaries or
;; falls back to building from source. Here, we patch out
@@ -1480,7 +1456,7 @@ (define-public node-sqlite3
"node-gyp"
;; These we'd like, we just don't have them yet:
"eslint"
- "mocha"))))
+ "mocha")))))
(add-before 'configure 'npm-config-sqlite
;; We need this step even if we do replace @mapbox/node-pre-gyp
;; because the package expects to build its bundled sqlite
@@ -1514,8 +1490,9 @@ (define-public node-sqlite3
(substitute* ".npmignore"
(("lib/binding")
"#lib/binding # <- patched for Guix"))
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (let ((binary-alist (assoc-ref pkg-meta-alist "binary")))
+ (modify-json
+ (lambda (pkg-meta-alist)
+ (let ((binary-alist (assoc-ref pkg-meta-alist "binary")))
;; When it builds from source, node-pre-gyp supplies
;; module_name and module_path based on the entries under
;; "binary" from "package.json", so this package's
@@ -1528,19 +1505,11 @@ (define-public node-sqlite3
(assoc-ref binary-alist "module_name")
" module_path="
(assoc-ref binary-alist "module_path"))))
+ pkg-meta-alist)
;; We need to remove the install script from "package.json",
;; as it would try to use node-pre-gyp and would block the
;; automatic building performed by `npm install`.
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("install" . _) #f)
- (_ #t))
- scripts-alist)))
- (other other))
- pkg-meta-alist))))))))
+ (delete-fields `(("scripts" "install")))))))))
(home-page "https://github.com/mapbox/node-sqlite3")
(synopsis "Node.js bindings for SQLite3")
(description
@@ -1623,8 +1592,8 @@ (define-public node-string-decoder
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- '("tap" "core-util-is" "babel-polyfill")))))
+ (modify-json (delete-dependencies
+ '("tap" "core-util-is" "babel-polyfill"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(inputs (list node-safe-buffer node-inherits))
@@ -1678,7 +1647,7 @@ (define-public node-wrappy
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/npm/wrappy")
(synopsis "Callback wrapping utility")
(description "@code{wrappy} is a utility for Node.js to wrap callbacks.")
@@ -1703,7 +1672,8 @@ (define-public node-yazl
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("airtap" "bl" "istanbul"
"yauzl")))))))
+ (modify-json (delete-dependencies
+ '("airtap" "bl" "istanbul" "yauzl"))))))))
(inputs (list node-buffer-crc32))
(home-page "https://github.com/thejoshwolfe/yazl")
(synopsis "Yet another zip library for node")
diff --git a/gnu/packages/node.scm b/gnu/packages/node.scm
index 20acffb3df..a13ec5d077 100644
--- a/gnu/packages/node.scm
+++ b/gnu/packages/node.scm
@@ -13,6 +13,7 @@
;;; Copyright © 2021, 2022 Philip McGrath <philip@philipmcgrath.com>
;;; Copyright © 2022 Hilton Chain <hako@ultrarare.space>
;;; Copyright © 2024 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2024 Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -366,7 +367,7 @@ (define-public node-semver-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/npm/node-semver")
(properties '((hidden? . #t)))
(synopsis "Parses semantic versions strings")
@@ -397,11 +398,12 @@ (define-public node-ms-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("eslint"
- "expect.js"
- "husky"
- "lint-staged"
- "mocha")))))))
+ (modify-json (delete-dependencies
+ '("eslint"
+ "expect.js"
+ "husky"
+ "lint-staged"
+ "mocha"))))))))
(home-page "https://github.com/zeit/ms#readme")
(properties '((hidden? . #t)))
(synopsis "Tiny millisecond conversion utility")
@@ -431,7 +433,7 @@ (define-public node-binary-search-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("chai" "mocha")))))))
+ (modify-json (delete-dependencies `("chai" "mocha"))))))))
(home-page "https://github.com/darkskyapp/binary-search#readme")
(properties '((hidden? . #t)))
(synopsis "Tiny binary search function with comparators")
@@ -460,17 +462,18 @@ (define-public node-debug-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("brfs"
- "browserify"
- "coveralls"
- "istanbul"
- "karma"
- "karma-browserify"
- "karma-chrome-launcher"
- "karma-mocha"
- "mocha"
- "mocha-lcov-reporter"
- "xo")))))))
+ (modify-json (delete-dependencies
+ `("brfs"
+ "browserify"
+ "coveralls"
+ "istanbul"
+ "karma"
+ "karma-browserify"
+ "karma-chrome-launcher"
+ "karma-mocha"
+ "mocha"
+ "mocha-lcov-reporter"
+ "xo"))))))))
(inputs (list node-ms-bootstrap))
(home-page "https://github.com/visionmedia/debug#readme")
(properties '((hidden? . #t)))
@@ -526,12 +529,13 @@ (define-public node-llparse-builder-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies `("@types/mocha"
- "@types/node"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/mocha"
+ "@types/node"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
@@ -587,13 +591,14 @@ (define-public node-llparse-frontend-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/debug"
- "@types/mocha"
- "@types/node"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/debug"
+ "@types/mocha"
+ "@types/node"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
@@ -648,15 +653,16 @@ (define-public node-llparse-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/debug"
- "@types/mocha"
- "@types/node"
- "esm"
- "llparse-test-fixture"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/debug"
+ "@types/mocha"
+ "@types/node"
+ "esm"
+ "llparse-test-fixture"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
diff --git a/guix/build/node-build-system.scm b/guix/build/node-build-system.scm
index df7ea7774c..ea23d92a05 100644
--- a/guix/build/node-build-system.scm
+++ b/guix/build/node-build-system.scm
@@ -31,18 +31,14 @@ (define-module (guix build node-build-system)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-71)
#:export (%standard-phases
- with-atomic-json-file-replacement
delete-dependencies
- node-build))
-
-(define* (with-atomic-json-file-replacement proc
- #:optional (file "package.json"))
- "Like 'with-atomic-file-replacement', but PROC is called with a single
-argument---the result of parsing FILE's contents as json---and should a value
-to be written as json to the replacement FILE."
- (with-atomic-file-replacement file
- (lambda (in out)
- (scm->json (proc (json->scm in)) out))))
+ delete-dev-dependencies
+ delete-fields
+ modify-json
+ modify-json-fields
+ node-build
+ replace-fields
+ with-atomic-json-file-replacement))
(define* (assoc-ref* alist key #:optional default)
"Like assoc-ref, but return DEFAULT instead of #f if no value exists."
@@ -72,6 +68,161 @@ (define* (alist-update alist key proc #:optional (= equal?))
(acons key (proc (cdr pair)) rest)
alist)))
+;;;
+;;; package.json modification procedures
+;;;
+
+(define* (with-atomic-json-file-replacement proc
+ #:optional (file "package.json"))
+ "Like 'with-atomic-file-replacement', but PROC is called with a single
+argument---the result of parsing FILE's contents as json---and should a value
+to be written as json to the replacement FILE."
+ (with-atomic-file-replacement file
+ (lambda (in out)
+ (scm->json (proc (json->scm in)) out))))
+
+(define* (modify-json #:key (file "package.json") #:rest all-arguments)
+ "Provide package.json modifying callbacks such as (delete-dependencies ...)"
+ (let
+ (
+ (modifications
+ (let loop ((arguments all-arguments))
+ (cond
+ ((null? arguments) '())
+ ((keyword? (car arguments)) (loop (cddr arguments)))
+ (else (cons (car arguments) (loop (cdr arguments))))))))
+ (with-atomic-json-file-replacement
+ (lambda (package)
+ (fold
+ (lambda (modification package)
+ (modification package))
+ package
+ modifications))
+ file)))
+
+(define (delete-dependencies dependencies-to-remove)
+ "Rewrite 'package.json' to allow the build to proceed without packages
+listed in 'dependencies-to-remove', a list of strings naming npm packages.
+
+To prevent the deleted dependencies from being reintroduced, use this function
+only after the 'patch-dependencies' phase."
+ (lambda (pkg-meta)
+ (fold
+ (lambda (dependency-key pkg-meta)
+ (alist-update
+ pkg-meta
+ dependency-key
+ (lambda (dependencies)
+ (remove
+ (lambda (dependency)
+ (member (car dependency) dependencies-to-remove))
+ dependencies))))
+ pkg-meta
+ (list
+ "devDependencies"
+ "dependencies"
+ "peerDependencies"
+ "optionalDependencies"))))
+
+(define* (modify-json-fields
+ fields
+ field-modifier
+ #:key
+ (field-path-mapper (lambda (field) field))
+ (insert? #f)
+ (strict? #t))
+ "Provides a lambda to supply to modify-json which modifies the specified
+ json file.
+- `fields` is a list procedure-specific data structures which should include
+ the definition of a `field-path` in one of two syntaxes: dot-syntax string
+ such as `\"devDependencies.esbuild\"`, or a list of strings such as
+ `(list \"devDependencies\" \"esbuild\")`.
+- `field-modifier` is a lambda which is invoked at the position of the field.
+ It is supplied with the current field definition, the association list (alist)
+ at the field location in the json file, and the field name, also called `key`.
+- `field-path-mapper` is a lambda which instructs where the field-path is
+ located within the field structure.
+- `insert?` allows the creation of the field and any missing intermediate
+ fields.
+- `strict?` causes an error to be thrown if the exact field-path is not found
+ in the data"
+ (lambda (package)
+ (fold
+ (lambda (field package)
+ (let*
+ (
+ (field-path (field-path-mapper field))
+ (
+ field-path
+ (cond
+ ((string? field-path)
+ (string-split field-path #\.))
+ ((and (list? field-path) (every string? field-path))
+ field-path)
+ (else
+ (error
+ (string-append
+ "Invalid field value provided, expecting a string or a "
+ "list of string but instead got: "
+ (with-output-to-string (lambda _ (display
field-path))))))
+ )))
+ (let loop
+ (
+ (data package)
+ (field-path field-path))
+ (let*
+ (
+ (key (car field-path))
+ (data
+ (if (and (not (assoc key data)) insert?)
+ (acons key '() data)
+ data)))
+ (if (not (assoc key data))
+ (if strict?
+ (error (string-append
+ "Key '" key "' was not found in data: "
+ (with-output-to-string (lambda _ (display data)))))
+ data)
+ (if (= (length field-path) 1)
+ (field-modifier field data key)
+ (assoc-set!
+ data
+ key
+ (loop (assoc-ref data key) (cdr field-path)))))))))
+ package
+ fields)))
+
+(define* (delete-fields fields #:key (strict? #t))
+ "Provides a lambda to supply to modify-json which deletes the specified
+ `fields` which is a list of field-paths as mentioned in `modify-json-fields`.
+ Examples:
+ (delete-fields '(
+ (\"path\" \"to\" \"field\")
+ \"path.to.other.field\"))"
+ (modify-json-fields
+ fields
+ (lambda (_ data key)
+ (assoc-remove! data key))
+ #:strict? strict?))
+
+(define* (replace-fields fields #:key (strict? #t))
+ "Provides a lambda to supply to modify-json which replaces the value of the
+ supplied field. `fields` is a list of pairs, where the first element is the
+ field-path and the second element is the value to replace the target with.
+ Examples:
+ (replace-fields '(
+ ((\"path\" \"to\" \"field\") \"new field value\")
+ (\"path.to.other.field\" \"new field value\")))"
+ (modify-json-fields
+ fields
+ (lambda (field data key)
+ (assoc-set! data key (cdr field)))
+ #:field-path-mapper (lambda (field) (car field))
+ #:strict? strict?))
+
+(define (delete-dev-dependencies)
+ (delete-fields (list "devDependencies") #:strict #f))
+
;;;
;;; Phases.
;;;
@@ -144,31 +295,6 @@ (define* (patch-dependencies #:key inputs
#:allow-other-keys)
(assoc-ref* pkg-meta "dependencies" '())))))))))
#t)
-(define (delete-dependencies dependencies-to-remove)
- "Rewrite 'package.json' to allow the build to proceed without packages
-listed in 'dependencies-to-remove', a list of strings naming npm packages.
-
-To prevent the deleted dependencies from being reintroduced, use this function
-only after the 'patch-dependencies' phase."
- (with-atomic-json-file-replacement
- (lambda (pkg-meta)
- (fold
- (lambda (dependency-key pkg-meta)
- (alist-update
- pkg-meta
- dependency-key
- (lambda (dependencies)
- (remove
- (lambda (dependency)
- (member (car dependency) dependencies-to-remove))
- dependencies))))
- pkg-meta
- (list
- "devDependencies"
- "dependencies"
- "peerDependencies"
- "optionalDependencies")))))
-
(define* (delete-lockfiles #:key inputs #:allow-other-keys)
"Delete 'package-lock.json', 'yarn.lock', and 'npm-shrinkwrap.json', if they
exist."
--
2.46.0
[-- Attachment #2: 0002-Introduce-modify-json-delete-fields-and-replace-fields.patch --]
[-- Type: text/x-patch, Size: 43063 bytes --]
From ac54433a8aae4cd6e6c660263503b96660a35fa8 Mon Sep 17 00:00:00 2001
Message-ID: <ac54433a8aae4cd6e6c660263503b96660a35fa8.1735498183.git.d.khodabakhsh@gmail.com>
In-Reply-To: <e4ea7b88ce39b1f5b24818174f2e5c17424f3adc.1735498183.git.d.khodabakhsh@gmail.com>
References: <e4ea7b88ce39b1f5b24818174f2e5c17424f3adc.1735498183.git.d.khodabakhsh@gmail.com>
From: Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
Date: Sun, 29 Dec 2024 10:24:23 -0800
Subject: [PATCH 2/2] Introduce (modify-json), (delete-fields), and
(replace-fields) to node-build-system
This change introduces helper procedures (modify-json) which takes in lambdas
which modify the target json #:file which defaults to package.json
This change also includes (delete-fields) and (replace-fields) to help deleting
and replacing the value of fields in a package.json file.
Signed-off-by: Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
Change-Id: I957f7ca814078d2136d5261985174820235f1369
---
gnu/packages/node-xyz.scm | 324 ++++++++++++++-----------------
gnu/packages/node.scm | 86 ++++----
guix/build/node-build-system.scm | 198 +++++++++++++++----
3 files changed, 355 insertions(+), 253 deletions(-)
diff --git a/gnu/packages/node-xyz.scm b/gnu/packages/node-xyz.scm
index ec3f9fbfb1..cdc69de0c1 100644
--- a/gnu/packages/node-xyz.scm
+++ b/gnu/packages/node-xyz.scm
@@ -69,18 +69,7 @@ (define-public node-acorn
;; We need to remove the prepare script from "package.json", as
;; it would try to use the build environment and would block the
;; automatic building by other packages making use of node-acorn.
- ;; TODO: Add utility function
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("prepare" . _) #f)
- (_ #t))
- scripts-alist)))
- (other other))
- pkg-meta-alist)))))
+ (modify-json (delete-fields '(("scripts" "prepare"))))))
(replace 'build
(lambda* (#:key inputs native-inputs #:allow-other-keys)
(let ((esbuild (search-input-file (or native-inputs inputs)
@@ -136,38 +125,26 @@ (define-public node-addon-api
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- `("benchmark"
- "bindings"
- "clang-format"
- "eslint"
- "eslint-config-semistandard"
- "eslint-config-standard"
- "eslint-plugin-import"
- "eslint-plugin-node"
- "eslint-plugin-promise"
- "fs-extra"
- "neostandard"
- "path"
- "pre-commit"
- "semver"))))
- (add-after 'unpack 'skip-js-tests
- ;; We can't run the js-based tests,
- ;; but we can still do the C++ parts
- (lambda args
- (define new-test-script
- "echo stopping after pretest on Guix")
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (map
- (match-lambda
- (("test" . _) (cons "test" new-test-script))
- (other other))
- scripts-alist)))
- (other other))
- pkg-meta-alist))))))))
+ (modify-json
+ (delete-dependencies `(
+ "benchmark"
+ "bindings"
+ "clang-format"
+ "eslint"
+ "eslint-config-semistandard"
+ "eslint-config-standard"
+ "eslint-plugin-import"
+ "eslint-plugin-node"
+ "eslint-plugin-promise"
+ "fs-extra"
+ "neostandard"
+ "path"
+ "pre-commit"
+ "semver"))
+ ;; We can't run the js-based tests,
+ ;; but we can still do the C++ parts
+ (replace-fields (list (cons
+ "scripts.test" "echo stopping after pretest on Guix")))))))))
(home-page "https://github.com/nodejs/node-addon-api")
(synopsis "Node.js API (Node-API) header-only C++ wrappers")
(description "This module contains header-only C++ wrapper classes which
@@ -232,7 +209,7 @@ (define-public node-buffer-crc32
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/brianloveswords/buffer-crc32")
(synopsis "CRC32 implementation in Javascript")
(description
@@ -288,14 +265,15 @@ (define-public node-crx3
"minimist"))))
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("c8"
- "docdash"
- "eslint"
- "eslint-plugin-jsdoc"
- "jsdoc"
- "tap-diff"
- "tape"
- "tape-catch")))))))
+ (modify-json (delete-dependencies
+ '("c8"
+ "docdash"
+ "eslint"
+ "eslint-plugin-jsdoc"
+ "jsdoc"
+ "tap-diff"
+ "tape"
+ "tape-catch"))))))))
(inputs (list node-minimist node-pbf node-yazl))
(home-page "https://github.com/ahwayakchih/crx3")
(synopsis "Create CRXv3 browser extensions with Javascript")
@@ -325,18 +303,19 @@ (define-public node-debug
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("brfs"
- "browserify"
- "coveralls"
- "istanbul"
- "karma"
- "karma-browserify"
- "karma-chrome-launcher"
- "karma-mocha"
- "mocha"
- "mocha-lcov-reporter"
- "xo"
- "supports-color")))))
+ (modify-json (delete-dependencies
+ `("brfs"
+ "browserify"
+ "coveralls"
+ "istanbul"
+ "karma"
+ "karma-browserify"
+ "karma-chrome-launcher"
+ "karma-mocha"
+ "mocha"
+ "mocha-lcov-reporter"
+ "xo"
+ "supports-color"))))))
#:tests? #f))
(home-page "https://github.com/debug-js/debug")
(synopsis "Debugging utility for Node.js")
@@ -421,21 +400,22 @@ (define-public node-file-uri-to-path
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/mocha"
- "@types/node"
- "@typescript-eslint/eslint-plugin"
- "@typescript-eslint/parser"
- "cpy-cli"
- "eslint"
- "eslint-config-airbnb"
- "eslint-config-prettier"
- "eslint-import-resolver-typescript"
- "eslint-plugin-import"
- "eslint-plugin-jsx-a11y"
- "eslint-plugin-react"
- "mocha"
- "rimraf"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/mocha"
+ "@types/node"
+ "@typescript-eslint/eslint-plugin"
+ "@typescript-eslint/parser"
+ "cpy-cli"
+ "eslint"
+ "eslint-config-airbnb"
+ "eslint-config-prettier"
+ "eslint-import-resolver-typescript"
+ "eslint-plugin-import"
+ "eslint-plugin-jsx-a11y"
+ "eslint-plugin-react"
+ "mocha"
+ "rimraf"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs native-inputs #:allow-other-keys)
(copy-recursively "src" "dist")
@@ -497,7 +477,8 @@ (define-public node-ieee754
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("airtap" "standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("airtap" "standard" "tape"))))))))
(home-page "https://github.com/feross/ieee754")
(synopsis "Read/write IEEE754 floating point numbers in Javascript")
(description "This package can read and write IEEE754 floating point
@@ -524,7 +505,7 @@ (define-public node-inherits
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(home-page "https://github.com/isaacs/inherits")
@@ -553,8 +534,8 @@ (define-public node-irc
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- `("ansi-color" "faucet" "jscs" "tape")))))
+ (modify-json (delete-dependencies
+ `("ansi-color" "faucet" "jscs" "tape"))))))
#:tests? #f))
(inputs
(list node-irc-colors))
@@ -583,7 +564,7 @@ (define-public node-irc-colors
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("istanbul" "vows")))))
+ (modify-json (delete-dependencies `("istanbul" "vows"))))))
#:tests? #f))
(home-page "https://github.com/fent/irc-colors.js")
(synopsis "Node.js module providing color and formatting for IRC")
@@ -657,7 +638,8 @@ (define-public node-minimist
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("covert" "tap" "tape")))))))
+ (modify-json (delete-dependencies
+ '("covert" "tap" "tape"))))))))
(home-page "https://github.com/substack/minimist")
(synopsis "Parse CLI arguments in Javascript")
(description "This package can scan for CLI flags and arguments in
@@ -683,12 +665,13 @@ (define-public node-ms
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("eslint"
- "expect.js"
- "husky"
- "lint-staged"
- "mocha"
- "prettier")))))
+ (modify-json (delete-dependencies
+ `("eslint"
+ "expect.js"
+ "husky"
+ "lint-staged"
+ "mocha"
+ "prettier"))))))
#:tests? #f))
(home-page "https://github.com/vercel/ms")
(synopsis "Convert time to milliseconds")
@@ -716,14 +699,14 @@ (define-public node-nan
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
+ (modify-json (delete-dependencies
'("bindings"
"commander"
"glob"
"request"
"node-gyp" ;; would be needed for tests
"tap"
- "xtend")))))
+ "xtend"))))))
;; tests need tap and other dependencies
#:tests? #f))
(inputs
@@ -755,7 +738,8 @@ (define-public node-normalize-path
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("gulp-format-md" "mocha")))))))
+ (modify-json (delete-dependencies
+ '("gulp-format-md" "mocha"))))))))
(native-inputs (list node-minimist))
(home-page "https://github.com/jonschlinkert/normalize-path")
(synopsis "Normalize slashes in a file path")
@@ -784,7 +768,7 @@ (define-public node-once
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(inputs
@@ -841,7 +825,8 @@ (define-public node-path-key
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("@types/node" "ava" "tsd" "xo")))))))
+ (modify-json (delete-dependencies
+ '("@types/node" "ava" "tsd" "xo"))))))))
(home-page "https://github.com/sindresorhus/path-key")
(synopsis "Cross-platform utility to compute the PATH environment variable key")
(description "@code{path-key} provides an implementation to compute the
@@ -867,7 +852,7 @@ (define-public node-pbf
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies
+ (modify-json (delete-dependencies
'("benchmark"
"browserify"
"eslint"
@@ -877,7 +862,7 @@ (define-public node-pbf
"protocol-buffers"
"tap"
"tile-stats-runner"
- "uglify-js")))))))
+ "uglify-js"))))))))
(inputs (list node-ieee754 node-resolve-protobuf-schema))
(home-page "https://github.com/mapbox/pbf")
(synopsis "Decode and encode protocol buffers in Javascript")
@@ -908,7 +893,8 @@ (define-public node-protocol-buffers-schema
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("standard" "tape"))))))))
(home-page "https://github.com/mafintosh/protocol-buffers-schema")
(synopsis "Protocol buffers schema parser written in Javascript")
(description "This package provides a protocol buffers schema parser
@@ -935,26 +921,27 @@ (define-public node-readable-stream
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@babel/cli"
- "@babel/core"
- "@babel/polyfill"
- "@babel/preset-env"
- "airtap"
- "assert"
- "bl"
- "deep-strict-equal"
- "events.once"
- "glob"
- "gunzip-maybe"
- "hyperquest"
- "lolex"
- "nyc"
- "pump"
- "rimraf"
- "tap"
- "tape"
- "tar-fs"
- "util-promisify")))))
+ (modify-json (delete-dependencies
+ `("@babel/cli"
+ "@babel/core"
+ "@babel/polyfill"
+ "@babel/preset-env"
+ "airtap"
+ "assert"
+ "bl"
+ "deep-strict-equal"
+ "events.once"
+ "glob"
+ "gunzip-maybe"
+ "hyperquest"
+ "lolex"
+ "nyc"
+ "pump"
+ "rimraf"
+ "tap"
+ "tape"
+ "tar-fs"
+ "util-promisify"))))))
#:tests? #f))
(inputs (list node-util-deprecate node-string-decoder node-inherits))
(home-page "https://github.com/nodejs/readable-stream")
@@ -983,7 +970,8 @@ (define-public node-resolve-protobuf-schema
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("standard" "tape")))))))
+ (modify-json (delete-dependencies
+ '("standard" "tape"))))))))
(inputs (list node-protocol-buffers-schema))
(home-page "https://github.com/mafintosh/resolve-protobuf-schema")
(synopsis "Resolve protobuf imports")
@@ -1012,7 +1000,7 @@ (define-public node-safe-buffer
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tape" "standard")))))
+ (modify-json (delete-dependencies '("tape" "standard"))))))
#:tests? #f))
(home-page "https://github.com/feross/safe-buffer")
(synopsis "Buffer creation with explicit semantics")
@@ -1040,20 +1028,21 @@ (define-public node-safe-stable-stringify
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("benchmark" "clone"
- "fast-json-stable-stringify"
- "fast-safe-stringify"
- "fast-stable-stringify"
- "faster-stable-stringify"
- "fastest-stable-stringify"
- "json-stable-stringify"
- "json-stringify-deterministic"
- "json-stringify-safe"
- "standard"
- "tap"
- "typescript"
- "@types/node"
- "@types/json-stable-stringify")))))))
+ (modify-json (delete-dependencies
+ '("benchmark" "clone"
+ "fast-json-stable-stringify"
+ "fast-safe-stringify"
+ "fast-stable-stringify"
+ "faster-stable-stringify"
+ "fastest-stable-stringify"
+ "json-stable-stringify"
+ "json-stringify-deterministic"
+ "json-stringify-safe"
+ "standard"
+ "tap"
+ "typescript"
+ "@types/node"
+ "@types/json-stable-stringify"))))))))
(home-page "https://github.com/BridgeAR/safe-stable-stringify")
(synopsis "Serialization of javascript objects")
(description
@@ -1111,7 +1100,7 @@ (define-public node-semver
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))
+ (modify-json (delete-dependencies '("tap"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(home-page "https://github.com/npm/node-semver")
@@ -1151,7 +1140,8 @@ (define-public node-serialport
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@serialport/binding-mock"))))
+ (modify-json (delete-dependencies
+ `("@serialport/binding-mock")))))
(add-after 'unpack 'chdir
(lambda args
(chdir "packages/serialport"))))
@@ -1210,25 +1200,10 @@ (define-public node-serialport-bindings
(chdir "packages/bindings")))
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("prebuild-install"
- ;; devDependencies
- "@serialport/binding-mock"
- "node-abi"))))
- (add-after 'chdir 'avoid-prebuild-install
- (lambda args
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("install" . _) #f)
- (_ #t))
- scripts-alist)))
- (("gypfile" . _)
- (cons "gypfile" #f))
- (other other))
- pkg-meta-alist))))))
+ (modify-json
+ (delete-dependencies `(
+ ;; devDependencies
+ "node-abi"))))))
#:tests? #f))
(synopsis "Abstract base class for Node SerialPort bindings")
(description "Node SerialPort is a modular suite of Node.js packages for
@@ -1409,8 +1384,9 @@ (define-public node-serialport-stream
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `(;; devDependencies
- "@serialport/binding-mock"))))
+ (modify-json
+ (delete-dependencies ;; devDependencies
+ `("@serialport/binding-mock")))))
(add-after 'unpack 'chdir
(lambda args
(chdir "packages/stream"))))
@@ -1461,7 +1437,7 @@ (define-public node-sqlite3
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
+ (modify-json (delete-dependencies
`(;; Normally, this is "built" using @mapbox/node-pre-gyp,
;; which publishes or downloads pre-built binaries or
;; falls back to building from source. Here, we patch out
@@ -1480,7 +1456,7 @@ (define-public node-sqlite3
"node-gyp"
;; These we'd like, we just don't have them yet:
"eslint"
- "mocha"))))
+ "mocha")))))
(add-before 'configure 'npm-config-sqlite
;; We need this step even if we do replace @mapbox/node-pre-gyp
;; because the package expects to build its bundled sqlite
@@ -1514,8 +1490,9 @@ (define-public node-sqlite3
(substitute* ".npmignore"
(("lib/binding")
"#lib/binding # <- patched for Guix"))
- (with-atomic-json-file-replacement (lambda (pkg-meta-alist)
- (let ((binary-alist (assoc-ref pkg-meta-alist "binary")))
+ (modify-json
+ (lambda (pkg-meta-alist)
+ (let ((binary-alist (assoc-ref pkg-meta-alist "binary")))
;; When it builds from source, node-pre-gyp supplies
;; module_name and module_path based on the entries under
;; "binary" from "package.json", so this package's
@@ -1528,19 +1505,11 @@ (define-public node-sqlite3
(assoc-ref binary-alist "module_name")
" module_path="
(assoc-ref binary-alist "module_path"))))
+ pkg-meta-alist)
;; We need to remove the install script from "package.json",
;; as it would try to use node-pre-gyp and would block the
;; automatic building performed by `npm install`.
- (map
- (match-lambda
- (("scripts" . scripts-alist)
- (cons "scripts" (filter
- (match-lambda
- (("install" . _) #f)
- (_ #t))
- scripts-alist)))
- (other other))
- pkg-meta-alist))))))))
+ (delete-fields `(("scripts" "install")))))))))
(home-page "https://github.com/mapbox/node-sqlite3")
(synopsis "Node.js bindings for SQLite3")
(description
@@ -1623,8 +1592,8 @@ (define-public node-string-decoder
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies
- '("tap" "core-util-is" "babel-polyfill")))))
+ (modify-json (delete-dependencies
+ '("tap" "core-util-is" "babel-polyfill"))))))
;; FIXME: Tests depend on node-tap
#:tests? #f))
(inputs (list node-safe-buffer node-inherits))
@@ -1678,7 +1647,7 @@ (define-public node-wrappy
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/npm/wrappy")
(synopsis "Callback wrapping utility")
(description "@code{wrappy} is a utility for Node.js to wrap callbacks.")
@@ -1703,7 +1672,8 @@ (define-public node-yazl
#:phases (modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies '("airtap" "bl" "istanbul" "yauzl")))))))
+ (modify-json (delete-dependencies
+ '("airtap" "bl" "istanbul" "yauzl"))))))))
(inputs (list node-buffer-crc32))
(home-page "https://github.com/thejoshwolfe/yazl")
(synopsis "Yet another zip library for node")
diff --git a/gnu/packages/node.scm b/gnu/packages/node.scm
index 20acffb3df..a13ec5d077 100644
--- a/gnu/packages/node.scm
+++ b/gnu/packages/node.scm
@@ -13,6 +13,7 @@
;;; Copyright © 2021, 2022 Philip McGrath <philip@philipmcgrath.com>
;;; Copyright © 2022 Hilton Chain <hako@ultrarare.space>
;;; Copyright © 2024 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2024 Daniel Khodabakhsh <d.khodabakhsh@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -366,7 +367,7 @@ (define-public node-semver-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("tap")))))))
+ (modify-json (delete-dependencies '("tap"))))))))
(home-page "https://github.com/npm/node-semver")
(properties '((hidden? . #t)))
(synopsis "Parses semantic versions strings")
@@ -397,11 +398,12 @@ (define-public node-ms-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies '("eslint"
- "expect.js"
- "husky"
- "lint-staged"
- "mocha")))))))
+ (modify-json (delete-dependencies
+ '("eslint"
+ "expect.js"
+ "husky"
+ "lint-staged"
+ "mocha"))))))))
(home-page "https://github.com/zeit/ms#readme")
(properties '((hidden? . #t)))
(synopsis "Tiny millisecond conversion utility")
@@ -431,7 +433,7 @@ (define-public node-binary-search-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("chai" "mocha")))))))
+ (modify-json (delete-dependencies `("chai" "mocha"))))))))
(home-page "https://github.com/darkskyapp/binary-search#readme")
(properties '((hidden? . #t)))
(synopsis "Tiny binary search function with comparators")
@@ -460,17 +462,18 @@ (define-public node-debug-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("brfs"
- "browserify"
- "coveralls"
- "istanbul"
- "karma"
- "karma-browserify"
- "karma-chrome-launcher"
- "karma-mocha"
- "mocha"
- "mocha-lcov-reporter"
- "xo")))))))
+ (modify-json (delete-dependencies
+ `("brfs"
+ "browserify"
+ "coveralls"
+ "istanbul"
+ "karma"
+ "karma-browserify"
+ "karma-chrome-launcher"
+ "karma-mocha"
+ "mocha"
+ "mocha-lcov-reporter"
+ "xo"))))))))
(inputs (list node-ms-bootstrap))
(home-page "https://github.com/visionmedia/debug#readme")
(properties '((hidden? . #t)))
@@ -526,12 +529,13 @@ (define-public node-llparse-builder-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda _
- (delete-dependencies `("@types/mocha"
- "@types/node"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/mocha"
+ "@types/node"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
@@ -587,13 +591,14 @@ (define-public node-llparse-frontend-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/debug"
- "@types/mocha"
- "@types/node"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/debug"
+ "@types/mocha"
+ "@types/node"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
@@ -648,15 +653,16 @@ (define-public node-llparse-bootstrap
(modify-phases %standard-phases
(add-after 'patch-dependencies 'delete-dependencies
(lambda args
- (delete-dependencies `("@types/debug"
- "@types/mocha"
- "@types/node"
- "esm"
- "llparse-test-fixture"
- "mocha"
- "ts-node"
- "tslint"
- "typescript"))))
+ (modify-json (delete-dependencies
+ `("@types/debug"
+ "@types/mocha"
+ "@types/node"
+ "esm"
+ "llparse-test-fixture"
+ "mocha"
+ "ts-node"
+ "tslint"
+ "typescript")))))
(replace 'build
(lambda* (#:key inputs #:allow-other-keys)
(let ((esbuild (search-input-file inputs "/bin/esbuild")))
diff --git a/guix/build/node-build-system.scm b/guix/build/node-build-system.scm
index df7ea7774c..ea23d92a05 100644
--- a/guix/build/node-build-system.scm
+++ b/guix/build/node-build-system.scm
@@ -31,18 +31,14 @@ (define-module (guix build node-build-system)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-71)
#:export (%standard-phases
- with-atomic-json-file-replacement
delete-dependencies
- node-build))
-
-(define* (with-atomic-json-file-replacement proc
- #:optional (file "package.json"))
- "Like 'with-atomic-file-replacement', but PROC is called with a single
-argument---the result of parsing FILE's contents as json---and should a value
-to be written as json to the replacement FILE."
- (with-atomic-file-replacement file
- (lambda (in out)
- (scm->json (proc (json->scm in)) out))))
+ delete-dev-dependencies
+ delete-fields
+ modify-json
+ modify-json-fields
+ node-build
+ replace-fields
+ with-atomic-json-file-replacement))
(define* (assoc-ref* alist key #:optional default)
"Like assoc-ref, but return DEFAULT instead of #f if no value exists."
@@ -72,6 +68,161 @@ (define* (alist-update alist key proc #:optional (= equal?))
(acons key (proc (cdr pair)) rest)
alist)))
+;;;
+;;; package.json modification procedures
+;;;
+
+(define* (with-atomic-json-file-replacement proc
+ #:optional (file "package.json"))
+ "Like 'with-atomic-file-replacement', but PROC is called with a single
+argument---the result of parsing FILE's contents as json---and should a value
+to be written as json to the replacement FILE."
+ (with-atomic-file-replacement file
+ (lambda (in out)
+ (scm->json (proc (json->scm in)) out))))
+
+(define* (modify-json #:key (file "package.json") #:rest all-arguments)
+ "Provide package.json modifying callbacks such as (delete-dependencies ...)"
+ (let
+ (
+ (modifications
+ (let loop ((arguments all-arguments))
+ (cond
+ ((null? arguments) '())
+ ((keyword? (car arguments)) (loop (cddr arguments)))
+ (else (cons (car arguments) (loop (cdr arguments))))))))
+ (with-atomic-json-file-replacement
+ (lambda (package)
+ (fold
+ (lambda (modification package)
+ (modification package))
+ package
+ modifications))
+ file)))
+
+(define (delete-dependencies dependencies-to-remove)
+ "Rewrite 'package.json' to allow the build to proceed without packages
+listed in 'dependencies-to-remove', a list of strings naming npm packages.
+
+To prevent the deleted dependencies from being reintroduced, use this function
+only after the 'patch-dependencies' phase."
+ (lambda (pkg-meta)
+ (fold
+ (lambda (dependency-key pkg-meta)
+ (alist-update
+ pkg-meta
+ dependency-key
+ (lambda (dependencies)
+ (remove
+ (lambda (dependency)
+ (member (car dependency) dependencies-to-remove))
+ dependencies))))
+ pkg-meta
+ (list
+ "devDependencies"
+ "dependencies"
+ "peerDependencies"
+ "optionalDependencies"))))
+
+(define* (modify-json-fields
+ fields
+ field-modifier
+ #:key
+ (field-path-mapper (lambda (field) field))
+ (insert? #f)
+ (strict? #t))
+ "Provides a lambda to supply to modify-json which modifies the specified
+ json file.
+- `fields` is a list procedure-specific data structures which should include
+ the definition of a `field-path` in one of two syntaxes: dot-syntax string
+ such as `\"devDependencies.esbuild\"`, or a list of strings such as
+ `(list \"devDependencies\" \"esbuild\")`.
+- `field-modifier` is a lambda which is invoked at the position of the field.
+ It is supplied with the current field definition, the association list (alist)
+ at the field location in the json file, and the field name, also called `key`.
+- `field-path-mapper` is a lambda which instructs where the field-path is
+ located within the field structure.
+- `insert?` allows the creation of the field and any missing intermediate
+ fields.
+- `strict?` causes an error to be thrown if the exact field-path is not found
+ in the data"
+ (lambda (package)
+ (fold
+ (lambda (field package)
+ (let*
+ (
+ (field-path (field-path-mapper field))
+ (
+ field-path
+ (cond
+ ((string? field-path)
+ (string-split field-path #\.))
+ ((and (list? field-path) (every string? field-path))
+ field-path)
+ (else
+ (error
+ (string-append
+ "Invalid field value provided, expecting a string or a "
+ "list of string but instead got: "
+ (with-output-to-string (lambda _ (display field-path))))))
+ )))
+ (let loop
+ (
+ (data package)
+ (field-path field-path))
+ (let*
+ (
+ (key (car field-path))
+ (data
+ (if (and (not (assoc key data)) insert?)
+ (acons key '() data)
+ data)))
+ (if (not (assoc key data))
+ (if strict?
+ (error (string-append
+ "Key '" key "' was not found in data: "
+ (with-output-to-string (lambda _ (display data)))))
+ data)
+ (if (= (length field-path) 1)
+ (field-modifier field data key)
+ (assoc-set!
+ data
+ key
+ (loop (assoc-ref data key) (cdr field-path)))))))))
+ package
+ fields)))
+
+(define* (delete-fields fields #:key (strict? #t))
+ "Provides a lambda to supply to modify-json which deletes the specified
+ `fields` which is a list of field-paths as mentioned in `modify-json-fields`.
+ Examples:
+ (delete-fields '(
+ (\"path\" \"to\" \"field\")
+ \"path.to.other.field\"))"
+ (modify-json-fields
+ fields
+ (lambda (_ data key)
+ (assoc-remove! data key))
+ #:strict? strict?))
+
+(define* (replace-fields fields #:key (strict? #t))
+ "Provides a lambda to supply to modify-json which replaces the value of the
+ supplied field. `fields` is a list of pairs, where the first element is the
+ field-path and the second element is the value to replace the target with.
+ Examples:
+ (replace-fields '(
+ ((\"path\" \"to\" \"field\") \"new field value\")
+ (\"path.to.other.field\" \"new field value\")))"
+ (modify-json-fields
+ fields
+ (lambda (field data key)
+ (assoc-set! data key (cdr field)))
+ #:field-path-mapper (lambda (field) (car field))
+ #:strict? strict?))
+
+(define (delete-dev-dependencies)
+ (delete-fields (list "devDependencies") #:strict #f))
+
;;;
;;; Phases.
;;;
@@ -144,31 +295,6 @@ (define* (patch-dependencies #:key inputs #:allow-other-keys)
(assoc-ref* pkg-meta "dependencies" '())))))))))
#t)
-(define (delete-dependencies dependencies-to-remove)
- "Rewrite 'package.json' to allow the build to proceed without packages
-listed in 'dependencies-to-remove', a list of strings naming npm packages.
-
-To prevent the deleted dependencies from being reintroduced, use this function
-only after the 'patch-dependencies' phase."
- (with-atomic-json-file-replacement
- (lambda (pkg-meta)
- (fold
- (lambda (dependency-key pkg-meta)
- (alist-update
- pkg-meta
- dependency-key
- (lambda (dependencies)
- (remove
- (lambda (dependency)
- (member (car dependency) dependencies-to-remove))
- dependencies))))
- pkg-meta
- (list
- "devDependencies"
- "dependencies"
- "peerDependencies"
- "optionalDependencies")))))
-
(define* (delete-lockfiles #:key inputs #:allow-other-keys)
"Delete 'package-lock.json', 'yarn.lock', and 'npm-shrinkwrap.json', if they
exist."
--
2.46.0
prev parent reply other threads:[~2024-12-29 22:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-15 20:30 [bug#74900] [PATCH] Replace (guix build json) with (json) in node build system Daniel Khodabakhsh
2024-12-15 21:41 ` [bug#74900] Daniel Khodabakhsh
2024-12-26 13:30 ` [bug#74900] Daniel Khodabakhsh
2024-12-27 23:58 ` [bug#74900] Daniel Khodabakhsh
2024-12-28 19:00 ` [bug#74900] Daniel Khodabakhsh
2024-12-29 21:54 ` [bug#74900] [PATCH 0/2] Improve node-build-system helper procedures Daniel Khodabakhsh
2024-12-29 21:56 ` [bug#74900] [PATCH 1/2] Replace (guix build json) with (json) in node-build-system Daniel Khodabakhsh
2024-12-29 21:58 ` Daniel Khodabakhsh [this message]
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=CAADuFnLa3g3NFk4+uRvs2P1nz+PFp_qFscGFQpAGv79-WL_9+w@mail.gmail.com \
--to=d.khodabakhsh@gmail.com \
--cc=74900@debbugs.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).