summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--build-aux/test-env.in7
-rw-r--r--configure.ac17
-rw-r--r--doc/guix.texi30
-rw-r--r--etc/completion/fish/guix.fish2
-rw-r--r--guix/import/snix.scm467
-rw-r--r--guix/scripts/import.scm4
-rw-r--r--guix/scripts/import/nix.scm90
-rw-r--r--tests/snix.scm73
9 files changed, 4 insertions, 689 deletions
diff --git a/Makefile.am b/Makefile.am
index 062a7ba154f..04b4ed74ed0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -261,7 +261,6 @@ MODULES = \
261 guix/import/opam.scm \ 261 guix/import/opam.scm \
262 guix/import/print.scm \ 262 guix/import/print.scm \
263 guix/import/pypi.scm \ 263 guix/import/pypi.scm \
264 guix/import/snix.scm \
265 guix/import/stackage.scm \ 264 guix/import/stackage.scm \
266 guix/import/texlive.scm \ 265 guix/import/texlive.scm \
267 guix/import/utils.scm \ 266 guix/import/utils.scm \
@@ -300,7 +299,6 @@ MODULES = \
300 guix/scripts/import/go.scm \ 299 guix/scripts/import/go.scm \
301 guix/scripts/import/hackage.scm \ 300 guix/scripts/import/hackage.scm \
302 guix/scripts/import/json.scm \ 301 guix/scripts/import/json.scm \
303 guix/scripts/import/nix.scm \
304 guix/scripts/import/opam.scm \ 302 guix/scripts/import/opam.scm \
305 guix/scripts/import/pypi.scm \ 303 guix/scripts/import/pypi.scm \
306 guix/scripts/import/stackage.scm \ 304 guix/scripts/import/stackage.scm \
@@ -489,7 +487,6 @@ SCM_TESTS = \
489 tests/services/linux.scm \ 487 tests/services/linux.scm \
490 tests/sets.scm \ 488 tests/sets.scm \
491 tests/size.scm \ 489 tests/size.scm \
492 tests/snix.scm \
493 tests/status.scm \ 490 tests/status.scm \
494 tests/store-database.scm \ 491 tests/store-database.scm \
495 tests/store-deduplication.scm \ 492 tests/store-deduplication.scm \
diff --git a/build-aux/test-env.in b/build-aux/test-env.in
index 59ab58cc941..7efc43206c2 100644
--- a/build-aux/test-env.in
+++ b/build-aux/test-env.in
@@ -1,7 +1,7 @@
1#!/bin/sh 1#!/bin/sh
2 2
3# GNU Guix --- Functional package management for GNU 3# GNU Guix --- Functional package management for GNU
4# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> 4# Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2021 Ludovic Courtès <ludo@gnu.org>
5# 5#
6# This file is part of GNU Guix. 6# This file is part of GNU Guix.
7# 7#
@@ -91,14 +91,11 @@ then
91 # Place for the substituter's cache. 91 # Place for the substituter's cache.
92 XDG_CACHE_HOME="$GUIX_STATE_DIRECTORY/cache-$$" 92 XDG_CACHE_HOME="$GUIX_STATE_DIRECTORY/cache-$$"
93 93
94 # For the (guix import snix) tests.
95 NIXPKGS="@NIXPKGS@"
96
97 export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \ 94 export NIX_IGNORE_SYMLINK_STORE NIX_STORE_DIR \
98 GUIX_LOG_DIRECTORY GUIX_STATE_DIRECTORY GUIX_DATABASE_DIRECTORY \ 95 GUIX_LOG_DIRECTORY GUIX_STATE_DIRECTORY GUIX_DATABASE_DIRECTORY \
99 GUIX_BINARY_SUBSTITUTE_URL \ 96 GUIX_BINARY_SUBSTITUTE_URL \
100 GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES \ 97 GUIX_ALLOW_UNAUTHENTICATED_SUBSTITUTES \
101 GUIX_CONFIGURATION_DIRECTORY XDG_CACHE_HOME NIXPKGS 98 GUIX_CONFIGURATION_DIRECTORY XDG_CACHE_HOME
102 99
103 # Launch the daemon without chroot support because is may be 100 # Launch the daemon without chroot support because is may be
104 # unavailable, for instance if we're not running as root. 101 # unavailable, for instance if we're not running as root.
diff --git a/configure.ac b/configure.ac
index 7c1b9ef8dd7..f8b9376c1f0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -202,23 +202,6 @@ AC_SUBST([GZIP])
202AC_SUBST([BZIP2]) 202AC_SUBST([BZIP2])
203AC_SUBST([XZ]) 203AC_SUBST([XZ])
204 204
205AC_ARG_WITH([nixpkgs],
206 [AS_HELP_STRING([--with-nixpkgs=DIR],
207 [search for Nixpkgs in DIR (for testing purposes only)])],
208 [case "$withval" in
209 yes|no) AC_MSG_ERROR([Please use `--with-nixpkgs=DIR'.]);;
210 *) NIXPKGS="$withval";;
211 esac],
212 [])
213
214AC_MSG_CHECKING([for Nixpkgs source tree])
215if test -f "$NIXPKGS/default.nix"; then
216 AC_MSG_RESULT([$NIXPKGS])
217 AC_SUBST([NIXPKGS])
218else
219 AC_MSG_RESULT([not found])
220fi
221
222LIBGCRYPT_LIBDIR="no" 205LIBGCRYPT_LIBDIR="no"
223LIBGCRYPT_PREFIX="no" 206LIBGCRYPT_PREFIX="no"
224 207
diff --git a/doc/guix.texi b/doc/guix.texi
index 58bcfbdbb5f..2fe7ad3a2aa 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11417,36 +11417,6 @@ and outputs a package expression:
11417guix import json hello.json 11417guix import json hello.json
11418@end example 11418@end example
11419 11419
11420@item nix
11421Import metadata from a local copy of the source of the
11422@uref{https://nixos.org/nixpkgs/, Nixpkgs distribution}@footnote{This
11423relies on the @command{nix-instantiate} command of
11424@uref{https://nixos.org/nix/, Nix}.}. Package definitions in Nixpkgs are
11425typically written in a mixture of Nix-language and Bash code. This
11426command only imports the high-level package structure that is written in
11427the Nix language. It normally includes all the basic fields of a
11428package definition.
11429
11430When importing a GNU package, the synopsis and descriptions are replaced
11431by their canonical upstream variant.
11432
11433Usually, you will first need to do:
11434
11435@example
11436export NIX_REMOTE=daemon
11437@end example
11438
11439@noindent
11440so that @command{nix-instantiate} does not try to open the Nix database.
11441
11442As an example, the command below imports the package definition of
11443LibreOffice (more precisely, it imports the definition of the package
11444bound to the @code{libreoffice} top-level attribute):
11445
11446@example
11447guix import nix ~/path/to/nixpkgs libreoffice
11448@end example
11449
11450@item hackage 11420@item hackage
11451@cindex hackage 11421@cindex hackage
11452Import metadata from the Haskell community's central package archive 11422Import metadata from the Haskell community's central package archive
diff --git a/etc/completion/fish/guix.fish b/etc/completion/fish/guix.fish
index 422baab4bb1..8d1a1eb1e96 100644
--- a/etc/completion/fish/guix.fish
+++ b/etc/completion/fish/guix.fish
@@ -322,8 +322,6 @@ complete -f -c guix -n '__fish_guix_needs_command' -a import -d 'Run IMPORTER wi
322##### import gnu 322##### import gnu
323complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a gnu -d 'Return a package declaration template for PACKAGE, a GNU package.' 323complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a gnu -d 'Return a package declaration template for PACKAGE, a GNU package.'
324complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "never", and "interactive", which is also used when "key-download" is not specified.' 324complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "never", and "interactive", which is also used when "key-download" is not specified.'
325##### import nix
326complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a nix -d 'Import and convert the Nix expression ATTRIBUTE of NIXPKGS.'
327##### import pypi 325##### import pypi
328complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a pypi -d 'Import and convert the PyPI package for PACKAGE-NAME.' 326complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a pypi -d 'Import and convert the PyPI package for PACKAGE-NAME.'
329##### import cpan 327##### import cpan
diff --git a/guix/import/snix.scm b/guix/import/snix.scm
deleted file mode 100644
index 56934e8cf95..00000000000
--- a/guix/import/snix.scm
+++ /dev/null
@@ -1,467 +0,0 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix import snix)
20 #:use-module (sxml ssax)
21 #:use-module (ice-9 popen)
22 #:use-module (ice-9 match)
23 #:use-module (ice-9 rdelim)
24 #:use-module (ice-9 format)
25 #:use-module (ice-9 regex)
26 #:use-module (ice-9 vlist)
27 #:use-module (srfi srfi-1)
28 #:use-module (srfi srfi-9)
29 #:use-module (srfi srfi-11)
30 #:use-module (srfi srfi-26)
31 #:use-module (srfi srfi-37)
32 #:use-module (system foreign)
33 #:use-module (rnrs bytevectors)
34
35 ;; Use the 'package-name->name+version' procedure that works with
36 ;; hyphen-separate name/version, not the one that works with '@'-separated
37 ;; name/version. Subtle!
38 #:use-module ((guix utils) #:hide (package-name->name+version))
39 #:use-module ((guix build utils) #:select (package-name->name+version))
40
41 #:use-module (guix import utils)
42 #:use-module (guix base16)
43 #:use-module (guix base32)
44 #:use-module (guix config)
45 #:use-module (guix gnu-maintenance)
46 #:export (open-nixpkgs
47 xml->snix
48 nixpkgs->guix-package))
49
50;;; Commentary:
51;;;
52;;; Converting Nix code to s-expressions, and then to Guix `package'
53;;; declarations, using the XML output of `nix-instantiate'.
54;;;
55;;; Code:
56
57
58;;;
59;;; SNix.
60;;;
61
62;; Nix object types visible in the XML output of `nix-instantiate' and
63;; mapping to S-expressions (we map to sexps, not records, so that we
64;; can do pattern matching):
65;;
66;; at (at varpat attrspat)
67;; attr (attribute loc name value)
68;; attrs (attribute-set attributes)
69;; attrspat (attribute-set-pattern patterns)
70;; bool #f|#t
71;; derivation (derivation drv-path out-path attributes)
72;; ellipsis '...
73;; expr (snix loc body ...)
74;; function (function loc at|attrspat|varpat)
75;; int int
76;; list list
77;; null 'null
78;; path string
79;; string string
80;; unevaluated 'unevaluated
81;; varpat (varpat name)
82;;
83;; Initially ATTRIBUTES in `derivation' and `attribute-set' was a promise;
84;; however, handling `repeated' nodes makes it impossible to do anything
85;; lazily because the whole SXML tree has to be traversed to maintain the
86;; list of known derivations.
87
88(define (xml-element->snix elem attributes body derivations)
89 "Return an SNix element corresponding to XML element ELEM."
90
91 (define (loc)
92 (location (assq-ref attributes 'path)
93 (assq-ref attributes 'line)
94 (assq-ref attributes 'column)))
95
96 (case elem
97 ((at)
98 (values `(at ,(car body) ,(cadr body)) derivations))
99 ((attr)
100 (let ((name (assq-ref attributes 'name)))
101 (cond ((null? body)
102 (values `(attribute-pattern ,name) derivations))
103 ((and (pair? body) (null? (cdr body)))
104 (values `(attribute ,(loc) ,name ,(car body))
105 derivations))
106 (else
107 (error "invalid attribute body" name (loc) body)))))
108 ((attrs)
109 (values `(attribute-set ,(reverse body)) derivations))
110 ((attrspat)
111 (values `(attribute-set-pattern ,body) derivations))
112 ((bool)
113 (values (string-ci=? "true" (assq-ref attributes 'value))
114 derivations))
115 ((derivation)
116 (let ((drv-path (assq-ref attributes 'drvPath))
117 (out-path (assq-ref attributes 'outPath)))
118 (if (equal? body '(repeated))
119 (let ((body (vhash-assoc drv-path derivations)))
120 (if (pair? body)
121 (values `(derivation ,drv-path ,out-path ,(cdr body))
122 derivations)
123
124 ;; DRV-PATH hasn't been encountered yet but may be later
125 ;; (see <http://article.gmane.org/gmane.linux.distributions.nixos/5946>.)
126 ;; Return an `unresolved' node.
127 (values `(unresolved
128 ,(lambda (derivations)
129 (let ((body (vhash-assoc drv-path derivations)))
130 (if (pair? body)
131 `(derivation ,drv-path ,out-path
132 ,(cdr body))
133 (error "no previous occurrence of derivation"
134 drv-path)))))
135 derivations)))
136 (values `(derivation ,drv-path ,out-path ,body)
137 (vhash-cons drv-path body derivations)))))
138 ((ellipsis)
139 (values '... derivations))
140 ((expr)
141 (values `(snix ,(loc) ,@body) derivations))
142 ((function)
143 (values `(function ,(loc) ,body) derivations))
144 ((int)
145 (values (string->number (assq-ref attributes 'value))
146 derivations))
147 ((list)
148 (values body derivations))
149 ((null)
150 (values 'null derivations))
151 ((path)
152 (values (assq-ref attributes 'value) derivations))
153 ((repeated)
154 (values 'repeated derivations))
155 ((string)
156 (values (assq-ref attributes 'value) derivations))
157 ((unevaluated)
158 (values 'unevaluated derivations))
159 ((varpat)
160 (values `(varpat ,(assq-ref attributes 'name)) derivations))
161 (else (error "unhandled Nix XML element" elem))))
162
163(define (resolve snix derivations)
164 "Return a new SNix tree where `unresolved' nodes from SNIX have been
165replaced by the result of their application to DERIVATIONS, a vhash."
166 (let loop ((node snix)
167 (seen vlist-null))
168 (if (vhash-assq node seen)
169 (values node seen)
170 (match node
171 (('unresolved proc)
172 (let ((n (proc derivations)))
173 (values n seen)))
174 ((tag body ...)
175 (let ((body+seen (fold (lambda (n body+seen)
176 (call-with-values
177 (lambda ()
178 (loop n (cdr body+seen)))
179 (lambda (n* seen)
180 (cons (cons n* (car body+seen))
181 (vhash-consq n #t seen)))))
182 (cons '() (vhash-consq node #t seen))
183 body)))
184 (values (cons tag (reverse (car body+seen)))
185 (vhash-consq node #t (cdr body+seen)))))
186 (anything
187 (values anything seen))))))
188
189(define xml->snix
190 (let ((parse
191 (ssax:make-parser NEW-LEVEL-SEED
192 (lambda (elem-gi attributes namespaces expected-content
193 seed)
194 (cons '() (cdr seed)))
195
196 FINISH-ELEMENT
197 (lambda (elem-gi attributes namespaces parent-seed
198 seed)
199 (let ((snix (car seed))
200 (derivations (cdr seed)))
201 (let-values (((snix derivations)
202 (xml-element->snix elem-gi
203 attributes
204 snix
205 derivations)))
206 (cons (cons snix (car parent-seed))
207 derivations))))
208
209 CHAR-DATA-HANDLER
210 (lambda (string1 string2 seed)
211 ;; Discard inter-node strings, which are blanks.
212 seed))))
213 (lambda (port)
214 "Return the SNix represention of TREE, an SXML tree as returned by
215parsing the XML output of `nix-instantiate' on Nixpkgs."
216 (match (parse port (cons '() vlist-null))
217 (((snix) . derivations)
218 (resolve snix derivations))))))
219
220(define (attribute-value attribute)
221 "Return the value of ATTRIBUTE."
222 (match attribute
223 (('attribute _ _ value) value)))
224
225(define (derivation-source derivation)
226 "Return the \"src\" attribute of DERIVATION or #f if not found."
227 (match derivation
228 (('derivation _ _ (attributes ...))
229 (find-attribute-by-name "src" attributes))))
230
231(define (derivation-output-path derivation)
232 "Return the output path of DERIVATION."
233 (match derivation
234 (('derivation _ out-path _)
235 out-path)
236 (_ #f)))
237
238(define (source-output-path src)
239 "Return the output path of SRC, the \"src\" attribute of a derivation."
240 (derivation-output-path (attribute-value src)))
241
242(define (source-urls src)
243 "Return the URLs of SRC, the \"src\" attribute of a derivation."
244 (match src
245 (('attribute _ _ ('derivation _ _ (attributes ...)))
246 (match (find-attribute-by-name "urls" attributes)
247 (('attribute _ _ value)
248 value)))
249 (_ #f)))
250
251(define (source-sha256 src)
252 "Return the sha256 of SRC, the \"src\" attribute of a derivation, as a
253bytevector."
254 (match src
255 (('attribute _ _ ('derivation _ _ (attributes ...)))
256 (match (find-attribute-by-name "outputHash" attributes)
257 (('attribute _ _ value)
258 (match value
259 ((= string-length 52)
260 (nix-base32-string->bytevector value))
261 ((= string-length 64)
262 (base16-string->bytevector value))
263 (_
264 (error "unsupported hash format" value))))))
265 (_ #f)))
266
267(define (derivation-source-output-path derivation)
268 "Return the output path of the \"src\" attribute of DERIVATION or #f
269if DERIVATION lacks an \"src\" attribute."
270 (and=> (derivation-source derivation) source-output-path))
271
272(define* (open-nixpkgs nixpkgs #:optional attribute)
273 "Return an input pipe to the XML representation of Nixpkgs. When
274ATTRIBUTE is true, only that attribute is considered."
275 (with-fluids ((%default-port-encoding "UTF-8"))
276 (let ((cross-system (format #f "{
277 config = \"i686-guix-linux-gnu\";
278 libc = \"glibc\";
279 arch = \"guix\";
280 withTLS = true;
281 float = \"hard\";
282 openssl.system = \"linux-generic32\";
283 platform = (import ~a/pkgs/top-level/platforms.nix).sheevaplug;
284}" nixpkgs)))
285 (apply open-pipe* OPEN_READ
286 "nix-instantiate" "--strict" "--eval-only" "--xml"
287
288 ;; Pass a dummy `crossSystem' argument so that `buildInputs' and
289 ;; `nativeBuildInputs' are not coalesced.
290 ;; XXX: This is hacky and has other problems.
291 ;"--arg" "crossSystem" cross-system
292
293 `(,@(if attribute
294 `("-A" ,attribute)
295 '())
296 ,nixpkgs)))))
297
298(define (pipe-failed? pipe)
299 "Close pipe and return its status if it failed."
300 (let ((status (close-pipe pipe)))
301 (if (or (status:term-sig status)
302 (not (= (status:exit-val status) 0)))
303 status
304 #f)))
305
306(define (find-attribute-by-name name attributes)
307 "Return attribute NAME in ATTRIBUTES, an attribute set or list of SNix
308attributes, or #f if NAME cannot be found."
309 (find (lambda (a)
310 (match a
311 (('attribute _ (? (cut string=? <> name)) _)
312 a)
313 (_ #f)))
314 (match attributes
315 (('attribute-set (attributes ...))
316 attributes)
317 (_
318 attributes))))
319
320(define (license-variable license)
321 "Return the name of the (guix licenses) variable for LICENSE."
322 (match license
323 ("GPLv2+" 'gpl2+)
324 ("GPLv3+" 'gpl3+)
325 ("LGPLv2+" 'lgpl2.1+)
326 ("LGPLv2.1+" 'lgpl2.1+)
327 ("LGPLv3+" 'lgpl3+)
328 (('attribute-set _ ...)
329 ;; At some point in 2013, Nixpkgs switched to attribute sets to represent
330 ;; licenses. These are listed in lib/licenses.nix.
331 (match (and=> (find-attribute-by-name "shortName" license)
332 attribute-value)
333 ("agpl3Plus" 'agpl3+)
334 ("gpl2Plus" 'gpl2+)
335 ("gpl3Plus" 'gpl3+)
336 ("lgpl2Plus" 'lgpl2.0+)
337 ("lgpl21Plus" 'lgpl2.1+)
338 ("lgpl3Plus" 'lgpl3+)
339 ((? string? x) x)
340 (_ license)))
341 (_ license)))
342
343(define (package-source-output-path package)
344 "Return the output path of the \"src\" derivation of PACKAGE."
345 (derivation-source-output-path (attribute-value package)))
346
347
348;;;
349;;; Conversion of "Nix expressions" to "Guix expressions".
350;;;
351
352(define (snix-derivation->guix-package derivation)
353 "Return the `package' s-expression corresponding to SNix DERIVATION, a
354Nixpkgs `stdenv.mkDerivation'-style derivation, and the original source
355location of DERIVATION."
356 (match derivation
357 (('derivation _ _ (attributes ...))
358 (let*-values (((full-name loc)
359 (match (find-attribute-by-name "name" attributes)
360 (('attribute loc _ value)
361 (values value loc))
362 (_
363 (values #f #f))))
364 ((name version)
365 (package-name->name+version full-name)))
366 (define (convert-inputs type)
367 ;; Convert the derivation's input from a list of SNix derivations to
368 ;; a list of name/variable pairs.
369 (match (and=> (find-attribute-by-name type attributes)
370 attribute-value)
371 (#f
372 '())
373 ((inputs ...)
374 ;; Inputs can be either derivations or the null value.
375 (filter-map (match-lambda
376 (('derivation _ _ (attributes ...))
377 (let* ((full-name
378 (attribute-value
379 (find-attribute-by-name "name" attributes)))
380 (name (package-name->name+version full-name)))
381 (list name
382 (list 'unquote (string->symbol name)))))
383 ('null #f))
384 inputs))))
385
386 (define (maybe-inputs guix-name inputs)
387 (match inputs
388 (()
389 '())
390 ((inputs ...)
391 (list (list guix-name
392 (list 'quasiquote inputs))))))
393
394 (define (pretty-uri uri version)
395 (if version
396 (match (factorize-uri uri version)
397 ((items ...)
398 `(string-append ,@items))
399 (x x))
400 uri))
401
402 (let* ((source (find-attribute-by-name "src" attributes))
403 (urls (source-urls source))
404 (sha256 (source-sha256 source))
405 (meta (and=> (find-attribute-by-name "meta" attributes)
406 attribute-value)))
407 (values
408 `(package
409 (name ,name)
410 (version ,version)
411 (source (origin
412 (method url-fetch)
413 (uri ,(pretty-uri (car urls) version))
414 (sha256
415 (base32
416 ,(bytevector->nix-base32-string sha256)))))
417 (build-system gnu-build-system)
418
419 ;; When doing a native Nixpkgs build, `buildInputs' is empty and
420 ;; everything is in `nativeBuildInputs'. So we can't distinguish
421 ;; between both, here.
422 ;;
423 ;; Note that `nativeBuildInputs' was renamed from
424 ;; `buildNativeInputs' in Nixpkgs sometime around March 2013.
425 ,@(maybe-inputs 'inputs
426 (convert-inputs "nativeBuildInputs"))
427 ,@(maybe-inputs 'propagated-inputs
428 (convert-inputs "propagatedNativeBuildInputs"))
429
430 (home-page ,(and=> (find-attribute-by-name "homepage" meta)
431 attribute-value))
432 (synopsis
433 ;; For GNU packages, prefer the official synopsis.
434 ,(or (false-if-exception
435 (and=> (find (lambda (gnu-package)
436 (equal? (gnu-package-name gnu-package)
437 name))
438 (official-gnu-packages))
439 gnu-package-doc-summary))
440 (and=> (find-attribute-by-name "description" meta)
441 attribute-value)))
442 (description
443 ;; Likewise, prefer the official description of GNU packages.
444 ,(or (false-if-exception
445 (and=> (find (lambda (gnu-package)
446 (equal? (gnu-package-name gnu-package)
447 name))
448 (official-gnu-packages))
449 gnu-package-doc-description))
450 (and=> (find-attribute-by-name "longDescription" meta)
451 attribute-value)))
452 (license ,(and=> (find-attribute-by-name "license" meta)
453 (compose license-variable attribute-value))))
454 loc))))))
455
456(define (nixpkgs->guix-package nixpkgs attribute)
457 "Evaluate ATTRIBUTE in NIXPKGS, the file name of a Nixpkgs checkout,
458and return the `package' s-expression corresponding to that package."
459 (let ((port (open-nixpkgs nixpkgs attribute)))
460 (match (xml->snix port)
461 (('snix loc (and drv ('derivation _ ...)))
462 (and (not (pipe-failed? port))
463 (snix-derivation->guix-package drv)))
464 (_
465 (not (pipe-failed? port))))))
466
467;;; snix.scm ends here
diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm
index 98554ef79bf..bbd9a3b1906 100644
--- a/guix/scripts/import.scm
+++ b/guix/scripts/import.scm
@@ -1,5 +1,5 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2014, 2020 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2012, 2013, 2014, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2014 David Thompson <davet@gnu.org> 3;;; Copyright © 2014 David Thompson <davet@gnu.org>
4;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com> 4;;; Copyright © 2018 Kyle Meyer <kyle@kyleam.com>
5;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net> 5;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
@@ -76,7 +76,7 @@ rather than \\n."
76;;; Entry point. 76;;; Entry point.
77;;; 77;;;
78 78
79(define importers '("gnu" "nix" "pypi" "cpan" "hackage" "stackage" "elpa" "gem" 79(define importers '("gnu" "pypi" "cpan" "hackage" "stackage" "elpa" "gem"
80 "go" "cran" "crate" "texlive" "json" "opam")) 80 "go" "cran" "crate" "texlive" "json" "opam"))
81 81
82(define (resolve-importer name) 82(define (resolve-importer name)
diff --git a/guix/scripts/import/nix.scm b/guix/scripts/import/nix.scm
deleted file mode 100644
index 45ca7e3fcf1..00000000000
--- a/guix/scripts/import/nix.scm
+++ /dev/null
@@ -1,90 +0,0 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2016 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2014 David Thompson <davet@gnu.org>
4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (guix scripts import nix)
21 #:use-module (guix ui)
22 #:use-module (guix utils)
23 #:use-module (guix scripts)
24 #:use-module (guix import snix)
25 #:use-module (guix scripts import)
26 #:use-module (srfi srfi-1)
27 #:use-module (srfi srfi-11)
28 #:use-module (srfi srfi-37)
29 #:use-module (ice-9 match)
30 #:export (guix-import-nix))
31
32
33;;;
34;;; Command-line options.
35;;;
36
37(define %default-options
38 '())
39
40(define (show-help)
41 (display (G_ "Usage: guix import nix NIXPKGS ATTRIBUTE
42Import and convert the Nix expression ATTRIBUTE of NIXPKGS.\n"))
43 (display (G_ "
44 -h, --help display this help and exit"))
45 (display (G_ "
46 -V, --version display version information and exit"))
47 (newline)
48 (show-bug-report-information))
49
50(define %options
51 ;; Specification of the command-line options.
52 (cons* (option '(#\h "help") #f #f
53 (lambda args
54 (show-help)
55 (exit 0)))
56 (option '(#\V "version") #f #f
57 (lambda args
58 (show-version-and-exit "guix import nix")))
59 %standard-import-options))
60
61
62;;;
63;;; Entry point.
64;;;
65
66(define (guix-import-nix . args)
67 (define (parse-options)
68 ;; Return the alist of option values.
69 (args-fold* args %options
70 (lambda (opt name arg result)
71 (leave (G_ "~A: unrecognized option~%") name))
72 (lambda (arg result)
73 (alist-cons 'argument arg result))
74 %default-options))
75
76 (let* ((opts (parse-options))
77 (args (filter-map (match-lambda
78 (('argument . value)
79 value)
80 (_ #f))
81 (reverse opts))))
82 (match args
83 ((nixpkgs attribute)
84 (let-values (((expr loc)
85 (nixpkgs->guix-package nixpkgs attribute)))
86 (format #t ";; converted from ~a:~a~%~%"
87 (location-file loc) (location-line loc))
88 expr))
89 (x
90 (leave (G_ "wrong number of arguments~%"))))))
diff --git a/tests/snix.scm b/tests/snix.scm
deleted file mode 100644
index 4c31e3389d9..00000000000
--- a/tests/snix.scm
+++ /dev/null
@@ -1,73 +0,0 @@
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2015 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (test-snix)
20 #:use-module (guix import snix)
21 #:use-module (srfi srfi-1)
22 #:use-module (srfi srfi-64)
23 #:use-module (ice-9 match))
24
25(define %nixpkgs-directory
26 (getenv "NIXPKGS"))
27
28(define factorize-uri
29 (@@ (guix import snix) factorize-uri))
30
31(define-syntax-rule (every? proc lists ...)
32 (not (not (every proc lists ...))))
33
34(test-begin "snix")
35
36(test-assert "factorize-uri"
37 (every? (match-lambda
38 ((uri version '-> expected)
39 (equal? (factorize-uri uri version)
40 expected)))
41 '(("http://example.com/foo.tgz" "1.0"
42 -> "http://example.com/foo.tgz")
43 ("http://example.com/foo-2.8.tgz" "2.8"
44 -> ("http://example.com/foo-" version ".tgz"))
45 ("http://example.com/2.8/foo-2.8.tgz" "2.8"
46 -> ("http://example.com/" version "/foo-" version ".tgz")))))
47
48(test-skip (if (and %nixpkgs-directory
49 (file-exists? (string-append %nixpkgs-directory
50 "/default.nix")))
51 0
52 1))
53
54(test-assert "nixpkgs->guix-package"
55 (match (nixpkgs->guix-package %nixpkgs-directory "guile")
56 (('package
57 ('name "guile")
58 ('version (? string?))
59 ('source ('origin _ ...))
60 ('build-system _)
61 ('inputs ('quasiquote (inputs ...)))
62 ('propagated-inputs ('quasiquote (pinputs ...)))
63 ('home-page (? string?))
64 ('synopsis (? string?))
65 ('description (? string?))
66 ('license (? symbol?)))
67 (and (member '("libffi" ,libffi) inputs)
68 (member '("gmp" ,gmp) pinputs)
69 #t))
70 (x
71 (pk 'fail x #f))))
72
73(test-end "snix")