From: Julien Lepiller <julien@lepiller.eu>
To: 53828@debbugs.gnu.org
Subject: [bug#53828] [PATCH] guix: opam: Allow importing local files.
Date: Sun, 6 Feb 2022 22:41:30 +0100 [thread overview]
Message-ID: <20220206224130.2220aae9@tachikoma.lepiller.eu> (raw)
[-- Attachment #1: Type: text/plain, Size: 473 bytes --]
Hi Guix!
This patch lets you import opam packages from a local file. This is a
feature that was requested a few times, and there it is :)
Now, if you have an OCaml package sources that provides an opam file
(usually called opam, or with the .opam extension), you can import the
package, recursively or not with something like:
guix import opam foo -f foo.opam -r
instead of fetching foo from the repositories, it will fetch the data
directly from the given file. WDYT?
[-- Attachment #2: 0001-guix-opam-Allow-importing-local-files.patch --]
[-- Type: text/x-patch, Size: 11718 bytes --]
From b027391357eef4d6fa1bb8741528cf9650aef568 Mon Sep 17 00:00:00 2001
Message-Id: <b027391357eef4d6fa1bb8741528cf9650aef568.1644183523.git.julien@lepiller.eu>
From: Julien Lepiller <julien@lepiller.eu>
Date: Sun, 6 Feb 2022 22:35:14 +0100
Subject: [PATCH] guix: opam: Allow importing local files.
* guix/scripts/import/opam.scm (guix-import-opam): Support `--file` flag.
* guix/import/utils.scm (recursive-import): Add optional file argument.
Pass it to the first iteration when available.
* guix/import/opam.scm (opam-fetch): Fetch from file when available.
(opam->guix-source): Factorize source out of opam->guix-package.
(opam->guix-package): Add file argument. Ensure it does not fail when
name, version and url are not available.
---
guix/import/opam.scm | 101 +++++++++++++++++++----------------
guix/import/utils.scm | 17 +++---
guix/scripts/import/opam.scm | 11 +++-
3 files changed, 75 insertions(+), 54 deletions(-)
diff --git a/guix/import/opam.scm b/guix/import/opam.scm
index a6f6fe8c9f..05f79110f8 100644
--- a/guix/import/opam.scm
+++ b/guix/import/opam.scm
@@ -310,8 +310,11 @@ (define (dependency-list->inputs lst)
(map string->symbol
(ocaml-names->guix-names lst)))
-(define* (opam-fetch name #:optional (repositories-specs '("opam")))
- (or (fold (lambda (repository others)
+(define* (opam-fetch name #:optional (repositories-specs '("opam")) (file #f))
+ (or (and file (let ((metadata (get-metadata file)))
+ `(("metadata" . ,metadata)
+ ("version" . #f))))
+ (fold (lambda (repository others)
(match (find-latest-version name repository)
((_ version file) `(("metadata" ,@(get-metadata file))
("version" . ,version)))
@@ -320,17 +323,29 @@ (define* (opam-fetch name #:optional (repositories-specs '("opam")))
(filter-map get-opam-repository repositories-specs))
(warning (G_ "opam: package '~a' not found~%") name)))
-(define* (opam->guix-package name #:key (repo 'opam) version)
+(define (opam->guix-source url-dict)
+ (let ((source-url (and url-dict
+ (or (metadata-ref url-dict "src")
+ (metadata-ref url-dict "archive")))))
+ (if source-url
+ (call-with-temporary-output-file
+ (lambda (temp port)
+ (and (url-fetch source-url temp)
+ `(origin
+ (method url-fetch)
+ (uri ,source-url)
+ (sha256 (base32 ,(guix-hash-url temp)))))))
+ 'no-source-information)))
+
+(define* (opam->guix-package name #:key (repo '("opam")) (file #f) version)
"Import OPAM package NAME from REPOSITORY (a directory name) or, if
-REPOSITORY is #f, from the official OPAM repository. Return a 'package' sexp
+REPOSITORY is #f, from the official OPAM repository. When FILE is defined,
+import the packaged defined in the opam FILE instead. Return a 'package' sexp
or #f on failure."
(and-let* ((with-opam (if (member "opam" repo) repo (cons "opam" repo)))
- (opam-file (opam-fetch name with-opam))
- (version (assoc-ref opam-file "version"))
+ (opam-file (opam-fetch name with-opam file))
(opam-content (assoc-ref opam-file "metadata"))
- (url-dict (metadata-ref opam-content "url"))
- (source-url (or (metadata-ref url-dict "src")
- (metadata-ref url-dict "archive")))
+ (source (opam->guix-source (metadata-ref opam-content "url")))
(requirements (metadata-ref opam-content "depends"))
(names (dependency-list->names requirements))
(dependencies (filter-dependencies names))
@@ -344,47 +359,41 @@ (define* (opam->guix-package name #:key (repo 'opam) version)
(not (member name '("dune" "jbuilder"))))
native-dependencies))))
(let ((use-dune? (member "dune" names)))
- (call-with-temporary-output-file
- (lambda (temp port)
- (and (url-fetch source-url temp)
- (values
- `(package
- (name ,(ocaml-name->guix-name name))
- (version ,version)
- (source
- (origin
- (method url-fetch)
- (uri ,source-url)
- (sha256 (base32 ,(guix-hash-url temp)))))
- (build-system ,(if use-dune?
- 'dune-build-system
- 'ocaml-build-system))
- ,@(if (null? inputs)
- '()
- `((propagated-inputs (list ,@inputs))))
- ,@(if (null? native-inputs)
- '()
- `((native-inputs (list ,@native-inputs))))
- ,@(if (equal? name (guix-name->opam-name (ocaml-name->guix-name name)))
- '()
- `((properties
- ,(list 'quasiquote `((upstream-name . ,name))))))
- (home-page ,(metadata-ref opam-content "homepage"))
- (synopsis ,(metadata-ref opam-content "synopsis"))
- (description ,(beautify-description
- (metadata-ref opam-content "description")))
- (license ,(spdx-string->license
- (metadata-ref opam-content "license"))))
- (filter
- (lambda (name)
- (not (member name '("dune" "jbuilder"))))
- dependencies))))))))
+ (values
+ `(package
+ (name ,(and name (ocaml-name->guix-name name)))
+ (version ,(assoc-ref opam-file "version"))
+ (source ,source)
+ (build-system ,(if use-dune?
+ 'dune-build-system
+ 'ocaml-build-system))
+ ,@(if (null? inputs)
+ '()
+ `((propagated-inputs (list ,@inputs))))
+ ,@(if (null? native-inputs)
+ '()
+ `((native-inputs (list ,@native-inputs))))
+ ,@(if (and name (equal? name (guix-name->opam-name (ocaml-name->guix-name name))))
+ '()
+ `((properties
+ ,(list 'quasiquote `((upstream-name . ,name))))))
+ (home-page ,(metadata-ref opam-content "homepage"))
+ (synopsis ,(metadata-ref opam-content "synopsis"))
+ (description ,(beautify-description
+ (metadata-ref opam-content "description")))
+ (license ,(spdx-string->license
+ (metadata-ref opam-content "license"))))
+ (filter
+ (lambda (name)
+ (not (member name '("dune" "jbuilder"))))
+ dependencies)))))
-(define* (opam-recursive-import package-name #:key repo)
+(define* (opam-recursive-import package-name #:key repo file)
(recursive-import package-name
#:repo->guix-package opam->guix-package
#:guix-name ocaml-name->guix-name
- #:repo repo))
+ #:repo repo
+ #:file file))
(define (guix-name->opam-name name)
(if (string-prefix? "ocaml-" name)
diff --git a/guix/import/utils.scm b/guix/import/utils.scm
index 1c3cfa3e0b..ab35b8a4fc 100644
--- a/guix/import/utils.scm
+++ b/guix/import/utils.scm
@@ -470,7 +470,7 @@ (define (topological-sort nodes
(set-insert (node-name head) visited))))))))
(define* (recursive-import package-name
- #:key repo->guix-package guix-name version repo
+ #:key repo->guix-package guix-name version repo file
#:allow-other-keys)
"Return a list of package expressions for PACKAGE-NAME and all its
dependencies, sorted in topological order. For each package,
@@ -488,10 +488,15 @@ (define* (recursive-import package-name
(define (exists? name version)
(not (null? (find-packages-by-name (guix-name name) version))))
- (define (lookup-node name version)
- (let* ((package dependencies (repo->guix-package name
- #:version version
- #:repo repo))
+ (define* (lookup-node name version #:optional file)
+ (let* ((package dependencies (if file
+ (repo->guix-package name
+ #:version version
+ #:repo repo
+ #:file file)
+ (repo->guix-package name
+ #:version version
+ #:repo repo)))
(normalized-deps (map (match-lambda
((name version) (list name version))
(name (list name #f))) dependencies)))
@@ -499,7 +504,7 @@ (define* (recursive-import package-name
(filter-map
node-package
- (topological-sort (list (lookup-node package-name version))
+ (topological-sort (list (lookup-node package-name version file))
(lambda (node)
(map (lambda (name-version)
(apply lookup-node name-version))
diff --git a/guix/scripts/import/opam.scm b/guix/scripts/import/opam.scm
index 834ac34cb0..b58c6eab3d 100644
--- a/guix/scripts/import/opam.scm
+++ b/guix/scripts/import/opam.scm
@@ -50,6 +50,8 @@ (define (show-help)
--repo import packages from this opam repository (name, URL or local path)
can be used more than once"))
(display (G_ "
+ -f, --file import the package defined from a .opam file"))
+ (display (G_ "
-V, --version display version information and exit"))
(newline)
(show-bug-report-information))
@@ -66,6 +68,9 @@ (define %options
(option '(#f "repo") #t #f
(lambda (opt name arg result)
(alist-cons 'repo arg result)))
+ (option '(#\f "file") #t #f
+ (lambda (opt name arg result)
+ (alist-cons 'file arg result)))
(option '(#\r "recursive") #f #f
(lambda (opt name arg result)
(alist-cons 'recursive #t result)))
@@ -100,9 +105,11 @@ (define (guix-import-opam . args)
`(define-public ,(string->symbol name)
,pkg))
(_ #f))
- (opam-recursive-import package-name #:repo repo))
+ (opam-recursive-import package-name #:repo repo
+ #:file (assoc-ref opts 'file)))
;; Single import
- (let ((sexp (opam->guix-package package-name #:repo repo)))
+ (let ((sexp (opam->guix-package package-name #:repo repo
+ #:file (assoc-ref opts 'file))))
(unless sexp
(leave (G_ "failed to download meta-data for package '~a'~%")
package-name))
--
2.34.0
next reply other threads:[~2022-02-06 21:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-06 21:41 Julien Lepiller [this message]
2022-02-06 21:58 ` [bug#53828] [PATCH] guix: opam: Allow importing local files Maxime Devos
2022-02-07 8:27 ` Xinglu Chen
2022-02-07 8:46 ` Julien Lepiller
2022-02-09 13:34 ` Xinglu Chen
2022-06-12 6:31 ` [bug#53828] [PATCH v2] import: " Julien Lepiller
2022-06-12 6:37 ` Julien Lepiller
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220206224130.2220aae9@tachikoma.lepiller.eu \
--to=julien@lepiller.eu \
--cc=53828@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 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.