From ed2829549b8d7ca1cb34737f73ba9b6ea129d499 Mon Sep 17 00:00:00 2001 From: nee Date: Mon, 11 Dec 2017 00:49:14 +0100 Subject: [PATCH] WIP unfinished elixir and erlang buildsystem and hex importer --- Makefile.am | 2 + gnu/packages/erlang.scm | 58 +++++++++++++++++++ guix/download.scm | 41 ++++++++++++++ guix/import/hex.scm | 133 ++++++++++++++++++++++++++++++++++++++++++++ guix/scripts/import.scm | 2 +- guix/scripts/import/hex.scm | 7 +++ 6 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 guix/import/hex.scm create mode 100644 guix/scripts/import/hex.scm diff --git a/Makefile.am b/Makefile.am index ddbf7a798..a07a5dc6e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -160,6 +160,7 @@ MODULES = \ guix/import/cabal.scm \ guix/import/cran.scm \ guix/import/hackage.scm \ + guix/import/hex.scm \ guix/import/elpa.scm \ guix/import/texlive.scm \ guix/scripts.scm \ @@ -184,6 +185,7 @@ MODULES = \ guix/scripts/import/gnu.scm \ guix/scripts/import/nix.scm \ guix/scripts/import/hackage.scm \ + guix/scripts/import/hex.scm \ guix/scripts/import/elpa.scm \ guix/scripts/import/texlive.scm \ guix/scripts/environment.scm \ diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm index 770ed715b..bccb835ea 100644 --- a/gnu/packages/erlang.scm +++ b/gnu/packages/erlang.scm @@ -19,6 +19,7 @@ ;;; along with GNU Guix. If not, see . (define-module (gnu packages erlang) + #:use-module (ice-9 match) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix build-system gnu) #:use-module (guix download) @@ -176,3 +177,60 @@ built-in support for concurrency, distribution and fault tolerance.") ;; have other licenses. See 'system/COPYRIGHT' in the source distribution. (license (list license:asl2.0 license:bsd-2 license:bsd-3 license:expat license:lgpl2.0+ license:tcl/tk license:zlib)))) + +;;; TODO patch rebar3 to not check for the registry and just accept whater it finds in _build +(define-public rebar3 + (let ((deps '(("erlware_commons" "1.0.4" "18j8bin8q9dcbwfgkyc66231wkyji6ddjnfqsjnfh6zvvfal8kar") + ("ssl_verify_fun" "1.1.3" "1zljxashfhqmiscmf298vhr880ppwbgi2rl3nbnyvsfn0mjhw4if") + ("certifi" "2.0.0" "075v7cvny52jbhnskchd3fp68fxgp7qfvdls0haamcycxrn0dipx") + ("providers" "1.7.0" "19p4rbsdx9lm2ihgvlhxyld1q76kxpd7qwyqxxsgmhl5r8ln3rlb") + ("getopt" "1.0.1" "174mb46c2qd1f4a7507fng4vvscjh1ds7rykfab5rdnfp61spqak") + ("bbmustache" "1.3.0" "042pfgss8kscq6ssg8gix8ccmdsrx0anjczsbrn2a6c36ljrx2p6") + ("relx" "3.24.3" "1g90ssg5gnnqs77n7l68nmv5a9fjcrxd0jb259vmff9mnpf1d1p3") + ("cf" "0.2.2" "08cvy7skn5d2k4manlx5k3anqgjdvajjhc5jwxbaszxw34q3na28") + ("cth_readable" "1.3.2" "0g9a6b7zi4azglafd9lfhn5a7vbbafg3s09l092zhcmk9jlgf866") + ("eunit_formatters" "0.5.0" "1jb3hzb216r29x2h4pcjwfmx1k81431rgh5v0mp4x5146hhvmj6n")))) + (package + (name "rebar3") + (version "3.4.7") + (source (origin + (method url-fetch) + (uri (string-append "https://github.com/erlang/rebar3/archive/" + version ".tar.gz")) + (sha256 + (base32 + "11rxb8a62hd5pwnhskmbxl8c0iwqchf6v9iwvzyfxrzjvv6xkcqr")))) + (build-system gnu-build-system) + (arguments `(#:phases (modify-phases %standard-phases + (delete 'configure) + (replace 'build + (lambda* (#:key inputs #:allow-other-keys) + ;; prepare dependencies + (for-each (lambda (name) + (mkdir-p (string-append "_build/default/lib/" name)) + (copy-recursively (assoc-ref inputs name) + (string-append "_build/default/lib/" name))) + (list ,@(map car (warn "DEPS" deps)))) + (setenv "HOME" (getcwd)) + (zero? (system* "./bootstrap")))) + (delete 'check) ;TODO package it + (replace 'install + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (mkdir-p (string-append out "/bin")) + (copy-file "rebar3" (string-append out "/bin/")))))))) + (inputs `(("erlang" ,erlang) + ,@(map (match-lambda + ((name version hash) + (list + name + (origin (method url-fetch/hex.pm) + (uri (string-append "https://repo.hex.pm/tarballs/" name "-" version ".tar")) + (sha256 (base32 hash)) + (file-name (string-append name "-" version ".tar.gz")))))) + deps))) + (home-page "https://rebar3.org") + (synopsis "erlang package build tool") + (description "Rebar3 is an Erlang tool that makes it easy to create, develop, +and release Erlang libraries, applications, and systems in a repeatable manner.") + (license license:asl2.0)))) diff --git a/guix/download.scm b/guix/download.scm index 8a0b19c01..32803b44d 100644 --- a/guix/download.scm +++ b/guix/download.scm @@ -37,6 +37,7 @@ url-fetch url-fetch/tarbomb url-fetch/zipbomb + url-fetch/hex.pm download-to-store)) ;;; Commentary: @@ -630,6 +631,46 @@ own. This helper makes it easier to deal with \"zip bombs\"." #$drv))) #:local-build? #t))) +(define* (url-fetch/hex.pm url hash-algo hash + #:optional name + #:key (system (%current-system)) + (guile (default-guile))) + "Similar to 'url-fetch' but unpack the contents.tar.gz contained in the url.tar. + This helper makes it easier to deal with \"hex.pm tars\"." + (define file-name + (match url + ((head _ ...) + (basename head)) + (_ + (basename url)))) + (define gzip + (module-ref (resolve-interface '(gnu packages compression)) 'gzip)) + (define tar + (module-ref (resolve-interface '(gnu packages base)) 'tar)) + + (mlet %store-monad ((drv (url-fetch url hash-algo hash + (string-append "hex.pm-" + (or name file-name)) + #:system system + #:guile guile))) + ;; Take the hex.pm tar, and unpack both + (gexp->derivation (or name file-name) + #~(begin + (mkdir #$output) + (setenv "PATH" (string-append #$gzip "/bin")) + (chdir #$output) + (zero? (system* (string-append #$tar "/bin/tar") + "xf" #$drv)) + ;; delete a bunch of hex.pm metadata we don't need + (delete-file "CHECKSUM") + (delete-file "metadata.config") + (delete-file "VERSION") + ;; unpack the actual package content + (zero? (system* (string-append #$tar "/bin/tar") + "xf" "contents.tar.gz")) + (delete-file "contents.tar.gz")) + #:local-build? #t))) + (define* (download-to-store store url #:optional (name (basename url)) #:key (log (current-error-port)) recursive? (verify-certificate? #t)) diff --git a/guix/import/hex.scm b/guix/import/hex.scm new file mode 100644 index 000000000..86d960e76 --- /dev/null +++ b/guix/import/hex.scm @@ -0,0 +1,133 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Federico Beffa +;;; +;;; 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 . + +(define-module (guix import hex) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:use-module (guix import json) + #:use-module (guix import hackage) + #:use-module (guix memoization) + #:use-module (guix packages) + #:use-module (guix upstream) + #:use-module (guix store) + #:use-module (guix base32) + #:use-module (guix hash) + #:use-module (guix import utils) + #:use-module ((guix download) #:select (download-to-store url-fetch)) + #:export (hex-fetch)) + +(define %packages-url "https://hex.pm/api/packages/") +(define %tarball-url "https://repo.hex.pm/tarballs/") +(define %package-name-prefix "hex-") + +(define (hex-name->guix-name name) + (if (string-prefix? %package-name-prefix name) + (snake-case name) + (string-append %package-name-prefix (snake-case name)))) + +(define (make-input-entry name) + (list name (list 'unquote (string->symbol name)))) + +(define (as-list item/s) + (if (list? item/s) + item/s + (list item/s))) + +(define (list-or-single item/s) + (if (null? (cdr item/s)) + (car item/s) + items)) + +;;; TODO take version as second arg +(define (hex-fetch package-name) + (define url (string-append %packages-url package-name)) + (define json (json-fetch url)) + (define meta (assoc-ref json "meta")) + (define latest-release (car (assoc-ref json "releases"))) + (define latest-release-info-url (assoc-ref latest-release "url")) + (define latest-release-version (assoc-ref latest-release "version")) + (define release-json (json-fetch latest-release-info-url)) + (define release-meta (assoc-ref release-json "meta")) + ;; TODO maybe also check the versions and optional + (define inputs (map car (assoc-ref release-json "requirements"))) + (define tarball-name (string-append package-name "-" latest-release-version ".tar")) + (define source-url (string-append %tarball-url tarball-name)) + (define tarball (with-store store + (download-to-store store source-url))) + `(package + (name ,(hex-name->guix-name package-name)) + (version ,latest-release-version) + (source (origin + (method url-fetch/hex.pm) + (uri (string-append ,@(list (string-append %tarball-url package-name "-") + 'version ".tar"))) + (sha256 + (base32 + ,(if tarball + (bytevector->nix-base32-string (file-sha256 tarball)) + "failed to download tar archive"))))) + (build-system hex-build-system) + (inputs ,(list 'quasiquote + (map (lambda (input-hex) + (define input-guix (hex-name->guix-name input-hex)) + (make-input-entry input-guix)) + inputs))) + (native-inputs ,(list 'quasiquote + (map (lambda (input-hex) + (define input-guix (match input-hex + ("rebar3" "rebar3") + ("mix" "elixir") + (input (hex-name->guix-name input)))) + (make-input-entry input-guix)) + (match (assoc-ref release-meta "build_tools") + (#f '()) + ((? list? lst) lst) + (single-tool (list single-tool)))))) + (home-page "") + (synopsis "") + (description ,(assoc-ref meta "description")) + (license ,(list-or-single + (map string->license + (as-list (or (assoc-ref meta "licenses") '()))))))) + +(define string->license + ;; copied from the hackage importer, slightly edited some names + ;; TODO: find a complete list of licences on hex.pm + (match-lambda + ("GPL-2" 'gpl2) + ("GPL-3" 'gpl3) + ("GPL" "'gpl??") + ("AGPL-3" 'agpl3) + ("AGPL" "'agpl??") + ("LGPL-2.1" 'lgpl2.1) + ("LGPL-3" 'lgpl3) + ("LGPL" "'lgpl??") + ("BSD2" 'bsd-2) + ("BSD3" 'bsd-3) + ("MIT" 'expat) + ("ISC" 'isc) + ("MPL" 'mpl2.0) + ("CC0-1.0" 'cc0) + ("Apache 2.0" 'asl2.0) + ((x) (string->license x)) + ((lst ...) `(list ,@(map string->license lst))) + (_ #f))) diff --git a/guix/scripts/import.scm b/guix/scripts/import.scm index 67bc7a755..5cb3f5c83 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" "json")) + "hex" "cran" "crate" "texlive" "json")) (define (resolve-importer name) (let ((module (resolve-interface diff --git a/guix/scripts/import/hex.scm b/guix/scripts/import/hex.scm new file mode 100644 index 000000000..f84f87a50 --- /dev/null +++ b/guix/scripts/import/hex.scm @@ -0,0 +1,7 @@ +(define-module (guix scripts import hex) + #:use-module (guix import hex) + #:export (guix-import-hex)) + +(define (guix-import-hex . args) + (warn "hex import" args) + (hex-fetch (car args))) -- 2.14.1