* [bug#28251] [PATCH 0/3] Add generic JSON importer @ 2017-08-27 15:58 Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Ricardo Wurmus @ 2017-08-27 15:58 UTC (permalink / raw) To: 28251; +Cc: Ricardo Wurmus Hi Guix, this patch set adds a somewhat unusual importer. Assume we have a file "package.json" with the following contents: --8<---------------cut here---------------start------------->8--- { "name": "hello", "version": "2.10", "source": { "method": "url-fetch", "uri": "mirror://gnu/hello/hello-2.10.tar.gz", "sha256": { "base32": "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i" } } "build-system": "gnu", "home-page": "https://www.gnu.org/software/hello/", "synopsis": "Hello, GNU world: An example GNU package", "description": "It really works.", "license": "GPL-3.0+", "inputs": ["r-minimal@3", "ghc-pandoc", "samtools@0"] } --8<---------------cut here---------------end--------------->8--- Let’s run the new “json” importer on this file: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix import json package.json (package (name "hello") (version "2.10") (source (origin (uri (string-append "mirror://gnu/hello/hello-2.10.tar.gz")) (method url-fetch) (sha256 (base32 "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) (build-system r-build-system) (inputs `(("r-minimal" ,(@ (gnu packages statistics) r-minimal)) ("ghc-pandoc" ,(@ (gnu packages haskell) ghc-pandoc)) ("samtools" ,(@ (gnu packages bioinformatics) samtools-0.1)))) (home-page "https://www.gnu.org/software/hello/") (synopsis "Hello, GNU world: An example GNU package") (description "It really works.") (license gpl3+)) --8<---------------cut here---------------end--------------->8--- What you don’t see here is that the JSON importer internally creates a package object, which could already be built (e.g. from within the REPL) — without having to write it to a file first and setting GUIX_PACKAGE_PATH. What is this good for? Users could create simple Guix packages for their own immature projects using a syntax that they may be more familiar with and generate a proper Scheme package definition from it to allow other people to install it. For more complicated packages they would, of course, be better served by using the usual Scheme syntax for package definitions. To make the importer behave like all other importers, we use the new “package->code” procedure, which takes a package and generates the code, which would create an equivalent package object when evaluated. There are some minor problems with “package->code”, which are marked with FIXME comments. We probably shouldn’t print out “(@ (gnu packages statistics) r-minimal)” and instead let “package->code” return two values: the package code and a list of modules needed to evaluate it. What do you think? Terrible? Exciting? Both? *raises hand* Documentation of this importer is missing because I’m not sure if this is the best way of doing this. Let’s discuss! ~~ Ricardo Ricardo Wurmus (3): packages: Add package->code. import: Add generic data to package converter. import: Add JSON importer. guix/import/utils.scm | 77 ++++++++++++++++++++++++- guix/packages.scm | 131 +++++++++++++++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/json.scm | 101 +++++++++++++++++++++++++++++++++ 4 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 guix/scripts/import/json.scm -- 2.14.1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 1/3] packages: Add package->code. 2017-08-27 15:58 [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus @ 2017-08-27 16:00 ` Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 2/3] import: Add generic data to package converter Ricardo Wurmus ` (2 more replies) 2017-08-28 12:27 ` [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus 2017-09-01 15:35 ` Ludovic Courtès 2 siblings, 3 replies; 12+ messages in thread From: Ricardo Wurmus @ 2017-08-27 16:00 UTC (permalink / raw) To: 28251; +Cc: Ricardo Wurmus * guix/packages.scm (package->code): New procedure. --- guix/packages.scm | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/guix/packages.scm b/guix/packages.scm index f619d9b37..d25920010 100644 --- a/guix/packages.scm +++ b/guix/packages.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org> ;;; Copyright © 2016 Alex Kost <alezost@gmail.com> ;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il> +;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -31,6 +32,7 @@ #:use-module (guix derivations) #:use-module (guix memoization) #:use-module (guix build-system) + #:use-module (guix licenses) #:use-module (guix search-paths) #:use-module (guix sets) #:use-module (ice-9 match) @@ -84,6 +86,7 @@ package-maintainers package-properties package-location + package->code hidden-package hidden-package? package-superseded @@ -306,6 +309,134 @@ name of its URI." package) 16))))) +;; FIXME: the quasiquoted arguments field may contain embedded package +;; objects, e.g. in #:disallowed-references; they will just be printed with +;; their usual #<package ...> representation, not as variable names. +(define (package->code package) + "Return an S-expression representing the source code that produces PACKAGE +when evaluated." + ;; The module in which the package PKG is defined + (define (package-module-name pkg) + (map string->symbol + (string-split (string-drop-right + (location-file (package-location pkg)) 4) + #\/))) + + ;; Return the first candidate variable name that is bound to VAL. + ;; TODO: avoid '%pkg-config + (define (variable-name val mod) + (let ((candidates (filter identity + (module-map + (lambda (sym var) + (if (equal? val (variable-ref var)) sym #f)) + (resolve-interface mod))))) + (if (null? candidates) #f (car candidates)))) + + ;; Print either license variable name or the code for a license object + (define (print-license lic) + (let ((var (variable-name lic '(guix licenses)))) + (or var + `(license + (name ,(license-name lic)) + (uri ,(license-uri lic)) + (comment ,(license-comment lic)))))) + + (define (print-search-path-specification spec) + `(search-path-specification + (variable ,(search-path-specification-variable spec)) + (files (list ,@(search-path-specification-files spec))) + (separator ,(search-path-specification-separator spec)) + (file-type (quote ,(search-path-specification-file-type spec))) + (file-pattern ,(search-path-specification-file-pattern spec)))) + + (define (print-source source version) + ;; FIXME: we cannot use factorize-uri because (guix import utils) + ;; cannot be imported in this module. + (let ((factorize-uri (lambda (uri version) + (list uri)))) + (match source + (($ <origin> uri method sha256 file-name patches) + `(origin + (uri (string-append ,@(factorize-uri uri version))) + (method ,(procedure-name method)) + (sha256 + (base32 + ,(format #f "~a" (bytevector->nix-base32-string sha256)))) + ;; FIXME: in order to be able to throw away the directory prefix, + ;; we just assume that the patch files can be found with + ;; "search-patches". + ,@(let ((ps (force patches))) + (if (null? ps) '() + `((patches (search-patches ,@(map basename ps))))))))))) + + (define (print-package-lists lsts) + (list 'quasiquote + (map (match-lambda + ((label pkg) + (let ((mod (package-module-name pkg))) + (list label + ;; FIXME: using '@ certainly isn't pretty, but it + ;; avoids having to import the individual package + ;; modules. + (list 'unquote + (list '@ mod (variable-name pkg mod))))))) + lsts))) + + (match package + (($ <package> name version source build-system + arguments inputs propagated-inputs native-inputs + self-native-input? + outputs + native-search-paths + search-paths + replacement + synopsis description license + home-page supported-systems maintainers + properties location) + `(package + (name ,name) + (version ,version) + (source ,(print-source source version)) + ,@(if (null? properties) '() + `((properties ,properties))) + ,@(let ((rep (replacement))) + (if rep + `((replacement ,rep)) + '())) + (build-system ,(symbol-append (build-system-name build-system) + '-build-system)) + ,@(let ((args (arguments))) + (if (null? args) '() + `((arguments ,(list 'quasiquote (arguments)))))) + ,@(if (equal? outputs '("out")) '() + `((outputs (list ,@outputs)))) + ,@(let ((pkgs (native-inputs))) + (if (null? pkgs) '() + `((native-inputs ,(print-package-lists pkgs))))) + ,@(let ((pkgs (inputs))) + (if (null? pkgs) '() + `((inputs ,(print-package-lists pkgs))))) + ,@(let ((pkgs (propagated-inputs))) + (if (null? pkgs) '() + `((propagated-inputs ,(print-package-lists pkgs))))) + ,@(if (lset= string=? supported-systems %supported-systems) + '() + `((supported-systems (list ,@supported-systems)))) + ,@(let ((paths (map print-search-path-specification native-search-paths))) + (if (null? paths) '() + `((native-search-paths + (list ,@paths))))) + ,@(let ((paths (map print-search-path-specification search-paths))) + (if (null? paths) '() + `((search-paths + (list ,@paths))))) + (home-page ,home-page) + (synopsis ,synopsis) + (description ,description) + (license ,(if (list? license) + `(list ,@(map print-license license)) + (print-license license))))))) + (define (package-upstream-name package) "Return the upstream name of PACKAGE, which could be different from the name it has in Guix." -- 2.14.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 2/3] import: Add generic data to package converter. 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus @ 2017-08-27 16:00 ` Ricardo Wurmus 2017-09-04 13:04 ` Ludovic Courtès 2017-08-27 16:00 ` [bug#28251] [PATCH 3/3] import: Add JSON importer Ricardo Wurmus 2017-09-01 15:55 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ludovic Courtès 2 siblings, 1 reply; 12+ messages in thread From: Ricardo Wurmus @ 2017-08-27 16:00 UTC (permalink / raw) To: 28251; +Cc: Ricardo Wurmus * guix/import/utils.scm (build-system-modules, guix-modules): New variables. (lookup-build-system-by-name, specs->package-lists, convert-source, data->guix-package): New procedures. --- guix/import/utils.scm | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/guix/import/utils.scm b/guix/import/utils.scm index be1980d08..edc6fda26 100644 --- a/guix/import/utils.scm +++ b/guix/import/utils.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2016 Jelle Licht <jlicht@fsfe.org> ;;; Copyright © 2016 David Craven <david@craven.ch> +;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -25,6 +26,10 @@ #:use-module (guix http-client) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix utils) + #:use-module (guix packages) + #:use-module (guix discovery) + #:use-module (guix build-system) + #:use-module (gnu packages) #:use-module (ice-9 match) #:use-module (ice-9 regex) #:use-module (srfi srfi-1) @@ -45,7 +50,9 @@ license->symbol snake-case - beautify-description)) + beautify-description + + data->guix-package)) (define (factorize-uri uri version) "Factorize URI, a package tarball URI as a string, such that any occurrences @@ -241,3 +248,71 @@ package definition." (('package ('name (? string? name)) _ ...) `(define-public ,(string->symbol name) ,guix-package)))) + +(define build-system-modules + (all-modules (map (lambda (entry) + `(,entry . "guix/build-system")) + %load-path))) + +(define guix-modules + (all-modules (map (lambda (entry) + `(,entry . "guix")) + %load-path))) + +(define (lookup-build-system-by-name name) + (fold-module-public-variables (lambda (obj result) + (if (and (build-system? obj) + (eq? name (build-system-name obj))) + obj result)) + #f + build-system-modules)) + +(define (specs->package-lists specs) + (map (lambda (spec) + (let ((pkg (specification->package spec))) + (list (package-name pkg) pkg))) + specs)) + +(define (convert-source source) + (match source + ((? string? file) (local-file file)) + (#f #f) + (orig (let ((sha (match (car (assoc-ref orig "sha256")) + (("base32" . value) + (base32 value)) + (_ #f)))) + (origin + (method (match (assoc-ref orig "method") + ("url-fetch" (@ (guix download) url-fetch)) + ("git-fetch" (@ (guix git-download) git-fetch)) + ("svn-fetch" (@ (guix svn-download) svn-fetch)) + ("hg-fetch" (@ (guix hg-download) hg-fetch)) + (_ #f))) + (uri (assoc-ref orig "uri")) + (sha256 sha)))))) + +(define (data->guix-package meta) + (package + (name (assoc-ref meta "name")) + (version (assoc-ref meta "version")) + (source (convert-source (assoc-ref meta "source"))) + (build-system + (lookup-build-system-by-name + (string->symbol (assoc-ref meta "build-system")))) + (native-inputs + (specs->package-lists (or (assoc-ref meta "native-inputs") '()))) + (inputs + (specs->package-lists (or (assoc-ref meta "inputs") '()))) + (propagated-inputs + (specs->package-lists (or (assoc-ref meta "propagated-inputs") '()))) + (home-page + (assoc-ref meta "home-page")) + (synopsis + (assoc-ref meta "synopsis")) + (description + (assoc-ref meta "description")) + (license + (let ((l (assoc-ref meta "license"))) + (or (module-ref (resolve-interface '(guix licenses) #:prefix 'license:) + (spdx-string->license l)) + (fsdg-compatible l)))))) -- 2.14.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 2/3] import: Add generic data to package converter. 2017-08-27 16:00 ` [bug#28251] [PATCH 2/3] import: Add generic data to package converter Ricardo Wurmus @ 2017-09-04 13:04 ` Ludovic Courtès 0 siblings, 0 replies; 12+ messages in thread From: Ludovic Courtès @ 2017-09-04 13:04 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: 28251 Hello! Ricardo Wurmus <rekado@elephly.net> skribis: > * guix/import/utils.scm (build-system-modules, guix-modules): New variables. > (lookup-build-system-by-name, specs->package-lists, convert-source, > data->guix-package): New procedures. [...] > +(define build-system-modules > + (all-modules (map (lambda (entry) > + `(,entry . "guix/build-system")) > + %load-path))) > + > +(define guix-modules > + (all-modules (map (lambda (entry) > + `(,entry . "guix")) > + %load-path))) ‘all-modules’ causes a directory traversal, so it should not be called at the top level. The solution is to turn these two things in a promise or a thunk or probably an ‘mlambda’ thunk (depending on whether they are expected to be called frequently.) > +(define (lookup-build-system-by-name name) > + (fold-module-public-variables (lambda (obj result) Docstring please. :-) > +(define (specs->package-lists specs) > + (map (lambda (spec) > + (let ((pkg (specification->package spec))) > + (list (package-name pkg) pkg))) > + specs)) This should probably use ‘specification->package+output’ so that one can use specs like “hwloc:lib”. > +(define (convert-source source) Maybe ‘source-spec->object’? > + (match source > + ((? string? file) (local-file file)) > + (#f #f) > + (orig (let ((sha (match (car (assoc-ref orig "sha256")) > + (("base32" . value) > + (base32 value)) > + (_ #f)))) > + (origin > + (method (match (assoc-ref orig "method") > + ("url-fetch" (@ (guix download) url-fetch)) > + ("git-fetch" (@ (guix git-download) git-fetch)) > + ("svn-fetch" (@ (guix svn-download) svn-fetch)) > + ("hg-fetch" (@ (guix hg-download) hg-fetch)) > + (_ #f))) > + (uri (assoc-ref orig "uri")) > + (sha256 sha)))))) Though as discussed earlier, I’m unsure about exposing “url-fetch” and co. in the spec that people write. > +(define (data->guix-package meta) Maybe ‘alist->package’? Ludo’. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 3/3] import: Add JSON importer. 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 2/3] import: Add generic data to package converter Ricardo Wurmus @ 2017-08-27 16:00 ` Ricardo Wurmus 2017-09-04 13:04 ` Ludovic Courtès 2017-09-01 15:55 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ludovic Courtès 2 siblings, 1 reply; 12+ messages in thread From: Ricardo Wurmus @ 2017-08-27 16:00 UTC (permalink / raw) To: 28251; +Cc: Ricardo Wurmus * guix/scripts/import/json.scm: New file. * guix/scripts/import.scm (importers): Add json. --- guix/scripts/import.scm | 2 +- guix/scripts/import/json.scm | 101 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 guix/scripts/import/json.scm diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm index 9bba074e8..67bc7a755 100644 --- a/guix/scripts/import.scm +++ b/guix/scripts/import.scm @@ -74,7 +74,7 @@ rather than \\n." ;;; (define importers '("gnu" "nix" "pypi" "cpan" "hackage" "stackage" "elpa" "gem" - "cran" "crate" "texlive")) + "cran" "crate" "texlive" "json")) (define (resolve-importer name) (let ((module (resolve-interface diff --git a/guix/scripts/import/json.scm b/guix/scripts/import/json.scm new file mode 100644 index 000000000..b459ef819 --- /dev/null +++ b/guix/scripts/import/json.scm @@ -0,0 +1,101 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> +;;; Copyright © 2015, 2017 Ricardo Wurmus <rekado@elephly.net> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (guix scripts import json) + #:use-module (json) + #:use-module (guix ui) + #:use-module (guix utils) + #:use-module (guix scripts) + #:use-module (guix import utils) + #:use-module (guix scripts import) + #:use-module (guix packages) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9 gnu) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-37) + #:use-module (srfi srfi-41) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (ice-9 format) + #:export (guix-import-json)) + +\f +;;; +;;; Command-line options. +;;; + +(define %default-options + '()) + +(define (show-help) + (display (G_ "Usage: guix import json PACKAGE-FILE +Import and convert the JSON package definition in PACKAGE-FILE.\n")) + (display (G_ " + -h, --help display this help and exit")) + (display (G_ " + -V, --version display version information and exit")) + (newline) + (show-bug-report-information)) + +(define %options + ;; Specification of the command-line options. + (cons* (option '(#\h "help") #f #f + (lambda args + (show-help) + (exit 0))) + (option '(#\V "version") #f #f + (lambda args + (show-version-and-exit "guix import json"))) + %standard-import-options)) + +\f +;;; +;;; Entry point. +;;; + +(define (guix-import-json . args) + (define (parse-options) + ;; Return the alist of option values. + (args-fold* args %options + (lambda (opt name arg result) + (leave (G_ "~A: unrecognized option~%") name)) + (lambda (arg result) + (alist-cons 'argument arg result)) + %default-options)) + + (let* ((opts (parse-options)) + (args (filter-map (match-lambda + (('argument . value) + value) + (_ #f)) + (reverse opts)))) + (match args + ((file-name) + (catch 'json-invalid + (lambda () + (let ((json (json-string->scm + (with-input-from-file file-name read-string)))) + ;; TODO: also print define-module boilerplate + (package->code (data->guix-package (hash-table->alist json))))) + (lambda () + (leave (G_ "invalid JSON in file '~a'~%") file-name)))) + (() + (leave (G_ "too few arguments~%"))) + ((many ...) + (leave (G_ "too many arguments~%")))))) -- 2.14.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 3/3] import: Add JSON importer. 2017-08-27 16:00 ` [bug#28251] [PATCH 3/3] import: Add JSON importer Ricardo Wurmus @ 2017-09-04 13:04 ` Ludovic Courtès 0 siblings, 0 replies; 12+ messages in thread From: Ludovic Courtès @ 2017-09-04 13:04 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: 28251 Ricardo Wurmus <rekado@elephly.net> skribis: > * guix/scripts/import/json.scm: New file. > * guix/scripts/import.scm (importers): Add json. With a bit of doc, this looks all good! Ludo'. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 1/3] packages: Add package->code. 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 2/3] import: Add generic data to package converter Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 3/3] import: Add JSON importer Ricardo Wurmus @ 2017-09-01 15:55 ` Ludovic Courtès 2017-09-28 11:19 ` bug#28251: " Ricardo Wurmus 2 siblings, 1 reply; 12+ messages in thread From: Ludovic Courtès @ 2017-09-01 15:55 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: 28251 Ricardo Wurmus <rekado@elephly.net> skribis: > * guix/packages.scm (package->code): New procedure. We’ll need tests for this. :-) I would move it to (guix import utils) or a new (guix import print) module or similar (which will also allow us to use ‘factorize-uri’). In my mind, eventually all importers will produce a <package> object directly, and so this will be a core part of the import machinery. Since it’s not a crucial component, I would prefer to have it out of (guix packages) though. > +;; FIXME: the quasiquoted arguments field may contain embedded package > +;; objects, e.g. in #:disallowed-references; they will just be printed with > +;; their usual #<package ...> representation, not as variable names. Not sure how to solve that; maybe we can ignore for now. > +(define (package->code package) > + "Return an S-expression representing the source code that produces PACKAGE > +when evaluated." Like you wrote, it would be nice to also return a spec of modules in scope, like: ((gnu packages r) ((guix licenses) #:prefix license:)) WDYT? That way, we can eventually change ‘guix import’ to systematically print both the ‘define-module’ clause and the package definition. > + ;; The module in which the package PKG is defined > + (define (package-module-name pkg) > + (map string->symbol > + (string-split (string-drop-right > + (location-file (package-location pkg)) 4) > + #\/))) > + > + ;; Return the first candidate variable name that is bound to VAL. > + ;; TODO: avoid '%pkg-config > + (define (variable-name val mod) > + (let ((candidates (filter identity > + (module-map > + (lambda (sym var) > + (if (equal? val (variable-ref var)) sym #f)) > + (resolve-interface mod))))) > + (if (null? candidates) #f (car candidates)))) > + I think we should compare values with ‘eq?’ (usually we’re concerned with pointer identity of records), and also use ‘module-for-each’ + ‘let/ec’ to avoid building a list for nothing, like: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> (match (let/ec return (module-for-each (lambda (sym var) (if (eq? + (variable-ref var)) (return sym) #f)) the-scm-module)) ((? symbol? sym) sym) (_ #f)) $17 = + --8<---------------cut here---------------end--------------->8--- > + ;; Print either license variable name or the code for a license object > + (define (print-license lic) Nitpick: I’d rename all the ‘print-*’ procedures to ‘*->code’. > + (match package > + (($ <package> name version source build-system If we move this to (guix import …), we can no longer match on the record, but that’s not necessarily a bad thing anyway. :-) > + ,@(let ((args (arguments))) > + (if (null? args) '() > + `((arguments ,(list 'quasiquote (arguments)))))) > + ,@(if (equal? outputs '("out")) '() > + `((outputs (list ,@outputs)))) > + ,@(let ((pkgs (native-inputs))) > + (if (null? pkgs) '() > + `((native-inputs ,(print-package-lists pkgs))))) > + ,@(let ((pkgs (inputs))) > + (if (null? pkgs) '() > + `((inputs ,(print-package-lists pkgs))))) > + ,@(let ((pkgs (propagated-inputs))) > + (if (null? pkgs) '() > + `((propagated-inputs ,(print-package-lists pkgs))))) ‘match’! :-) This looks pretty cool already! Thanks, Ludo’. ^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#28251: [PATCH 1/3] packages: Add package->code. 2017-09-01 15:55 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ludovic Courtès @ 2017-09-28 11:19 ` Ricardo Wurmus 0 siblings, 0 replies; 12+ messages in thread From: Ricardo Wurmus @ 2017-09-28 11:19 UTC (permalink / raw) To: Ludovic Courtès; +Cc: 28251-done Ludovic Courtès <ludo@gnu.org> writes: > Ricardo Wurmus <rekado@elephly.net> skribis: > >> * guix/packages.scm (package->code): New procedure. > > We’ll need tests for this. :-) I’ve added some simple tests to tests/print.scm and import-utils.scm. > I would move it to (guix import utils) or a new (guix import print) > module or similar (which will also allow us to use ‘factorize-uri’). In > my mind, eventually all importers will produce a <package> object > directly, and so this will be a core part of the import machinery. > Since it’s not a crucial component, I would prefer to have it out of > (guix packages) though. Okay, done. >> +;; FIXME: the quasiquoted arguments field may contain embedded package >> +;; objects, e.g. in #:disallowed-references; they will just be printed with >> +;; their usual #<package ...> representation, not as variable names. > > Not sure how to solve that; maybe we can ignore for now. That’s why I originally experimented with overriding the printer. For the purposes of a JSON importer, however, this really isn’t important. >> +(define (package->code package) >> + "Return an S-expression representing the source code that produces PACKAGE >> +when evaluated." > > Like you wrote, it would be nice to also return a spec of modules in > scope, like: > > ((gnu packages r) > ((guix licenses) #:prefix license:)) > > WDYT? I’ll leave this as a later improvement, but yes: I’ll add this at some point. > I think we should compare values with ‘eq?’ (usually we’re concerned > with pointer identity of records), and also use ‘module-for-each’ + > ‘let/ec’ to avoid building a list for nothing That’s good! > Nitpick: I’d rename all the ‘print-*’ procedures to ‘*->code’. Done. I’ve implemented the other suggested changes and added some documentation. I’ll push it to master in a few minutes. Thanks for the comments! -- Ricardo GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC https://elephly.net ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 0/3] Add generic JSON importer 2017-08-27 15:58 [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus @ 2017-08-28 12:27 ` Ricardo Wurmus 2017-09-01 15:35 ` Ludovic Courtès 2 siblings, 0 replies; 12+ messages in thread From: Ricardo Wurmus @ 2017-08-28 12:27 UTC (permalink / raw) To: 28251 I have since made a couple of minor changes like adding a missing (guix gexp) import, adding the new script to the MODULES in Makefile.am, and adding a simple test for “data->guix-package”. I also have a small patch to “guix build -f”; given a file ending on “.json” it will parse the JSON and run “data->guix-package”. I have confirmed that this works for the “hello” package in JSON format. If this looks like a good idea I’ll convert the recursive CRAN importer to produce package objects; as a next step I’d extend “guix build” to accept a “--via=IMPORTER” option, which would cause a package to be imported and then built without requiring the manual work of writing or generating a package definition in Scheme. (Optionally, it could generate the code that could be contributed to Guix.) This is not meant to ever replace Scheme package definitions, but I think it can make importers useful to users, not only developers. -- Ricardo GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC https://elephly.net ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 0/3] Add generic JSON importer 2017-08-27 15:58 [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus 2017-08-28 12:27 ` [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus @ 2017-09-01 15:35 ` Ludovic Courtès 2017-09-28 11:23 ` Ricardo Wurmus 2 siblings, 1 reply; 12+ messages in thread From: Ludovic Courtès @ 2017-09-01 15:35 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: 28251 Hi Ricardo! Ricardo Wurmus <rekado@elephly.net> skribis: > this patch set adds a somewhat unusual importer. Assume we have a file > "package.json" with the following contents: > > { > "name": "hello", > "version": "2.10", > "source": { > "method": "url-fetch", > "uri": "mirror://gnu/hello/hello-2.10.tar.gz", > "sha256": { > "base32": "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i" > } > } > "build-system": "gnu", > "home-page": "https://www.gnu.org/software/hello/", > "synopsis": "Hello, GNU world: An example GNU package", > "description": "It really works.", > "license": "GPL-3.0+", > "inputs": ["r-minimal@3", "ghc-pandoc", "samtools@0"] > } Neat! I wonder if we could further simplify the “source” part, like allowing (maybe optionally) for: "source": "mirror://gnu…" and then letting the importer download the thing and fill in the hash. Likewise for a Git checkout: "git": { "commit": "cabba9e"; "url": "…" }; Thoughts? > What do you think? Terrible? Exciting? Both? *raises hand* Both! :-) As discussed at the GHM, I don’t fully measure that, but it can probably help us reach out to more people. Thanks! Ludo’, who goes look at the patches. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 0/3] Add generic JSON importer 2017-09-01 15:35 ` Ludovic Courtès @ 2017-09-28 11:23 ` Ricardo Wurmus 2017-09-28 19:58 ` Ludovic Courtès 0 siblings, 1 reply; 12+ messages in thread From: Ricardo Wurmus @ 2017-09-28 11:23 UTC (permalink / raw) To: Ludovic Courtès; +Cc: 28251 Ludovic Courtès <ludo@gnu.org> writes: > I wonder if we could further simplify the “source” part, like allowing > (maybe optionally) for: > > "source": "mirror://gnu…" > > and then letting the importer download the thing and fill in the hash. > Likewise for a Git checkout: > > "git": { "commit": "cabba9e"; "url": "…" }; > > Thoughts? I have added support for a simple source string as in the first example. I left the support for a direct translation of origin expressions unchanged, because I’m not sure yet how to express this. So, right now we can do either "source": "mirror://gnu/hello/hello-2.10.tar.gz", or "source": { "method": "url-fetch", "uri": "mirror://gnu/hello/hello-2.10.tar.gz", "sha256": { "base32": "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i" } } I’m open to simplifying this further. What do other people think? -- Ricardo GPG: BCA6 89B6 3655 3801 C3C6 2150 197A 5888 235F ACAC https://elephly.net ^ permalink raw reply [flat|nested] 12+ messages in thread
* [bug#28251] [PATCH 0/3] Add generic JSON importer 2017-09-28 11:23 ` Ricardo Wurmus @ 2017-09-28 19:58 ` Ludovic Courtès 0 siblings, 0 replies; 12+ messages in thread From: Ludovic Courtès @ 2017-09-28 19:58 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: 28251 Ricardo Wurmus <rekado@elephly.net> skribis: > Ludovic Courtès <ludo@gnu.org> writes: > >> I wonder if we could further simplify the “source” part, like allowing >> (maybe optionally) for: >> >> "source": "mirror://gnu…" >> >> and then letting the importer download the thing and fill in the hash. >> Likewise for a Git checkout: >> >> "git": { "commit": "cabba9e"; "url": "…" }; >> >> Thoughts? > > I have added support for a simple source string as in the first example. > I left the support for a direct translation of origin expressions > unchanged, because I’m not sure yet how to express this. > > So, right now we can do either > > "source": "mirror://gnu/hello/hello-2.10.tar.gz", > > or > > "source": { > "method": "url-fetch", > "uri": "mirror://gnu/hello/hello-2.10.tar.gz", > "sha256": { > "base32": "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i" > } > } > > I’m open to simplifying this further. What do other people think? That sounds good to me. One important consideration is to have a format that is future-proof, which is probably the case here. We could perhaps add a “format-version” field in the JSON input to be on the safe side, though it would defeat the whole simplification. (In other news, I’ve been considering the implementation of an “upstream” importer, where “guix import upstream URL” would return a package template as complete as possible.) Thanks, Ludo’. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-09-28 19:59 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-27 15:58 [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ricardo Wurmus 2017-08-27 16:00 ` [bug#28251] [PATCH 2/3] import: Add generic data to package converter Ricardo Wurmus 2017-09-04 13:04 ` Ludovic Courtès 2017-08-27 16:00 ` [bug#28251] [PATCH 3/3] import: Add JSON importer Ricardo Wurmus 2017-09-04 13:04 ` Ludovic Courtès 2017-09-01 15:55 ` [bug#28251] [PATCH 1/3] packages: Add package->code Ludovic Courtès 2017-09-28 11:19 ` bug#28251: " Ricardo Wurmus 2017-08-28 12:27 ` [bug#28251] [PATCH 0/3] Add generic JSON importer Ricardo Wurmus 2017-09-01 15:35 ` Ludovic Courtès 2017-09-28 11:23 ` Ricardo Wurmus 2017-09-28 19:58 ` Ludovic Courtès
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/guix.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.