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