2015-06-16 10:50:06 +02:00
|
|
|
|
;;; GNU Guix --- Functional package management for GNU
|
|
|
|
|
;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
|
2021-01-06 18:22:21 +01:00
|
|
|
|
;;; Copyright © 2015, 2016, 2017, 2018, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
2018-06-08 12:49:29 +02:00
|
|
|
|
;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
|
2020-02-04 13:18:18 +01:00
|
|
|
|
;;; Copyright © 2020 Martin Becze <mjbecze@riseup.net>
|
2020-12-31 15:50:48 +01:00
|
|
|
|
;;; Copyright © 2020 Ricardo Wurmus <rekado@elephly.net>
|
2021-08-31 20:17:52 +02:00
|
|
|
|
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
|
2022-01-05 15:07:48 +01:00
|
|
|
|
;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
|
2021-01-19 16:47:19 +01:00
|
|
|
|
;;; Copyright © 2021 Simon Tournier <zimon.toutoune@gmail.com>
|
2015-06-16 10:50:06 +02:00
|
|
|
|
;;;
|
|
|
|
|
;;; 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 import elpa)
|
|
|
|
|
#:use-module (ice-9 match)
|
|
|
|
|
#:use-module (ice-9 rdelim)
|
2020-03-18 03:54:52 +01:00
|
|
|
|
#:use-module (ice-9 regex)
|
2015-10-21 12:12:59 +02:00
|
|
|
|
#:use-module (web uri)
|
2015-06-16 10:50:06 +02:00
|
|
|
|
#:use-module (srfi srfi-1)
|
|
|
|
|
#:use-module (srfi srfi-9)
|
|
|
|
|
#:use-module (srfi srfi-9 gnu)
|
|
|
|
|
#:use-module (srfi srfi-11)
|
|
|
|
|
#:use-module (srfi srfi-26)
|
2020-12-31 15:50:48 +01:00
|
|
|
|
#:use-module (srfi srfi-34)
|
|
|
|
|
#:use-module (srfi srfi-35)
|
2015-06-16 10:50:06 +02:00
|
|
|
|
#:use-module ((guix download) #:select (download-to-store))
|
|
|
|
|
#:use-module (guix import utils)
|
2015-10-21 12:12:59 +02:00
|
|
|
|
#:use-module (guix http-client)
|
2020-03-18 03:54:52 +01:00
|
|
|
|
#:use-module (guix git)
|
2022-01-05 15:07:48 +01:00
|
|
|
|
#:use-module (guix hash)
|
2020-03-18 03:54:52 +01:00
|
|
|
|
#:use-module ((guix serialization) #:select (write-file))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
#:use-module (guix store)
|
|
|
|
|
#:use-module (guix ui)
|
|
|
|
|
#:use-module (guix base32)
|
2015-10-21 12:25:06 +02:00
|
|
|
|
#:use-module (guix upstream)
|
|
|
|
|
#:use-module (guix packages)
|
2021-12-23 22:08:33 +01:00
|
|
|
|
#:use-module (guix memoization)
|
utils: Move combinators to (guix combinators).
* guix/utils.scm (compile-time-value, memoize, fold2)
(fold-tree, fold-tree-leaves): Move to...
* guix/combinators: ... here. New file.
* tests/utils.scm ("fold2, 1 list", "fold2, 2 lists")
(fold-tree tests): Move to...
* tests/combinators.scm: ... here. New file.
* Makefile.am (MODULES, SCM_TESTS): Add them.
* gnu/packages.scm, gnu/packages/bootstrap.scm,
gnu/services/herd.scm, guix/build-system/gnu.scm,
guix/build-system/python.scm, guix/derivations.scm,
guix/gnu-maintenance.scm, guix/import/elpa.scm,
guix/scripts/archive.scm, guix/scripts/build.scm,
guix/scripts/graph.scm, guix/scripts/lint.scm,
guix/scripts/size.scm, guix/scripts/substitute.scm,
guix/serialization.scm, guix/store.scm, guix/ui.scm: Adjust imports
accordingly.
2016-05-04 17:35:47 +02:00
|
|
|
|
#:use-module ((guix utils) #:select (call-with-temporary-output-file))
|
2015-10-21 12:25:06 +02:00
|
|
|
|
#:export (elpa->guix-package
|
2021-12-17 21:55:54 +01:00
|
|
|
|
guix-package->elpa-name
|
2018-06-08 12:49:29 +02:00
|
|
|
|
%elpa-updater
|
|
|
|
|
elpa-recursive-import))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
|
|
|
|
(define (elpa-dependencies->names deps)
|
|
|
|
|
"Convert DEPS, a list of symbol/version pairs à la ELPA, to a list of
|
|
|
|
|
package names as strings"
|
|
|
|
|
(match deps
|
|
|
|
|
(((names _ ...) ...)
|
|
|
|
|
(map symbol->string names))))
|
|
|
|
|
|
|
|
|
|
(define emacs-standard-library?
|
|
|
|
|
(let ((libs '("emacs" "cl-lib")))
|
|
|
|
|
(lambda (lib)
|
|
|
|
|
"Return true if LIB is part of Emacs itself. The check is not
|
|
|
|
|
exhaustive and only attempts to recognize a subset of packages which in the
|
|
|
|
|
past were distributed separately from Emacs."
|
|
|
|
|
(member lib libs))))
|
|
|
|
|
|
|
|
|
|
(define (filter-dependencies names)
|
|
|
|
|
"Remove the package names included with Emacs from the list of
|
|
|
|
|
NAMES (strings)."
|
2017-03-28 17:12:20 +02:00
|
|
|
|
(remove emacs-standard-library? names))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
|
|
|
|
(define (elpa-name->package-name name)
|
|
|
|
|
"Given the NAME of an Emacs package, return the corresponding Guix name."
|
|
|
|
|
(let ((package-name-prefix "emacs-"))
|
|
|
|
|
(if (string-prefix? package-name-prefix name)
|
|
|
|
|
(string-downcase name)
|
|
|
|
|
(string-append package-name-prefix (string-downcase name)))))
|
|
|
|
|
|
|
|
|
|
(define* (elpa-url #:optional (repo 'gnu))
|
2018-03-16 14:55:10 +01:00
|
|
|
|
"Retrieve the URL of REPO."
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(let ((elpa-archives
|
2018-03-16 14:53:09 +01:00
|
|
|
|
'((gnu . "https://elpa.gnu.org/packages")
|
2020-01-16 22:49:41 +01:00
|
|
|
|
(gnu/http . "http://elpa.gnu.org/packages") ;for testing
|
2021-08-31 20:17:52 +02:00
|
|
|
|
(nongnu . "https://elpa.nongnu.org/nongnu")
|
2018-03-16 14:53:09 +01:00
|
|
|
|
(melpa-stable . "https://stable.melpa.org/packages")
|
|
|
|
|
(melpa . "https://melpa.org/packages"))))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(assq-ref elpa-archives repo)))
|
|
|
|
|
|
|
|
|
|
(define* (elpa-fetch-archive #:optional (repo 'gnu))
|
2018-03-16 14:55:10 +01:00
|
|
|
|
"Retrieve the archive with the list of packages available from REPO."
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(let ((url (and=> (elpa-url repo)
|
|
|
|
|
(cut string-append <> "/archive-contents"))))
|
|
|
|
|
(if url
|
2015-10-21 12:12:59 +02:00
|
|
|
|
;; Use a relatively small TTL for the archive itself.
|
2017-10-27 23:43:19 +02:00
|
|
|
|
(let* ((port (http-fetch/cached (string->uri url)
|
|
|
|
|
#:ttl (* 6 3600)))
|
|
|
|
|
(data (read port)))
|
|
|
|
|
(close-port port)
|
|
|
|
|
data)
|
ui: Rename '_' to 'G_'.
This avoids collisions with '_' when the latter is used as a 'match'
pattern for instance. See
<https://lists.gnu.org/archive/html/guix-devel/2017-04/msg00464.html>.
* guix/ui.scm: Rename '_' to 'G_'.
* po/guix/Makevars (XGETTEXT_OPTIONS): Adjust accordingly.
* build-aux/compile-all.scm (warnings): Remove 'format'.
* gnu/packages.scm,
gnu/services.scm,
gnu/services/shepherd.scm,
gnu/system.scm,
gnu/system/shadow.scm,
guix/gnupg.scm,
guix/http-client.scm,
guix/import/cpan.scm,
guix/import/elpa.scm,
guix/import/pypi.scm,
guix/nar.scm,
guix/scripts.scm,
guix/scripts/archive.scm,
guix/scripts/authenticate.scm,
guix/scripts/build.scm,
guix/scripts/challenge.scm,
guix/scripts/container.scm,
guix/scripts/container/exec.scm,
guix/scripts/copy.scm,
guix/scripts/download.scm,
guix/scripts/edit.scm,
guix/scripts/environment.scm,
guix/scripts/gc.scm,
guix/scripts/graph.scm,
guix/scripts/hash.scm,
guix/scripts/import.scm,
guix/scripts/import/cpan.scm,
guix/scripts/import/cran.scm,
guix/scripts/import/crate.scm,
guix/scripts/import/elpa.scm,
guix/scripts/import/gem.scm,
guix/scripts/import/gnu.scm,
guix/scripts/import/hackage.scm,
guix/scripts/import/nix.scm,
guix/scripts/import/pypi.scm,
guix/scripts/import/stackage.scm,
guix/scripts/lint.scm,
guix/scripts/offload.scm,
guix/scripts/pack.scm,
guix/scripts/package.scm,
guix/scripts/perform-download.scm,
guix/scripts/publish.scm,
guix/scripts/pull.scm,
guix/scripts/refresh.scm,
guix/scripts/size.scm,
guix/scripts/substitute.scm,
guix/scripts/system.scm,
guix/ssh.scm,
guix/upstream.scm: Use 'G_' instead of '_'. Most of this change was
obtained by running: "sed -i -e's/(_ "/(G_ "/g' `find -name \*.scm`".
2017-05-03 15:57:02 +02:00
|
|
|
|
(leave (G_ "~A: currently not supported~%") repo))))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
2015-07-22 15:26:12 +02:00
|
|
|
|
(define* (call-with-downloaded-file url proc #:optional (error-thunk #f))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
"Fetch URL, store the content in a temporary file and call PROC with that
|
2015-07-22 15:26:12 +02:00
|
|
|
|
file. Returns the value returned by PROC. On error call ERROR-THUNK and
|
|
|
|
|
return its value or leave if it's false."
|
2016-12-14 02:31:12 +01:00
|
|
|
|
(catch #t
|
|
|
|
|
(lambda ()
|
|
|
|
|
(proc (http-fetch/cached (string->uri url))))
|
|
|
|
|
(lambda (key . args)
|
|
|
|
|
(if error-thunk
|
|
|
|
|
(error-thunk)
|
ui: Rename '_' to 'G_'.
This avoids collisions with '_' when the latter is used as a 'match'
pattern for instance. See
<https://lists.gnu.org/archive/html/guix-devel/2017-04/msg00464.html>.
* guix/ui.scm: Rename '_' to 'G_'.
* po/guix/Makevars (XGETTEXT_OPTIONS): Adjust accordingly.
* build-aux/compile-all.scm (warnings): Remove 'format'.
* gnu/packages.scm,
gnu/services.scm,
gnu/services/shepherd.scm,
gnu/system.scm,
gnu/system/shadow.scm,
guix/gnupg.scm,
guix/http-client.scm,
guix/import/cpan.scm,
guix/import/elpa.scm,
guix/import/pypi.scm,
guix/nar.scm,
guix/scripts.scm,
guix/scripts/archive.scm,
guix/scripts/authenticate.scm,
guix/scripts/build.scm,
guix/scripts/challenge.scm,
guix/scripts/container.scm,
guix/scripts/container/exec.scm,
guix/scripts/copy.scm,
guix/scripts/download.scm,
guix/scripts/edit.scm,
guix/scripts/environment.scm,
guix/scripts/gc.scm,
guix/scripts/graph.scm,
guix/scripts/hash.scm,
guix/scripts/import.scm,
guix/scripts/import/cpan.scm,
guix/scripts/import/cran.scm,
guix/scripts/import/crate.scm,
guix/scripts/import/elpa.scm,
guix/scripts/import/gem.scm,
guix/scripts/import/gnu.scm,
guix/scripts/import/hackage.scm,
guix/scripts/import/nix.scm,
guix/scripts/import/pypi.scm,
guix/scripts/import/stackage.scm,
guix/scripts/lint.scm,
guix/scripts/offload.scm,
guix/scripts/pack.scm,
guix/scripts/package.scm,
guix/scripts/perform-download.scm,
guix/scripts/publish.scm,
guix/scripts/pull.scm,
guix/scripts/refresh.scm,
guix/scripts/size.scm,
guix/scripts/substitute.scm,
guix/scripts/system.scm,
guix/ssh.scm,
guix/upstream.scm: Use 'G_' instead of '_'. Most of this change was
obtained by running: "sed -i -e's/(_ "/(G_ "/g' `find -name \*.scm`".
2017-05-03 15:57:02 +02:00
|
|
|
|
(leave (G_ "~A: download failed~%") url)))))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
|
|
|
|
(define (is-elpa-package? name elpa-pkg-spec)
|
|
|
|
|
"Return true if the string NAME corresponds to the name of the package
|
|
|
|
|
defined by ELPA-PKG-SPEC, a package specification as in an archive
|
|
|
|
|
'archive-contents' file."
|
|
|
|
|
(eq? (first elpa-pkg-spec) (string->symbol name)))
|
|
|
|
|
|
|
|
|
|
(define* (elpa-package-info name #:optional (repo 'gnu))
|
|
|
|
|
"Extract the information about the package NAME from the package archieve of
|
|
|
|
|
REPO."
|
|
|
|
|
(let* ((archive (elpa-fetch-archive repo))
|
|
|
|
|
(pkgs (match archive ((version pkg-spec ...) pkg-spec)))
|
|
|
|
|
(info (filter (cut is-elpa-package? name <>) pkgs)))
|
|
|
|
|
(if (pair? info) (first info) #f)))
|
|
|
|
|
|
|
|
|
|
;; Object to store information about an ELPA package.
|
|
|
|
|
(define-record-type <elpa-package>
|
|
|
|
|
(make-elpa-package name version inputs synopsis kind home-page description
|
|
|
|
|
source-url)
|
|
|
|
|
elpa-package?
|
|
|
|
|
(name elpa-package-name)
|
|
|
|
|
(version elpa-package-version)
|
|
|
|
|
(inputs elpa-package-inputs)
|
|
|
|
|
(synopsis elpa-package-synopsis)
|
|
|
|
|
(kind elpa-package-kind)
|
|
|
|
|
(home-page elpa-package-home-page)
|
|
|
|
|
(description elpa-package-description)
|
|
|
|
|
(source-url elpa-package-source-url))
|
|
|
|
|
|
|
|
|
|
(set-record-type-printer! <elpa-package>
|
|
|
|
|
(lambda (package port)
|
2016-01-24 17:42:39 +01:00
|
|
|
|
(format port "#<elpa-package ~a@~a>"
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(elpa-package-name package)
|
|
|
|
|
(elpa-package-version package))))
|
|
|
|
|
|
|
|
|
|
(define (elpa-version->string elpa-version)
|
|
|
|
|
"Convert the package version as used in Emacs package files into a string."
|
|
|
|
|
(if (pair? elpa-version)
|
|
|
|
|
(let-values (((ms rest) (match elpa-version
|
|
|
|
|
((ms . rest)
|
|
|
|
|
(values ms rest)))))
|
|
|
|
|
(fold (lambda (n s) (string-append s "." (number->string n)))
|
|
|
|
|
(number->string ms) rest))
|
|
|
|
|
#f))
|
|
|
|
|
|
|
|
|
|
(define (package-home-page alist)
|
|
|
|
|
"Extract the package home-page from ALIST."
|
|
|
|
|
(or (assq-ref alist ':url) "unspecified"))
|
|
|
|
|
|
|
|
|
|
(define (ensure-list alist)
|
|
|
|
|
"If ALIST is the symbol 'nil return the empty list. Otherwise, return ALIST."
|
|
|
|
|
(if (eq? alist 'nil)
|
|
|
|
|
'()
|
|
|
|
|
alist))
|
|
|
|
|
|
|
|
|
|
(define (package-source-url kind name version repo)
|
|
|
|
|
"Return the source URL of the package described the the strings NAME and
|
|
|
|
|
VERSION at REPO. KIND is either the symbol 'single or 'tar."
|
|
|
|
|
(case kind
|
|
|
|
|
((single) (full-url repo name ".el" version))
|
|
|
|
|
((tar) (full-url repo name ".tar" version))
|
|
|
|
|
(else
|
|
|
|
|
#f)))
|
|
|
|
|
|
|
|
|
|
(define* (full-url repo name suffix #:optional (version #f))
|
|
|
|
|
"Return the full URL of the package NAME at REPO and the SUFFIX. Maybe
|
|
|
|
|
include VERSION."
|
|
|
|
|
(if version
|
|
|
|
|
(string-append (elpa-url repo) "/" name "-" version suffix)
|
|
|
|
|
(string-append (elpa-url repo) "/" name suffix)))
|
|
|
|
|
|
|
|
|
|
(define (fetch-package-description kind name repo)
|
|
|
|
|
"Fetch the description of package NAME of type KIND from REPO."
|
2015-07-22 15:26:12 +02:00
|
|
|
|
(let ((url (full-url repo name "-readme.txt"))
|
|
|
|
|
(error-thunk (lambda () "No description available.")))
|
|
|
|
|
(call-with-downloaded-file url read-string error-thunk)))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
|
|
|
|
(define* (fetch-elpa-package name #:optional (repo 'gnu))
|
|
|
|
|
"Fetch package NAME from REPO."
|
|
|
|
|
(let ((pkg (elpa-package-info name repo)))
|
|
|
|
|
(match pkg
|
|
|
|
|
((name version reqs synopsis kind . rest)
|
|
|
|
|
(let* ((name (symbol->string name))
|
|
|
|
|
(ver (elpa-version->string version))
|
|
|
|
|
(url (package-source-url kind name ver repo)))
|
|
|
|
|
(make-elpa-package name ver
|
|
|
|
|
(ensure-list reqs) synopsis kind
|
2018-06-30 09:51:45 +02:00
|
|
|
|
(package-home-page (match rest
|
|
|
|
|
(() #f)
|
|
|
|
|
((one) one)))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(fetch-package-description kind name repo)
|
|
|
|
|
url)))
|
|
|
|
|
(_ #f))))
|
|
|
|
|
|
2020-03-18 03:54:52 +01:00
|
|
|
|
(define* (download-git-repository url ref)
|
|
|
|
|
"Fetch the given REF from the Git repository at URL."
|
|
|
|
|
(with-store store
|
|
|
|
|
(latest-repository-commit store url #:ref ref)))
|
|
|
|
|
|
|
|
|
|
(define (package-name->melpa-recipe package-name)
|
|
|
|
|
"Fetch the MELPA recipe for PACKAGE-NAME, represented as an alist from
|
|
|
|
|
keywords to values."
|
|
|
|
|
(define recipe-url
|
|
|
|
|
(string-append "https://raw.githubusercontent.com/melpa/melpa/master/recipes/"
|
|
|
|
|
package-name))
|
|
|
|
|
|
|
|
|
|
(define (data->recipe data)
|
|
|
|
|
(match data
|
|
|
|
|
(() '())
|
|
|
|
|
((key value . tail)
|
|
|
|
|
(cons (cons key value) (data->recipe tail)))))
|
|
|
|
|
|
|
|
|
|
(let* ((port (http-fetch/cached (string->uri recipe-url)
|
|
|
|
|
#:ttl (* 6 3600)))
|
|
|
|
|
(data (read port)))
|
|
|
|
|
(close-port port)
|
|
|
|
|
(data->recipe (cons ':name data))))
|
|
|
|
|
|
|
|
|
|
(define (git-repository->origin recipe url)
|
|
|
|
|
"Fetch origin details from the Git repository at URL for the provided MELPA
|
|
|
|
|
RECIPE."
|
|
|
|
|
(define ref
|
|
|
|
|
(cond
|
|
|
|
|
((assoc-ref recipe #:branch)
|
|
|
|
|
=> (lambda (branch) (cons 'branch branch)))
|
|
|
|
|
((assoc-ref recipe #:commit)
|
|
|
|
|
=> (lambda (commit) (cons 'commit commit)))
|
|
|
|
|
(else
|
2021-09-06 12:57:04 +02:00
|
|
|
|
'())))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
|
|
|
|
|
(let-values (((directory commit) (download-git-repository url ref)))
|
|
|
|
|
`(origin
|
|
|
|
|
(method git-fetch)
|
|
|
|
|
(uri (git-reference
|
|
|
|
|
(url ,url)
|
|
|
|
|
(commit ,commit)))
|
|
|
|
|
(sha256
|
|
|
|
|
(base32
|
|
|
|
|
,(bytevector->nix-base32-string
|
2022-01-05 15:07:48 +01:00
|
|
|
|
(file-hash* directory #:recursive? #true)))))))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
|
|
|
|
|
(define* (melpa-recipe->origin recipe)
|
|
|
|
|
"Fetch origin details from the MELPA recipe and associated repository for
|
|
|
|
|
the package named PACKAGE-NAME."
|
|
|
|
|
(define (github-repo->url repo)
|
|
|
|
|
(string-append "https://github.com/" repo ".git"))
|
|
|
|
|
(define (gitlab-repo->url repo)
|
|
|
|
|
(string-append "https://gitlab.com/" repo ".git"))
|
|
|
|
|
|
|
|
|
|
(match (assq-ref recipe ':fetcher)
|
|
|
|
|
('github (git-repository->origin recipe (github-repo->url (assq-ref recipe ':repo))))
|
|
|
|
|
('gitlab (git-repository->origin recipe (gitlab-repo->url (assq-ref recipe ':repo))))
|
|
|
|
|
('git (git-repository->origin recipe (assq-ref recipe ':url)))
|
|
|
|
|
(#f #f) ; if we're not using melpa then this stops us printing a warning
|
|
|
|
|
(_ (warning (G_ "Unsupported MELPA fetcher: ~a, falling back to unstable MELPA source.~%")
|
|
|
|
|
(assq-ref recipe ':fetcher))
|
|
|
|
|
#f)))
|
|
|
|
|
|
|
|
|
|
(define default-files-spec
|
|
|
|
|
;; This contains more than just the things contained in %default-include and
|
|
|
|
|
;; %default-exclude, presumably because this includes source files (*.in,
|
|
|
|
|
;; *.texi, etc.) which have already been processed for releases.
|
|
|
|
|
;;
|
|
|
|
|
;; Taken from:
|
|
|
|
|
;; https://github.com/melpa/melpa/blob/e8dc709d0ab2b4a68c59315f42858bcb86095f11/package-build/package-build.el#L580-L585
|
|
|
|
|
'("*.el" "*.el.in" "dir"
|
|
|
|
|
"*.info" "*.texi" "*.texinfo"
|
|
|
|
|
"doc/dir" "doc/*.info" "doc/*.texi" "doc/*.texinfo"
|
|
|
|
|
(:exclude ".dir-locals.el" "test.el" "tests.el" "*-test.el" "*-tests.el")))
|
|
|
|
|
|
|
|
|
|
(define* (melpa-recipe->maybe-arguments melpa-recipe)
|
|
|
|
|
"Extract arguments for the build system from MELPA-RECIPE."
|
|
|
|
|
(define (glob->regexp glob)
|
|
|
|
|
(string-append
|
|
|
|
|
"^"
|
|
|
|
|
(regexp-substitute/global #f "\\*\\*?" glob
|
|
|
|
|
'pre
|
|
|
|
|
(lambda (m)
|
|
|
|
|
(if (string= (match:substring m 0) "**")
|
|
|
|
|
".*"
|
|
|
|
|
"[^/]+"))
|
|
|
|
|
'post)
|
|
|
|
|
"$"))
|
|
|
|
|
|
|
|
|
|
(let ((files (assq-ref melpa-recipe ':files)))
|
|
|
|
|
(if files
|
|
|
|
|
(let* ((with-default (apply append (map (lambda (entry)
|
|
|
|
|
(if (eq? ':defaults entry)
|
|
|
|
|
default-files-spec
|
|
|
|
|
(list entry)))
|
|
|
|
|
files)))
|
|
|
|
|
(inclusions (remove pair? with-default))
|
|
|
|
|
(exclusions (apply append (map (match-lambda
|
|
|
|
|
((':exclude . values)
|
|
|
|
|
values)
|
|
|
|
|
(_ '()))
|
|
|
|
|
with-default))))
|
|
|
|
|
`((arguments '(#:include ',(map glob->regexp inclusions)
|
|
|
|
|
#:exclude ',(map glob->regexp exclusions)))))
|
|
|
|
|
'())))
|
|
|
|
|
|
|
|
|
|
(define* (elpa-package->sexp pkg #:optional license repo)
|
2015-06-16 10:50:06 +02:00
|
|
|
|
"Return the `package' S-expression for the Emacs package PKG, a record of
|
|
|
|
|
type '<elpa-package>'."
|
|
|
|
|
|
2020-03-18 03:54:52 +01:00
|
|
|
|
(define melpa-recipe
|
2021-11-06 16:42:32 +01:00
|
|
|
|
;; XXX: Call 'identity' to work around a Guile 3.0.[5-7] compiler bug:
|
|
|
|
|
;; <https://bugs.gnu.org/48368>.
|
|
|
|
|
(and (eq? (identity repo) 'melpa)
|
|
|
|
|
(package-name->melpa-recipe (elpa-package-name pkg))))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(define name (elpa-package-name pkg))
|
|
|
|
|
|
|
|
|
|
(define version (elpa-package-version pkg))
|
|
|
|
|
|
|
|
|
|
(define source-url (elpa-package-source-url pkg))
|
|
|
|
|
|
2018-06-08 12:49:29 +02:00
|
|
|
|
(define dependencies-names
|
|
|
|
|
(filter-dependencies (elpa-dependencies->names
|
|
|
|
|
(elpa-package-inputs pkg))))
|
|
|
|
|
|
2015-06-16 10:50:06 +02:00
|
|
|
|
(define dependencies
|
2021-06-30 16:09:00 +02:00
|
|
|
|
(map (compose string->symbol elpa-name->package-name)
|
2018-06-08 12:49:29 +02:00
|
|
|
|
dependencies-names))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
|
|
|
|
(define (maybe-inputs input-type inputs)
|
|
|
|
|
(match inputs
|
|
|
|
|
(()
|
|
|
|
|
'())
|
|
|
|
|
((inputs ...)
|
2021-06-30 16:09:00 +02:00
|
|
|
|
(list (list input-type `(list ,@inputs))))))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
2020-03-18 03:54:52 +01:00
|
|
|
|
(define melpa-source
|
|
|
|
|
(melpa-recipe->origin melpa-recipe))
|
|
|
|
|
|
|
|
|
|
(values
|
|
|
|
|
`(package
|
|
|
|
|
(name ,(elpa-name->package-name name))
|
|
|
|
|
(version ,version)
|
|
|
|
|
(source ,(or melpa-source
|
|
|
|
|
(let ((tarball (with-store store
|
|
|
|
|
(download-to-store store source-url))))
|
|
|
|
|
`(origin
|
|
|
|
|
(method url-fetch)
|
|
|
|
|
(uri (string-append ,@(factorize-uri source-url version)))
|
|
|
|
|
(sha256
|
|
|
|
|
(base32
|
|
|
|
|
,(if tarball
|
2022-01-05 15:07:48 +01:00
|
|
|
|
(bytevector->nix-base32-string
|
|
|
|
|
(file-hash* tarball #:recursive? #false))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
"failed to download package")))))))
|
|
|
|
|
(build-system emacs-build-system)
|
|
|
|
|
,@(maybe-inputs 'propagated-inputs dependencies)
|
|
|
|
|
,@(if melpa-source
|
|
|
|
|
(melpa-recipe->maybe-arguments melpa-recipe)
|
|
|
|
|
'())
|
|
|
|
|
(home-page ,(elpa-package-home-page pkg))
|
|
|
|
|
(synopsis ,(elpa-package-synopsis pkg))
|
2021-12-17 14:10:40 +01:00
|
|
|
|
(description ,(beautify-description (elpa-package-description pkg)))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
(license ,license))
|
|
|
|
|
dependencies-names))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
2020-02-04 13:18:18 +01:00
|
|
|
|
(define* (elpa->guix-package name #:key (repo 'gnu) version)
|
2015-06-16 10:50:06 +02:00
|
|
|
|
"Fetch the package NAME from REPO and produce a Guix package S-expression."
|
2018-03-18 22:26:34 +01:00
|
|
|
|
(match (fetch-elpa-package name repo)
|
2020-12-31 15:50:48 +01:00
|
|
|
|
(#false
|
2021-01-19 16:47:19 +01:00
|
|
|
|
(values #f '()))
|
2018-03-18 22:26:34 +01:00
|
|
|
|
(package
|
|
|
|
|
;; ELPA is known to contain only GPLv3+ code. Other repos may contain
|
|
|
|
|
;; code under other license but there's no license metadata.
|
2020-01-16 22:49:41 +01:00
|
|
|
|
(let ((license (and (memq repo '(gnu gnu/http)) 'license:gpl3+)))
|
2020-03-18 03:54:52 +01:00
|
|
|
|
(elpa-package->sexp package license repo)))))
|
2015-06-16 10:50:06 +02:00
|
|
|
|
|
2015-10-21 12:25:06 +02:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Updates.
|
|
|
|
|
;;;
|
|
|
|
|
|
2021-12-17 21:55:54 +01:00
|
|
|
|
(define (guix-package->elpa-name package)
|
|
|
|
|
"Given a Guix package, PACKAGE, return the upstream name on ELPA."
|
|
|
|
|
(or (and=> (package-properties package)
|
|
|
|
|
(cut assq-ref <> 'upstream-name))
|
|
|
|
|
(if (string-prefix? "emacs-" (package-name package))
|
|
|
|
|
(string-drop (package-name package) 6)
|
|
|
|
|
(package-name package))))
|
|
|
|
|
|
2015-10-21 12:25:06 +02:00
|
|
|
|
(define (latest-release package)
|
2016-04-14 21:40:20 +02:00
|
|
|
|
"Return an <upstream-release> for the latest release of PACKAGE."
|
2021-12-17 21:55:54 +01:00
|
|
|
|
(define name (guix-package->elpa-name package))
|
2021-12-23 22:08:33 +01:00
|
|
|
|
(define repo (elpa-repository package))
|
2021-01-06 18:22:21 +01:00
|
|
|
|
|
|
|
|
|
(match (elpa-package-info name repo)
|
|
|
|
|
(#f
|
|
|
|
|
;; No info, perhaps because PACKAGE is not truly an ELPA package.
|
|
|
|
|
#f)
|
|
|
|
|
(info
|
|
|
|
|
(let* ((version (match info
|
|
|
|
|
((name raw-version . _)
|
|
|
|
|
(elpa-version->string raw-version))))
|
|
|
|
|
(url (match info
|
|
|
|
|
((_ raw-version reqs synopsis kind . rest)
|
|
|
|
|
(package-source-url kind name version repo)))))
|
|
|
|
|
(upstream-source
|
|
|
|
|
(package (package-name package))
|
|
|
|
|
(version version)
|
|
|
|
|
(urls (list url))
|
|
|
|
|
(signature-urls (list (string-append url ".sig"))))))))
|
2015-10-21 12:25:06 +02:00
|
|
|
|
|
2021-12-23 22:08:33 +01:00
|
|
|
|
(define elpa-repository
|
|
|
|
|
(memoize
|
|
|
|
|
(url-predicate (lambda (url)
|
|
|
|
|
(let ((uri (string->uri url)))
|
|
|
|
|
(and uri
|
|
|
|
|
(cond
|
|
|
|
|
((string=? (uri-host uri) "elpa.gnu.org")
|
|
|
|
|
'gnu)
|
|
|
|
|
((string=? (uri-host uri) "elpa.nongnu.org")
|
|
|
|
|
'nongnu)
|
|
|
|
|
(else #f))))))))
|
|
|
|
|
|
|
|
|
|
(define (package-from-elpa-repository? package)
|
|
|
|
|
(member (elpa-repository package) '(gnu nongnu)))
|
2015-10-21 12:25:06 +02:00
|
|
|
|
|
|
|
|
|
(define %elpa-updater
|
|
|
|
|
;; The ELPA updater. We restrict it to packages hosted on elpa.gnu.org
|
|
|
|
|
;; because for other repositories, we typically grab the source elsewhere.
|
2015-10-26 19:24:53 +01:00
|
|
|
|
(upstream-updater
|
|
|
|
|
(name 'elpa)
|
|
|
|
|
(description "Updater for ELPA packages")
|
2021-12-23 22:08:33 +01:00
|
|
|
|
(pred package-from-elpa-repository?)
|
2015-10-26 19:24:53 +01:00
|
|
|
|
(latest latest-release)))
|
2015-10-21 12:25:06 +02:00
|
|
|
|
|
2018-06-08 12:49:29 +02:00
|
|
|
|
(define elpa-guix-name (cut guix-name "emacs-" <>))
|
|
|
|
|
|
|
|
|
|
(define* (elpa-recursive-import package-name #:optional (repo 'gnu))
|
2020-02-04 13:18:18 +01:00
|
|
|
|
(recursive-import package-name
|
|
|
|
|
#:repo repo
|
2018-06-08 12:49:29 +02:00
|
|
|
|
#:repo->guix-package elpa->guix-package
|
|
|
|
|
#:guix-name elpa-guix-name))
|
|
|
|
|
|
2015-06-16 10:50:06 +02:00
|
|
|
|
;;; elpa.scm ends here
|