guix: node-build-system: Add avoid-node-gyp-rebuild phase.
Packages with native addons currently try to write to store paths when used as dependecies. This patch adds a phase to replace that behaviour with a no-op. * guix/build/node-build-system.scm (avoid-node-gyp-rebuild): New variable. (%standard-phases): Add 'avoid-node-gyp-rebuild' after 'install'. Signed-off-by: Liliana Marie Prikler <liliana.prikler@gmail.com>
This commit is contained in:
		
							parent
							
								
									2ef3fe9f35
								
							
						
					
					
						commit
						df7d787ba4
					
				
					 1 changed files with 53 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -242,6 +242,57 @@ exist."
 | 
			
		|||
            "install" "../package.tgz")
 | 
			
		||||
    #t))
 | 
			
		||||
 | 
			
		||||
(define* (avoid-node-gyp-rebuild #:key outputs #:allow-other-keys)
 | 
			
		||||
  "Adjust the installed 'package.json' to remove an 'install' script that
 | 
			
		||||
would try to run 'node-gyp rebuild'."
 | 
			
		||||
  ;; We want to take advantage of `npm install`'s automatic support for
 | 
			
		||||
  ;; building native addons with node-gyp: in particular, it helps us avoid
 | 
			
		||||
  ;; hard-coding the specifics of how npm's internal copy of node-gyp is
 | 
			
		||||
  ;; currently packaged. However, the mechanism by which the automatic support
 | 
			
		||||
  ;; is implemented causes problems for us.
 | 
			
		||||
  ;;
 | 
			
		||||
  ;; If a package contains a 'binding.gyp' file and does not define an
 | 
			
		||||
  ;; 'install' or 'preinstall' script, 'npm install' runs a default install
 | 
			
		||||
  ;; script consisting of 'node-gyp rebuild'. In our 'install' phase, this
 | 
			
		||||
  ;; implicit 'install' script, if it is applicable, is explicitly added to
 | 
			
		||||
  ;; the "package.json" file. However, if another Guix package were to use a
 | 
			
		||||
  ;; Node.js package with such an 'install' script, the dependent package's
 | 
			
		||||
  ;; build process would fail, because 'node-gyp rebuild' would try to write
 | 
			
		||||
  ;; to the store.
 | 
			
		||||
  ;;
 | 
			
		||||
  ;; Here, if the installed "package.json" defines scripts.install as
 | 
			
		||||
  ;; "node-gyp rebuild", we replace it with a no-op. Importantly, deleting the
 | 
			
		||||
  ;; install script definition would not be enough, because the default
 | 
			
		||||
  ;; install script would cause the same problem.
 | 
			
		||||
  ;;
 | 
			
		||||
  ;; For further details, see:
 | 
			
		||||
  ;; - https://docs.npmjs.com/cli/v8/configuring-npm/package-json#default-values
 | 
			
		||||
  ;; - https://docs.npmjs.com/cli/v8/using-npm/scripts#best-practices
 | 
			
		||||
  (define installed-package.json
 | 
			
		||||
    (search-input-file outputs (string-append "/lib/node_modules/"
 | 
			
		||||
                                              (module-name ".")
 | 
			
		||||
                                              "/package.json")))
 | 
			
		||||
  ;; We don't want to use an atomic replacement here, because we often don't
 | 
			
		||||
  ;; even need to overwrite this file.  Therefore, let's use some helpers
 | 
			
		||||
  ;; that we'd otherwise not need.
 | 
			
		||||
  (define pkg-meta
 | 
			
		||||
    (call-with-input-file installed-package.json read-json))
 | 
			
		||||
  (define scripts
 | 
			
		||||
    (jsobject-ref pkg-meta "scripts" '(@)))
 | 
			
		||||
  (define (jsobject-set js key val)
 | 
			
		||||
    (jsobject-update* js (list key (const val))))
 | 
			
		||||
 | 
			
		||||
  (when (equal? "node-gyp rebuild" (jsobject-ref scripts "install" #f))
 | 
			
		||||
    (call-with-output-file installed-package.json
 | 
			
		||||
      (lambda (out)
 | 
			
		||||
        (write-json
 | 
			
		||||
         (jsobject-set pkg-meta
 | 
			
		||||
                       "scripts"
 | 
			
		||||
                       (jsobject-set scripts
 | 
			
		||||
                                     "install"
 | 
			
		||||
                                     "echo Guix: avoiding node-gyp rebuild"))
 | 
			
		||||
         out)))))
 | 
			
		||||
 | 
			
		||||
(define %standard-phases
 | 
			
		||||
  (modify-phases gnu:%standard-phases
 | 
			
		||||
    (add-after 'unpack 'set-home set-home)
 | 
			
		||||
| 
						 | 
				
			
			@ -251,7 +302,8 @@ exist."
 | 
			
		|||
    (replace 'build build)
 | 
			
		||||
    (replace 'check check)
 | 
			
		||||
    (add-before 'install 'repack repack)
 | 
			
		||||
    (replace 'install install)))
 | 
			
		||||
    (replace 'install install)
 | 
			
		||||
    (add-after 'install 'avoid-node-gyp-rebuild avoid-node-gyp-rebuild)))
 | 
			
		||||
 | 
			
		||||
(define* (node-build #:key inputs (phases %standard-phases)
 | 
			
		||||
                     #:allow-other-keys #:rest args)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue