From: Julien Lepiller <julien@lepiller.eu>
To: Xinglu Chen <public@yoctocell.xyz>, 53828@debbugs.gnu.org
Subject: [bug#53828] [PATCH] guix: opam: Allow importing local files.
Date: Mon, 07 Feb 2022 09:46:51 +0100 [thread overview]
Message-ID: <E7325AF8-C9EE-4A89-9AE5-390CBD49ABAA@lepiller.eu> (raw)
In-Reply-To: <87k0e713pg.fsf@yoctocell.xyz>
On February 7, 2022 9:27:39 AM GMT+01:00, Xinglu Chen <public@yoctocell.xyz> wrote:
>Julien schrieb am Sonntag der 06. Februar 2022 um 22:41 +01:
>
>> 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?
>
>Why just limit it to local files? What about accepting a tarball on the
>internet or any VCS repository? This could generally be useful for any
>importer.
That's a good idea, but I'm not sure how to recognize these cases.
>
>Also, since we already know the name of the package, maybe specifying
>the directory that contains the OCaml project would be enough?
Sure, that could be useful for your suggestion below to use the local directory as the source.
>
> guix import opam foo --type=local /path/to/directory
> guix import opam foo --type=tarball https://example.org/foo.tar.gz
> guix import opam foo --type=git https://git.example.org/foo
> …
>
>Or am I asking for too much? :-)
>
>> 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.
>
>It should be “import: opam: …”.
>
>> * 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)))
>
>I would use ‘and-let*’ instead of ‘let’, and drop the ‘if’ form.
That would return #f and make the ocher and-let* in opam->guix-package fail.
>
>The ability to import from a local file seems to mostly be useful when
>the package isn’t meant to be submitted to Guix, right? Wouldn’t it
>make more sense to make the source a ‘local-file’ object instead of just
>setting it to #f?
Excellent idea.
>
>> +(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
>
>s/packaged/package/
>
>> (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,
>
>The docstrings should also be updated.
next prev parent reply other threads:[~2022-02-07 9:50 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-06 21:41 [bug#53828] [PATCH] guix: opam: Allow importing local files Julien Lepiller
2022-02-06 21:58 ` Maxime Devos
2022-02-07 8:27 ` Xinglu Chen
2022-02-07 8:46 ` Julien Lepiller [this message]
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=E7325AF8-C9EE-4A89-9AE5-390CBD49ABAA@lepiller.eu \
--to=julien@lepiller.eu \
--cc=53828@debbugs.gnu.org \
--cc=public@yoctocell.xyz \
/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.