[PATCH] mix-build-system: draft 1

  • Done
  • quality assurance status badge
Details
3 participants
  • Pierre-Henry Fröhring
  • Liliana Marie Prikler
  • Pierre-Henry Fröhring
Owner
unassigned
Submitted by
Pierre-Henry Fröhring
Severity
normal
P
P
Pierre-Henry Fröhring wrote on 28 Oct 2023 22:19
(address . guix-patches@gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
68117eb2b3e0e6adcc7449d878e602c7b831ffee.1698524350.git.phfrohring@deeplinks.com
This commit introduces a mix-build-system. The provided code ensures that the
following code runs without errors:

./pre-inst-env guix build elixir-machete

A key challenge is the lack of bit reproducibility, in part due to rebar3's
lack of bit reproducibility. Future patches may address this, and I welcome
feedback.

Given the changes, splitting them into focused patches might be best. As a
first-time contributor, I seek advice on a suitable patch sequence.

I also request guidance from the Guix community for a seamless
integration. Please suggest next steps for the mix-build-system integration.

Thank you.
---
gnu/packages/elixir-xyz.scm | 327 ++++++++++
gnu/packages/elixir.scm | 164 +++--
gnu/packages/emacs-xyz.scm | 20 +
gnu/packages/erlang-xyz.scm | 650 +++++++++++++++++++
gnu/packages/erlang.scm | 996 +++++++++---------------------
guix/build-system/mix.scm | 185 ++++++
guix/build-system/rebar.scm | 320 +++++++---
guix/build/mix-build-system.scm | 373 +++++++++++
guix/build/rebar-build-system.scm | 302 +++++----
9 files changed, 2377 insertions(+), 960 deletions(-)
create mode 100644 gnu/packages/elixir-xyz.scm
create mode 100644 gnu/packages/erlang-xyz.scm
create mode 100644 guix/build-system/mix.scm
create mode 100644 guix/build/mix-build-system.scm

Toggle diff (471 lines)
diff --git a/gnu/packages/elixir-xyz.scm b/gnu/packages/elixir-xyz.scm
new file mode 100644
index 00000000..767f9db7
--- /dev/null
+++ b/gnu/packages/elixir-xyz.scm
@@ -0,0 +1,327 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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 (gnu packages elixir-xyz)
+ #:use-module ((guix licenses)
+ #:prefix license:)
+ #:use-module (gnu packages)
+ #:use-module (gnu packages erlang-xyz)
+ #:use-module (gnu packages linux)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:use-module (guix build-system mix)
+ #:use-module (guix download))
+
+(define-public elixir-nimble-parsec
+ (package
+ (name "elixir-nimble-parsec")
+ (version "1.3.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0rxiw6jzz77v0j460wmzcprhdgn71g1hrz3mcc6djn7bnb0f70i6"))))
+ (build-system mix-build-system)
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "Text-based parser combinators")
+ (description
+ "This library provides primitives for efficient parser combinators, allowing
+for higher-level combinators through composition.")
+ (home-page "https://hexdocs.pm/nimble_parsec/")
+ (license license:asl2.0)))
+
+(define-public elixir-makeup
+ (package
+ (name "elixir-makeup")
+ (version "1.1.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "19jpprryixi452jwhws3bbks6ki3wni9kgzah3srg22a3x8fsi8a"))))
+ (build-system mix-build-system)
+ (propagated-inputs (list elixir-nimble-parsec))
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "Syntax highlighter for source code")
+ (description
+ "Makeup is a generic syntax highlighter in the style of Pygments suitable for use in code hosting,
+forums, wikis or other applications that need to prettify source code.")
+ (home-page "https://hexdocs.pm/makeup/")
+ (license license:bsd-2)))
+
+(define-public elixir-telemetry-metrics
+ (package
+ (name "elixir-telemetry-metrics")
+ (version "0.6.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1iilk2n75kn9i95fdp8mpxvn3rcn3ghln7p77cijqws13j3y1sbv"))))
+ (build-system mix-build-system)
+ ;; There is no test/ in the source.
+ (arguments
+ (list
+ #:tests? #f))
+ (propagated-inputs (list erlang-telemetry))
+ (synopsis
+ "Provides a common interface for defining metrics based on Telemetry events")
+ (description
+ "Common interface for defining metrics based on :telemetry events. Metrics are
+aggregations of Telemetry events with specific name, providing a
+view of the system's behaviour over time.")
+ (home-page "https://hexdocs.pm/telemetry_metrics/")
+ (license license:asl2.0)))
+
+(define-public elixir-jason
+ (package
+ (name "elixir-jason")
+ (version "1.4.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "18d70i31bz11nr6vgsjn5prvhkvwqbyf3xq22ck5cnsnzp6ixc7v"))))
+ (build-system mix-build-system)
+ ;; There is no test/ in the source.
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "JSON parser and generator")
+ (description
+ "Parser and generator are written in pure Elixir and optimized for speed. They
+are at least twice as fast as other Elixir/Erlang libraries (e.g.
+Poison). The performance is comparable to jiffy, which is implemented in C as
+a NIF.")
+ (home-page "https://hexdocs.pm/jason/")
+ (license license:asl2.0)))
+
+(define-public elixir-file-system
+ (package
+ (name "elixir-file-system")
+ (version "0.2.10")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1p0myxmnjjds8bbg69dd6fvhk8q3n7lb78zd4qvmjajnzgdmw6a1"))))
+ (build-system mix-build-system)
+ (inputs (list inotify-tools))
+ (arguments
+ (list
+ #:tests? #f ;There is no test/ in the source.
+ #:phases #~(modify-phases %standard-phases
+ (add-after 'unpack 'rm-priv
+ (lambda _
+ ;; This directory represents source code not needed on UNIX systems.
+ ;; Since we aim at UNIX systems, it is deleted.
+ (delete-file-recursively "priv"))))))
+ (synopsis "File system change watcher")
+ (description "Provides a file system change watcher wrapper based on
+[fs](https://github.com/synrc/fs).")
+ (home-page "https://hexdocs.pm/file_system/")
+ (license license:wtfpl2)))
+
+(define-public elixir-bunt
+ (package
+ (name "elixir-bunt")
+ (version "0.2.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "19bp6xh052ql3ha0v3r8999cvja5d2p6cph02mxphfaj4jsbyc53"))))
+ (build-system mix-build-system)
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "256 color ANSI coloring in the terminal")
+ (description "256 color ANSI coloring in the terminal.")
+ (home-page "https://hexdocs.pm/bunt/")
+ (license license:expat)))
+
+(define-public elixir-inch-ex
+ (package
+ (name "elixir-inch-ex")
+ (version "2.0.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1a4rjcy3hn5pc40si1d1y7qg0b0mnxx6pw825la67ky8r9gfrl4n"))))
+ (build-system mix-build-system)
+ (arguments
+ (list
+ #:tests? #f))
+ (propagated-inputs (list elixir-bunt elixir-jason))
+ (synopsis
+ "Offers a Mix task for suggestions on enhancing your inline documentation")
+ (description
+ "This package provides a Mix task that gives you hints where to improve your
+inline docs.")
+ (home-page "https://hex.pm/packages/inch_ex")
+ (license license:expat)))
+
+(define-public elixir-castore
+ (package
+ (name "elixir-castore")
+ (version "1.0.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1y44amb8falsmrfzpkmf7qp6215g9kdl76g91dpna4af2jwc264l"))))
+ (build-system mix-build-system)
+ ;; There is no test/ in the source.
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "Up-to-date CA certificate store")
+ (description "Up-to-date CA certificate store.")
+ (home-page "https://hexdocs.pm/castore/")
+ (license license:asl2.0)))
+
+(define-public elixir-excoveralls
+ (package
+ (name "elixir-excoveralls")
+ (version "0.18.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "02x69ll5scvraky0k5gacvnnmldv5k04kgk02x087d9w3y8vn28i"))))
+ (build-system mix-build-system)
+ (propagated-inputs (list elixir-castore elixir-jason))
+ ;; No test/ folder.
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis "Coverage report tool with coveralls.io integration")
+ (description
+ "Library that reports test coverage statistics, with the option to
+post to coveralls.io service. It uses Erlang's cover to generate coverage
+information, and posts the test coverage results to coveralls.io through the
+JSON API.")
+ (home-page "https://hexdocs.pm/excoveralls/")
+ (license license:expat)))
+
+(define-public elixir-credo
+ (package
+ (name "elixir-credo")
+ (version "1.7.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "18jqi9s9r1587njzdxycvmmbma30cay9iamni4f3ih54jmh1r1z9"))))
+ (build-system mix-build-system)
+ (propagated-inputs (list elixir-bunt elixir-file-system elixir-jason))
+ (native-inputs (list elixir-excoveralls elixir-inch-ex))
+ (synopsis "Static code analysis tool")
+ (description
+ "Credo is a static code analysis tool for the Elixir language with a focus on
+teaching and code consistency. Credo can show you refactoring opportunities in
+your code, complex code fragments, warn you about common mistakes, show
+inconsistencies in your naming scheme and - if needed - help you enforce a
+desired coding style.")
+ (home-page "https://hexdocs.pm/credo/")
+ (license license:expat)))
+
+(define-public elixir-erlex
+ (package
+ (name "elixir-erlex")
+ (version "0.2.6")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0x8c1j62y748ldvlh46sxzv5514rpzm809vxn594vd7y25by5lif"))))
+ (build-system mix-build-system)
+ (arguments
+ (list
+ #:tests? #f))
+ (synopsis
+ "Convert Erlang style structs and error messages to equivalent Elixir")
+ (description
+ "Converted structs and error messages are useful for pretty printing things
+like Dialyzer errors and Observer .state. NOTE: Because this code calls the
+Elixir formatter, it requires Elixir 1.6+.")
+ (home-page "https://hexdocs.pm/erlex/")
+ (license license:asl2.0)))
+
+(define-public elixir-dialyxir
+ (package
+ (name "elixir-dialyxir")
+ (version "1.4.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "00cqwhd1wabwds44jz94rvvr8z8cp12884d3lp69fqkrszb9bdw4"))))
+ (build-system mix-build-system)
+ (arguments
+ (list
+ #:tests? #f))
+ (propagated-inputs (list elixir-erlex))
+ (synopsis "Mix tasks to simplify use of Dialyzer")
+ (description
+ "Mix Tasks are usable from the directory of the mix project you want to analyze.")
+ (home-page "https://hexdocs.pm/dialyxir/")
+ (license license:asl2.0)))
+
+(define-public elixir-machete
+ (package
+ (name "elixir-machete")
+ (version "0.2.8")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0952603bmqsf6v3ja99zpbnbx5d52i4xksjkfj3irl45ccq5pgq9"))))
+ (build-system mix-build-system)
+ (native-inputs (list elixir-credo elixir-dialyxir))
+ (synopsis "Literate test matchers for ExUnit")
+ (description
+ "Machete provides ergonomic match operators that act as building blocks to let
+you define test expectations that can match data against any combination of
+literals, variables, or parametrically defined matchers.")
+ (home-page "https://hexdocs.pm/machete/")
+ (license license:expat)))
+
+;;;
+;;; Avoid adding new packages to the end of this file. To reduce the chances
+;;; of a merge conflict, place them above by existing packages with similar
+;;; functionality or similar names.
+;;;
diff --git a/gnu/packages/elixir.scm b/gnu/packages/elixir.scm
index 724b4251..d1ac1d07 100644
--- a/gnu/packages/elixir.scm
+++ b/gnu/packages/elixir.scm
@@ -7,6 +7,7 @@
;;; Copyright © 2018 Nikita <nikita@n0.is>
;;; Copyright © 2021 Oskar Köök <oskar@maatriks.ee>
;;; Copyright © 2021 Cees de Groot <cg@evrl.com>
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -24,14 +25,21 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (gnu packages elixir)
- #:use-module ((guix licenses) #:prefix license:)
+ #:use-module ((guix licenses)
+ #:prefix license:)
+ #:use-module (gnu packages compression)
+ #:use-module (gnu packages erlang)
+ #:use-module (gnu packages version-control)
+ #:use-module (gnu packages)
+ #:use-module (guix build utils)
+ #:use-module (guix build-system copy)
#:use-module (guix build-system gnu)
+ #:use-module (guix download)
#:use-module (guix gexp)
#:use-module (guix git-download)
#:use-module (guix packages)
- #:use-module (gnu packages)
- #:use-module (gnu packages erlang)
- #:use-module (gnu packages version-control))
+ #:use-module (guix search-paths)
+ #:use-module (guix utils))
(define-public elixir
(package
@@ -52,57 +60,109 @@ (define-public elixir
(list
#:test-target "test"
#:parallel-tests? #f ;see <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=32171#23>
- #:make-flags #~(list (string-append "PREFIX=" #$output))
- #:phases
- #~(modify-phases %standard-phases
- (add-after 'unpack 'make-git-checkout-writable
- (lambda _
- (for-each make-file-writable (find-files "."))))
- (add-after 'make-git-checkout-writable 'replace-paths
- (lambda* (#:key inputs #:allow-other-keys)
- ;; Note: references end up obfuscated in binary BEAM files where
- ;; they may be invisible to the GC and graft code:
- ;; <https://issues.guix.gnu.org/54304#11>.
- (substitute* '("lib/mix/lib/mix/release.ex"
- "lib/mix/lib/mix/tasks/release.init.ex")
- (("#!/bin/sh")
- (string-append "#!" (search-input-file inputs "/bin/sh"))))
- (substitute* "bin/elixir"
- (("ERTS_BIN=\n")
- (string-append
- "ERTS_BIN="
- ;; Elixir Releases will prepend to ERTS_BIN the path of
- ;; a copy of erl. We detect if a release is being generated
- ;; by checking the initial ERTS_BIN value: if it's empty, we
- ;; are not in release mode and can point to the actual erl
- ;; binary in Guix store.
- "\nif [ -z \"$ERTS_BIN\" ]; then ERTS_BIN="
- (string-drop-right (search-input-file inputs "/bin/erl") 3)
- "; fi\n")))
- (substitute* "bin/mix"
- (("#!/usr/bin/env elixir")
- (string-append "#!" #$output "/bin/elixir")))))
- (add-before 'build 'make-current
- ;; The Elixir compiler checks whether or not to compile files by
- ;; inspecting their timestamps. When the timestamp is equal to the
- ;; epoch no compilation will be performed. Some tests fail when
- ;; files are older than Jan 1, 2000.
- (lambda _
- (for-each (lambda (file)
- (let ((recent 1400000000))
- (utime file recent recent 0 0)))
- (find-files "." ".*"))))
- (add-before 'check 'set-home
- (lambda* (#:key inputs #:allow-other-keys)
- ;; Some tests require access to a home directory.
- (setenv "HOME" "/tmp")))
- (delete 'configure))))
- (inputs
- (list erlang git))
+ #:make-flags #~(list (string-append "PREFIX="
+ #$output))
+ #:phases #~(modify-phases %standard-phases
+ (add-after 'unpack 'make-git-checkout-writable
+ (lambda _
+ (for-each make-file-writable
+ (find-files "."))))
+ (add-after 'make-git-checkout-writable 'replace-paths
+ (lambda* (#:key inputs #:allow-other-keys)
+ ;; Note: references end up obfuscated in binary BEAM files where
+ ;; they may be invisible to the GC and graft code:
+ ;; <https://issues.guix.gnu.org/54304#11>.
+ (substitute* '("lib/mix/lib/mix/release.ex"
+ "lib/mix/lib/mix/tasks/release.init.ex")
+ (("#!/bin/sh")
+ (string-append "#!"
+ (search-input-file inputs "/bin/sh"))))
+ (substitute* "bin/elixir"
+ (("ERTS_BIN=\n")
+ (string-append "ERTS_BIN="
+ ;; Elixir Releases will prepend to ERTS_BIN the path of
+ ;; a copy of erl. We detect if a release is being generated
+ ;; by checking the initial ERTS_BIN value: if it's empty, we
+ ;; are not in release mode and can point to the actual erl
+ ;; binary in Guix store.
+ "\nif [ -z \"$ERTS_BIN\" ]; then ERTS_BIN="
+ (string-drop-right (search-input-file inputs
+ "/bin/erl") 3)
+ "; fi\n")))
+ (substitute* "bin/mix"
+ (("#!/usr/bin/env elixir")
+ (string-append "#!"
+ #$output "/bin/elixir")))))
+ (add-before 'build 'make-current
+ ;; The Elixir compiler checks whether or not to compile files by
+ ;; inspecting their timestamps. When the timestamp is equal to the
+ ;; epoch no compilation will be performed. Some tests fail when
+ ;; files are older than Jan 1, 2000.
+ (lambda _
+ (for-each (lambda (file)
+ (let ((recent 1400000000))
+ (utime file recent recent 0 0)))
+ (find-files "." ".*"))))
+ (add-before 'check 'set-home
+ (lambda* (#:key inputs #:allow-other-keys)
+ ;; Some tests require access to a home directory.
+ (setenv "HOME" "/tmp")))
+ (delete 'configure)
+ (add-aft
This message was truncated. Download the full message here.
L
L
Liliana Marie Prikler wrote on 28 Oct 2023 23:43
65090f6d8f74d0434ed826e565571cf196e9e3ab.camel@gmail.com
Am Samstag, dem 28.10.2023 um 22:19 +0200 schrieb Pierre-Henry
Fröhring:
Toggle quote (19 lines)
> This commit introduces a mix-build-system. The provided code ensures
> that the following code runs without errors:
>
> ./pre-inst-env guix build elixir-machete
>
> A key challenge is the lack of bit reproducibility, in part due to
> rebar3's lack of bit reproducibility. Future patches may address
> this, and I welcome feedback.
>
> Given the changes, splitting them into focused patches might be best.
> As a first-time contributor, I seek advice on a suitable patch
> sequence.
>
> I also request guidance from the Guix community for a seamless
> integration. Please suggest next steps for the mix-build-system
> integration.
>
> Thank you.
> ---
I'd suggest the following order:
1. Clean up your changes for rebar-build-system
2. Add all the packages that can be built with rebar-build-system
3. Add mix-build-system
4. Add all the packages that need to be built with mix-build-system

Steps 2 and 4 should be further split in one patch per package with
each package only requiring the previous ones to build.

Toggle quote (4 lines)
> +(define* (tar-unpack tar)
> + [...])
> +(define* (phase-unpack #:key source #:allow-other-keys)
> + (tar-unpack source))
That's a little silly, isn't it? Stick with a single procedure please.
Also, we're not doing Hungarian variable names.

Cheers
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 01/32] rebar-build-system and packages.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
a3e5ae0f3235df996b4be479f107680ae769a3c4.1698590244.git.phfrohring@deeplinks.com
The builder now accepts the `#:sources-erlang` parameter, which expects a list
of "Source" items. Each "Source" corresponds to the source code of a library
directory, which is where Erlang looks for compiled modules. Documentation:
"Checkout", which are local dependencies linked to directories managed by
rebar. For more information, see
checkouts, rebar3 will not compile if there is no network access.

Change-Id: Idc3aa8bb204f55d0594c1669399845cd9b9e86ab
---
guix/build-system/rebar.scm | 274 +++++++++++++++++++-----------
guix/build/rebar-build-system.scm | 255 +++++++++++++++++----------
2 files changed, 339 insertions(+), 190 deletions(-)

Toggle diff (476 lines)
diff --git a/guix/build-system/rebar.scm b/guix/build-system/rebar.scm
index de1294ec..862721ee 100644
--- a/guix/build-system/rebar.scm
+++ b/guix/build-system/rebar.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -18,102 +19,117 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix build-system rebar)
- #:use-module (guix store)
- #:use-module (guix utils)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
#:use-module (guix gexp)
- #:use-module (guix packages)
#:use-module (guix monads)
+ #:use-module (guix packages)
#:use-module (guix search-paths)
- #:use-module (guix build-system)
- #:use-module (guix build-system gnu)
- #:export (hexpm-uri
- hexpm-package-url
- %rebar-build-system-modules
- rebar-build
- rebar-build-system))
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (srfi srfi-1)
+ #:export (hexpm-uri hexpm-package-url %rebar-build-system-modules
+ rebar-build rebar-build-system))
-;;;
-;;; Definitions for the hex.pm repository,
-;;;
+;; Source
+;; A « Source » reprensents the source code to a library directory. It is
+;; defined as (list <name> <origin>) where: <name> is a string representing
+;; the name of a library directory and <origin> is an origin as defined
+;; (guix packages).
+
+
+;; Pattern that an Erlang Guix package name is expected to match.
+(define pkg-name-re "^erlang-(.*)")
+
+(define (pkg-name->match name)
+ "Return the match object from NAME if NAME starts with pkg-name-prefix."
+ (string-match pkg-name-re name))
+
+(define (pkg-name? name)
+ "Test if NAME is the name of an Erlang Guix package."
+ (or (pkg-name->match name) #f))
-;; URL and paths from
-;; https://github.com/hexpm/specifications/blob/master/endpoints.md
-(define %hexpm-repo-url
- (make-parameter "https://repo.hex.pm"))
+(define (pkg-name->suffix name)
+ "Return the suffix of the name of an Erlang Guix package."
+ (regexp-substitute #f (pkg-name->match name) 1))
-(define hexpm-package-url
- (string-append (%hexpm-repo-url) "/tarballs/"))
+(define* (pkg-name->library-directory-name name #:key (version ""))
+ "Return the name of the library directory associated with the Erlang Guix package name NAME."
+ (string-append (string-replace-substring (pkg-name->suffix name) "-" "_")
+ (if (string= version "") "" (string-append "-" version))))
+
+;; See: https://github.com/hexpm/specifications/blob/master/endpoints.md
+(define hexpm (make-parameter "https://repo.hex.pm"))
+
+(define hexpm-tarballs (string-append (hexpm) "/tarballs/"))
(define (hexpm-uri name version)
"Return a URI string for the package hosted at hex.pm corresponding to NAME
-and VERSION."
- (string-append hexpm-package-url name "-" version ".tar"))
+and VERSION.
-;;
-;; Standard build procedure for Erlang packages using Rebar.
-;;
+XXX: should a warning be emitted?
+If NAME is not an Erlang Guix package name, then emit a warning. The download
+will fail if it is not correct anyway."
-(define %rebar-build-system-modules
- ;; Build-side modules imported by default.
- `((guix build rebar-build-system)
- ,@%gnu-build-system-modules))
+ (define (warn-about name)
+ (format #t "AssertionWarning 4dcbff27
+ Assertion: re matches name.
+ re = ~a
+ name = ~a
+" pkg-name-re name)
+
+ name)
-(define (default-rebar3)
- "Return the default Rebar3 package."
+ (define (name->archive-name name)
+ (if (pkg-name? name)
+ (string-append (pkg-name->library-directory-name name #:version version) ".tar")
+ (string-append (warn-about name) "-" version ".tar")))
+
+ (string-append hexpm-tarballs (name->archive-name name)))
+
+(define (rebar-default)
;; Lazily resolve the binding to avoid a circular dependency.
(let ((erlang-mod (resolve-interface '(gnu packages erlang))))
(module-ref erlang-mod 'rebar3)))
-(define (default-erlang)
- "Return the default Erlang package."
+(define (erlang-default)
;; Lazily resolve the binding to avoid a circular dependency.
(let ((erlang-mod (resolve-interface '(gnu packages erlang))))
(module-ref erlang-mod 'erlang)))
-(define* (lower name
- #:key source inputs native-inputs outputs system target
- (rebar (default-rebar3))
- (erlang (default-erlang))
- #:allow-other-keys
- #:rest arguments)
- "Return a bag for NAME from the given arguments."
- (define private-keywords
- '(#:target #:rebar #:erlang #:inputs #:native-inputs))
-
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs))
- (build-inputs `(("rebar" ,rebar)
- ("erlang" ,erlang) ;; for escriptize
- ,@native-inputs
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (outputs outputs)
- (build rebar-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
-
-(define* (rebar-build name inputs
- #:key
- guile source
- (rebar-flags ''("skip_deps=true" "-vv"))
- (tests? #t)
- (test-target "eunit")
- ;; TODO: install-name ; default: based on guix package name
- (install-profile "default")
- (phases '(@ (guix build rebar-build-system)
- %standard-phases))
- (outputs '("out"))
- (search-paths '())
- (native-search-paths '())
- (system (%current-system))
- (imported-modules %rebar-build-system-modules)
- (modules '((guix build rebar-build-system)
- (guix build utils))))
+(define imported-modules
+ `((guix build rebar-build-system)
+ ,@%gnu-build-system-modules))
+
+(define (input->source input)
+ "Return a Source associated to the Input INPUT."
+ (match input
+ ((name package)
+ (list (pkg-name->library-directory-name name)
+ (package-source package)))))
+
+(define* (rebar-build name
+ inputs
+ #:key
+ guile
+ source
+ (rebar-flags ''())
+ (tests? #t)
+ (test-target "eunit")
+ ;; TODO: install-name ; default: based on guix package name
+ (install-profile "default")
+ (phases '(@ (guix build rebar-build-system)
+ %standard-phases))
+ (outputs '("out"))
+ (search-paths '())
+ (native-search-paths '())
+ (system (%current-system))
+ (imported-modules imported-modules)
+ (modules '((guix build rebar-build-system)
+ (guix build utils)))
+ (sources-erlang '()))
"Build SOURCE with INPUTS."
(define builder
@@ -122,35 +138,95 @@ (define* (rebar-build name inputs
(use-modules #$@(sexp->gexp modules))
#$(with-build-variables inputs outputs
+
#~(rebar-build #:source #+source
- #:system #$system
- #:name #$name
- #:rebar-flags #$rebar-flags
- #:tests? #$tests?
- #:test-target #$test-target
- ;; TODO: #:install-name #$install-name
- #:install-profile #$install-profile
- #:phases #$(if (pair? phases)
- (sexp->gexp phases)
- phases)
- #:outputs %outputs
- #:search-paths '#$(sexp->gexp
- (map search-path-specification->sexp
- search-paths))
- #:inputs %build-inputs)))))
-
- (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
- system #:graft? #f)))
+ #:sources-erlang '#$sources-erlang
+ #:system #$system
+ #:name #$name
+ #:rebar-flags #$rebar-flags
+ #:tests? #$tests?
+ #:test-target #$test-target
+ ;; TODO: #:install-name #$install-name
+ #:install-profile #$install-profile
+ #:phases #$(if (pair?
+ phases)
+ (sexp->gexp
+ phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map
+ search-path-specification->sexp
+ search-paths))
+ #:inputs
+ %build-inputs)))))
+
+ (mlet %store-monad
+ ((guile (package->derivation (or guile
+ (default-guile)) system
+ #:graft? #f)))
+
;; Note: Always pass #:graft? #f. Without it, ALLOWED-REFERENCES &
;; co. would be interpreted as referring to grafted packages.
- (gexp->derivation name builder
+ (gexp->derivation name
+ builder
#:system system
#:target #f
#:graft? #f
#:guile-for-build guile)))
+(define* (lower name
+ #:key
+ (erlang (erlang-default))
+ inputs
+ native-inputs
+ outputs
+ (rebar (rebar-default))
+ source
+ system
+ target
+ #:allow-other-keys #:rest arguments)
+ "Return a bag for NAME from the given arguments."
+
+ (let* ((erlang-packages
+ (filter (lambda (input)
+ (match input
+ ((name _) (pkg-name? name))))
+ (append inputs native-inputs)))
+
+ (erlang-sources (map input->source erlang-packages)))
+
+ (define private-keywords
+ '(#:target #:rebar #:erlang #:inputs #:native-inputs #:sources-erlang))
+
+ (and (not target) ;XXX: no cross-compilation
+ (bag (name name)
+ (system system)
+ (host-inputs inputs)
+ (build-inputs `(,@(standard-packages)
+ ("erlang" ,erlang)
+ ("rebar" ,rebar)
+ ,@inputs
+ ,@native-inputs))
+ (outputs outputs)
+ (build rebar-build)
+ (arguments (append (list #:sources-erlang erlang-sources)
+ (strip-keyword-arguments private-keywords
+ arguments)))))))
+
(define rebar-build-system
- (build-system
- (name 'rebar)
- (description "The standard Rebar build system")
- (lower lower)))
+ (build-system (name 'rebar)
+ (description "The standard Rebar build system")
+ (lower lower)))
+
+
+;;;
+;;; Exports
+;;;
+
+(define hexpm-package-url hexpm-tarballs)
+
+(define %rebar-build-system-modules imported-modules)
+
+
+;;; rebar.scm ends here
diff --git a/guix/build/rebar-build-system.scm b/guix/build/rebar-build-system.scm
index fb664228..b68348bd 100644
--- a/guix/build/rebar-build-system.scm
+++ b/guix/build/rebar-build-system.scm
@@ -2,6 +2,7 @@
;;; Copyright © 2016, 2018 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2019 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
;;; Copyright © 2020, 2022 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,125 +24,197 @@ (define-module (guix build rebar-build-system)
#:use-module ((guix build utils) #:hide (delete))
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
+ #:use-module (ice-9 string-fun)
+ #:use-module (ice-9 receive)
+ #:use-module (ice-9 regex)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
- #:export (rebar-build
- %standard-phases))
+ #:export (rebar-build %standard-phases))
;;
;; Builder-side code of the standard build procedure for Erlang packages using
;; rebar3.
;;
-;; TODO: Think about whether bindir ("ebin"), libdir ("priv") and includedir
-;; "(include") need to be configurable
+;; Library directory
+;; A « library directory » is a directory where Erlang searches for compiled
+;; code. Its name should look like: `a_name-1.2.3' where the suffix `-1.2.3'
+;; is optional. See: https://www.erlang.org/doc/man/code#code-path.
+;;
+;; Package name
+;; A « package name » is the value of the name field of a package
+;; definition. It looks like: `prefix-a-name-1.2.3'. See:
+;; https://guix.gnu.org/manual/en/html_node/Package-Naming.html
+;;
+;; Profile
+;; For Rebar3, a « profile » is a name associated to a set of configuration
+;; settings overriding or complementing the regular configuration. See:
+;; https://rebar3.org/docs/configuration/profiles
+;;
+;; Source
+;; A « source » represents the source code associated to a Guix package as
+;; defined by its `source' field. Here, the data sctructure used to
+;; represent a source has the form `(list name path)' where `name' is a
+;; library directory name and `path' is the store path where to find the
+;; source code.
+;;
+;; Checkout
+;; A « checkout » is a locally defined dependency related to a directory
+;; managed by rebar. See:
+;; https://rebar3.org/docs/configuration/dependencies/#checkout-dependencies
-(define %erlang-libdir "/lib/erlang/lib")
+(define sep "/")
-(define* (erlang-depends #:key inputs #:allow-other-keys)
- (define input-directories
- (match inputs
- (((_ . dir) ...)
- dir)))
- (mkdir-p "_checkouts")
-
- (for-each
- (lambda (input-dir)
- (let ((elibdir (string-append input-dir %erlang-libdir)))
- (when (directory-exists? elibdir)
- (for-each
- (lambda (dirname)
- (let ((dest (string-append elibdir "/" dirname))
- (link (string-append "_checkouts/" dirname)))
- (when (not (file-exists? link))
- ;; RETHINK: Maybe better copy and make writable to avoid some
- ;; error messages e.g. when using with rebar3-git-vsn.
- (symlink dest link))))
- (list-directories elibdir)))))
- input-directories))
+;; Where Erlang libraries are installed relative to a package path in the store.
+(define lib-erlang-lib "lib/erlang/lib")
+
+(define (list-directories directory)
+ "Return file names of the sub-directory of DIRECTORY."
+ (scandir directory
+ (lambda (file)
+ (and (not (member file '("." "..")))
+ (file-is-directory? (string-append directory sep file))))))
+
+(define* (pkg-name->libdir-name name)
+ "Return the library name deduced from the Erlang package name NAME."
+ (let* ((suffix (regexp-substitute #f (string-match "^erlang-(.*)" name) 1))
+ (elements (string-split suffix #\-)))
+ (string-append (string-join (drop-right elements 1) "_") "-" (last elements))))
+
+(define (libdir-name->prefix name)
+ "Return the prefix of a library directory name NAME."
+ (car (string-split name #\-)))
+
+(define (rebar-build-dir profile)
+ "Return the path where rebar builds libraries given the profile PROFILE."
+ (format #f "_build/~a/lib" profile))
+
+(define* (pkg-name->build-dir name #:key (profile "default"))
+ "Return the path of library directory where rebar3 builds code of an Erlang package named NAME given the profile PROFILE."
+ (string-append (rebar-build-dir profile) sep (libdir-name->prefix (pkg-name->libdir-name name))))
(define* (unpack #:key source #:allow-other-keys)
- "Unpack SOURCE in the working directory, and change directory within the
-source. When SOURCE is a directory, copy it in a sub-directory of the current
-working directory."
- (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
- (gnu-unpack #:source source)
- ;; Packages from hex.pm typically have a contents.tar.gz containing the
- ;; actual source. If this tar file exists, extract it.
- (when (file-exists? "contents.tar.gz")
- (invoke "tar" "xvf" "contents.tar.gz"))))
-
-(define* (build #:key (rebar-flags '()) #:allow-other-keys)
+ (if (file-is-directory? source)
+ ;; If source is a checkout:
+ (begin
+ ;; Preserve timestamps (set to the Epoch) on the copied tree so that
+ ;; things work deterministically.
+ (copy-recursively source "." #:keep-mtime? #t)
+ ;; Make the source checkout files writable, for convenience.
+ (for-each (lambda (f)
+ (false-if-exception (make-file-writable f)))
+ (find-files ".")))
+
+ ;; If source is an hex.pm archive:
+ (begin
+ (invoke "tar" "xvf" source)
+ (invoke "tar" "xvf" "contents.tar.gz")
+
+ ;; Prevent an error message during the install phase.
+ ;; `rebar3 compile' produces symlinks like so in _build/:
+ ;; priv -> ../../../../priv
+ ;; include -> ../../../../include
+ ;;
+ ;; The install phase copies whatever has been built to the output directory.
+ ;; If the priv/ directory is absent, then an error `i/o error:
+ ;; _build/…/priv: No such file or directory' occurs. So, we make sure that a
+ ;; directory exists.
+ (for-each (lambda (dir) (mkdir-p dir)) (list "priv" "include")))))
+
+(define (configure-HOME . ignored_args)
+ "In some cases, it is needed for the environment
This message was truncated. Download the full message here.
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 02/32] gnu: erlang updated.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
6e5850df7e25c79f44d9f9038fce595cd209878a.1698590244.git.phfrohring@deeplinks.com
Wrapped Erlang programs (`erl`, `erlc`, `escript`) now prepend ERL_LIBS with
`native-search-paths` field in the package specification sets GUIX_ERL_LIBS,
which aggregates all compiled libraries for Erlang and Elixir, akin to the
functionality of GUIX_PYTHONPATH.

Change-Id: I53d0462eb366ebe66422e0b187f4db091a9fe5b5
---
gnu/packages/erlang.scm | 101 ++++++++++++++++++++++++----------------
1 file changed, 60 insertions(+), 41 deletions(-)

Toggle diff (306 lines)
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c53cb72c..dafc0e81 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -28,22 +28,23 @@
(define-module (gnu packages erlang)
#:use-module ((guix licenses) #:prefix license:)
- #:use-module (guix gexp)
- #:use-module (guix build-system gnu)
- #:use-module (guix build-system emacs)
- #:use-module (guix build-system rebar)
- #:use-module (guix download)
- #:use-module (guix git-download)
- #:use-module (guix packages)
- #:use-module (guix utils)
- #:use-module (gnu packages)
+ #:use-module (gnu packages elixir)
#:use-module (gnu packages fontutils)
#:use-module (gnu packages gl)
#:use-module (gnu packages ncurses)
#:use-module (gnu packages perl)
- #:use-module (gnu packages version-control)
#:use-module (gnu packages tls)
- #:use-module (gnu packages wxwidgets))
+ #:use-module (gnu packages version-control)
+ #:use-module (gnu packages wxwidgets)
+ #:use-module (gnu packages)
+ #:use-module (guix build-system emacs)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system rebar)
+ #:use-module (guix download)
+ #:use-module (guix gexp)
+ #:use-module (guix git-download)
+ #:use-module (guix packages)
+ #:use-module (guix utils))
(define-public erlang
(package
@@ -173,7 +174,16 @@ (define-public erlang
(substitute* (string-append out "/bin/erl")
(("basename") (which "basename"))
(("dirname") (which "dirname"))))))
- (add-after 'install 'install-doc
+ (add-after 'patch-erl 'wrap-programs
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (programs '("erl" "erlc" "escript")))
+ (for-each
+ (lambda (program)
+ (wrap-program (string-append out "/bin/" program)
+ '("ERL_LIBS" ":" prefix ("${GUIX_ERL_LIBS}"))))
+ programs))))
+ (add-after 'wrap-programs 'install-doc
(lambda* (#:key inputs outputs #:allow-other-keys)
(let* ((out (assoc-ref outputs "out"))
(manpages (assoc-ref inputs "erlang-manpages"))
@@ -181,6 +191,15 @@ (define-public erlang
(mkdir-p share)
(with-directory-excursion share
(invoke "tar" "xvf" manpages))))))))
+ (native-search-paths
+ (list (search-path-specification
+ (variable "GUIX_ERL_LIBS")
+ (files
+ (list
+ "lib/erlang/lib"
+ (string-append
+ "lib/elixir/"
+ (version-major+minor (package-version elixir))))))))
(home-page "https://www.erlang.org/")
(synopsis "The Erlang programming language")
(description
@@ -219,12 +238,12 @@ (define-public erlang-bbmustache
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "bbmustache" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "0fvvaxdpziygxl30j59g98qkh2n47xlb7w5dfpsm2bfcsnj372v8"))))
(build-system rebar-build-system)
(inputs
- (list erlang-getopt rebar3-git-vsn
+ (list erlang-getopt erlang-rebar3-git-vsn
erlang-edown)) ; for building the docs
(arguments
`(#:tests? #f ;; requires mustache specification file
@@ -251,7 +270,7 @@ (define-public erlang-certifi
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "certifi" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "0ha6vmf5p3xlbf5w1msa89frhvfk535rnyfybz9wdmh6vdms8v96"))))
(build-system rebar-build-system)
@@ -275,7 +294,7 @@ (define-public erlang-cf
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "cf" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "0wknz4xkqkhgvlx4vx5619p8m65v7g87lfgsvfy04jrsgm28spii"))))
(build-system rebar-build-system)
@@ -314,7 +333,7 @@ (define-public erlang-covertool
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "covertool" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1p0c1n3nl4063xwi1sv176l1x68xqf07qwvj444a5z888fx6i5aw"))))
(build-system rebar-build-system)
@@ -335,7 +354,7 @@ (define-public erlang-cth-readable
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "cth_readable" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "104xgybb6iciy6i28pyyrarqzliddi8kjyq43ajaav7y5si42rb8"))))
(build-system rebar-build-system)
@@ -356,7 +375,7 @@ (define-public erlang-edown
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "edown" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "0ij47gvgs6yfqphj0f54qjzj18crj8y1dsjjlzpp3dp8pscqzbqw"))))
(build-system rebar-build-system)
@@ -373,7 +392,7 @@ (define-public erlang-erlware-commons
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "erlware_commons" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "18qam9xdzi74wppb0cj4zc8161i0i8djr79z8662m6d276f2jz5m"))))
(build-system rebar-build-system)
@@ -400,7 +419,7 @@ (define-public erlang-eunit-formatters
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "eunit_formatters" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1jb3hzb216r29x2h4pcjwfmx1k81431rgh5v0mp4x5146hhvmj6n"))))
(build-system rebar-build-system)
@@ -416,7 +435,7 @@ (define-public erlang-getopt
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "getopt" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "09pasi7ki1rivw9sl7xndj5qgjbdqvcscxk83yk85yr28gm9l0m0"))))
(build-system rebar-build-system)
@@ -433,7 +452,7 @@ (define-public erlang-hex-core
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "hex_core" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "06p65hlm29ky03vs3fq3qz6px2ylwp8b0f2y75wdf5cm0kx2332b"))))
(build-system rebar-build-system)
@@ -445,7 +464,7 @@ (define-public erlang-hex-core
(when tests?
(invoke "rebar3" "as" "test" "proper")))))))
(inputs
- (list erlang-proper rebar3-proper))
+ (list erlang-proper erlang-rebar3-proper))
(home-page "https://github.com/hexpm/hex_core")
(synopsis "Reference implementation of Hex specifications")
(description "This package provides the reference implementation of Hex
@@ -459,7 +478,7 @@ (define-public erlang-jsone
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "jsone" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1gaxiw76syjp3s9rygskm32y9799b917q752rw8bxj3bxq93g8x3"))))
(build-system rebar-build-system)
@@ -483,7 +502,7 @@ (define-public erlang-parse-trans
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "parse_trans" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "16p4c2xjrvz16kzpr9pmcvi6nxq6rwckqi9fp0ksibaxwxn402k2"))))
(build-system rebar-build-system)
@@ -506,7 +525,7 @@ (define-public erlang-proper
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "proper" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1fwcas4a9kz3w3z1jqdk9lw8822srfjk9lcpvbxkxlsv3115ha0q"))))
(build-system rebar-build-system)
@@ -532,7 +551,7 @@ (define-public erlang-jsx
(version "3.1.0")
(source (origin
(method url-fetch)
- (uri (hexpm-uri "jsx" version))
+ (uri (hexpm-uri name version))
(sha256
(base32
"1wr7jkxm6nlgvd52xhniav64xr9rml2ngb35rwjwqlqvq7ywhp0c"))))
@@ -550,7 +569,7 @@ (define-public erlang-providers
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "providers" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "05y0kz3xgx77hzn1l05byaisvmk8bgds7c22hrh0a5ba81sfi1yj"))))
(build-system rebar-build-system)
@@ -568,7 +587,7 @@ (define-public erlang-relx
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "relx" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "02gmfx1vxg9m3mq4njsqhs4972l4nb8m5p1pdcf64g09ccf17y1g"))))
(build-system rebar-build-system)
@@ -590,7 +609,7 @@ (define-public erlang-ssl-verify-fun
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "ssl_verify_fun" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1026l1z1jh25z8bfrhaw0ryk5gprhrpnirq877zqhg253x3x5c5x"))))
(build-system rebar-build-system)
@@ -676,14 +695,14 @@ (define-public rebar3
of locations (git, hg, etc).")
(license license:asl2.0)))
-(define-public rebar3-raw-deps
+(define-public erlang-rebar3-raw-deps
(package
- (name "rebar3-raw-deps")
+ (name "erlang-rebar3-raw-deps")
(version "2.0.0")
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "rebar3_raw_deps" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1pzmm3m8gb2s9jn8fp6shzgfmy4mvh2vdci0z6nsm74ma3ffh1i3"))))
(build-system rebar-build-system)
@@ -693,14 +712,14 @@ (define-public rebar3-raw-deps
applications as a dependent libraries.")
(license license:expat)))
-(define-public rebar3-git-vsn
+(define-public erlang-rebar3-git-vsn
(package
- (name "rebar3-git-vsn")
+ (name "erlang-rebar3-git-vsn")
(version "1.1.1")
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "rebar3_git_vsn" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1dfz56034pa25axly9vqdzv3phkn8ll0qwrkws96pbgcprhky1hx"))))
(build-system rebar-build-system)
@@ -724,14 +743,14 @@ (define-public rebar3-git-vsn
a git checkout.")
(license license:expat)))
-(define-public rebar3-proper
+(define-public erlang-rebar3-proper
(package
- (name "rebar3-proper")
+ (name "erlang-rebar3-proper")
(version "0.12.1")
(source
(origin
(method url-fetch)
- (uri (hexpm-uri "rebar3_proper" version))
+ (uri (hexpm-uri name version))
(sha256
(base32 "1f174fb6h2071wr7qbw9aqqvnglzsjlylmyi8215fhrmi38w94b6"))))
(build-system rebar-build-system)
@@ -803,7 +822,7 @@ (define-public erlang-lfe
(setenv "REBAR_CACHE_DIR" "/tmp")
(invoke "make" "-j" (number->string (parallel-job-count))
"tests"))))))))
- (native-inputs (list rebar3 rebar3-proper erlang-proper))
+ (native-inputs (list rebar3 erlang-rebar3-proper erlang-proper))
(propagated-inputs (list erlang))
(home-page "https://github.com/lfe/lfe")
(synopsis "Lisp Flavoured Erlang")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 03/32] gnu: erlang-certifi: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
7c58f0885d71a76a852380230a2563eaf9508002.1698590244.git.phfrohring@deeplinks.com
Change-Id: I7491af542af5ffb2d82b5555675f4f7dbef167af
---
gnu/packages/erlang-xyz.scm | 62 +++++++++++++++++++++++++++++++++++++
gnu/packages/erlang.scm | 25 +--------------
2 files changed, 63 insertions(+), 24 deletions(-)
create mode 100644 gnu/packages/erlang-xyz.scm

Toggle diff (113 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
new file mode 100644
index 00000000..444fa648
--- /dev/null
+++ b/gnu/packages/erlang-xyz.scm
@@ -0,0 +1,62 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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 (gnu packages erlang-xyz)
+ #:use-module ((guix licenses) #:prefix license:)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages version-control)
+ #:use-module (gnu packages)
+ #:use-module (guix build-system rebar)
+ #:use-module (guix download)
+ #:use-module (guix gexp)
+ #:use-module (guix git-download)
+ #:use-module (guix git-download)
+ #:use-module (guix hg-download)
+ #:use-module (guix packages)
+ #:use-module (guix utils)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26))
+
+(define-public erlang-certifi
+ (package
+ (name "erlang-certifi")
+ (version "2.9.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0ha6vmf5p3xlbf5w1msa89frhvfk535rnyfybz9wdmh6vdms8v96"))))
+ (build-system rebar-build-system)
+ (arguments `(#:tests? #f)) ;; have not been updated for latest cert bundle
+ (home-page "https://github.com/certifi/erlang-certifi/")
+ (synopsis "Erlang CA certificate bundle")
+ (description "This Erlang library contains a CA bundle that you can
+reference in your Erlang application. This is useful for systems that do not
+have CA bundles that Erlang can find itself, or where a uniform set of CAs is
+valuable.
+
+This an Erlang specific port of certifi. The CA bundle is derived from
+Mozilla's canonical set.")
+ (license license:bsd-3)))
+
+;;;
+;;; Avoid adding new packages to the end of this file. To reduce the chances
+;;; of a merge conflict, place them above by existing packages with similar
+;;; functionality or similar names.
+;;;
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index dafc0e81..c729ab8a 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -29,6 +29,7 @@
(define-module (gnu packages erlang)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (gnu packages elixir)
+ #:use-module (gnu packages erlang-xyz)
#:use-module (gnu packages fontutils)
#:use-module (gnu packages gl)
#:use-module (gnu packages ncurses)
@@ -263,30 +264,6 @@ (define-public erlang-bbmustache
Mustache template engine")
(license license:expat)))
-(define-public erlang-certifi
- (package
- (name "erlang-certifi")
- (version "2.9.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "0ha6vmf5p3xlbf5w1msa89frhvfk535rnyfybz9wdmh6vdms8v96"))))
- (build-system rebar-build-system)
- (arguments
- `(#:tests? #f)) ;; have not been updated for latest cert bundle
- (home-page "https://github.com/certifi/erlang-certifi/")
- (synopsis "Erlang CA certificate bundle")
- (description "This Erlang library contains a CA bundle that you can
-reference in your Erlang application. This is useful for systems that do not
-have CA bundles that Erlang can find itself, or where a uniform set of CAs is
-valuable.
-
-This an Erlang specific port of certifi. The CA bundle is derived from
-Mozilla's canonical set.")
- (license license:bsd-3)))
-
(define-public erlang-cf
(package
(name "erlang-cf")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 04/32] gnu: erlang-getopt: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
f8c4db6aa007ea895d87914f0bd13cfb0eff313b.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ic7740512545c8798a4a7927b7aeee6e33f6990a2
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 444fa648..6ca0b4ae 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -55,6 +55,23 @@ (define-public erlang-certifi
Mozilla's canonical set.")
(license license:bsd-3)))
+(define-public erlang-getopt
+ (package
+ (name "erlang-getopt")
+ (version "1.0.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "09pasi7ki1rivw9sl7xndj5qgjbdqvcscxk83yk85yr28gm9l0m0"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/jcomellas/getopt")
+ (synopsis "Command-line options parser for Erlang")
+ (description "This package provides an Erlang module to parse command line
+arguments using the GNU getopt syntax.")
+ (license license:bsd-3)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c729ab8a..6c3b845b 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -405,23 +405,6 @@ (define-public erlang-eunit-formatters
(description "This package provides a better output for Erlang eunits.")
(license license:asl2.0)))
-(define-public erlang-getopt
- (package
- (name "erlang-getopt")
- (version "1.0.2")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "09pasi7ki1rivw9sl7xndj5qgjbdqvcscxk83yk85yr28gm9l0m0"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/jcomellas/getopt")
- (synopsis "Command-line options parser for Erlang")
- (description "This package provides an Erlang module to parse command line
-arguments using the GNU getopt syntax.")
- (license license:bsd-3)))
-
(define-public erlang-hex-core
(package
(name "erlang-hex-core")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 05/32] gnu: erlang-edown: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
28fffec0ba629384ce2b9d20a630eb8dfe08654a.1698590244.git.phfrohring@deeplinks.com
Change-Id: Iceff5a74baf1de97f478b168f122e7ec715b24d7
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 6ca0b4ae..5815d19f 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -72,6 +72,23 @@ (define-public erlang-getopt
arguments using the GNU getopt syntax.")
(license license:bsd-3)))
+(define-public erlang-edown
+ (package
+ (name "erlang-edown")
+ (version "0.8.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0ij47gvgs6yfqphj0f54qjzj18crj8y1dsjjlzpp3dp8pscqzbqw"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/uwiger/edown")
+ (synopsis "Markdown extension for EDoc")
+ (description "This package provides an extension for EDoc for generating
+Markdown.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 6c3b845b..5148abf0 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -345,23 +345,6 @@ (define-public erlang-cth-readable
outputs you want to be readable around all that noise they contain.")
(license license:bsd-3)))
-(define-public erlang-edown
- (package
- (name "erlang-edown")
- (version "0.8.4")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "0ij47gvgs6yfqphj0f54qjzj18crj8y1dsjjlzpp3dp8pscqzbqw"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/uwiger/edown")
- (synopsis "Markdown extension for EDoc")
- (description "This package provides an extension for EDoc for generating
-Markdown.")
- (license license:asl2.0)))
-
(define-public erlang-erlware-commons
(package
(name "erlang-erlware-commons")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:36
[PATCH va3e5ae0f..37252e07 06/32] gnu: erlang-rebar3-git-vsn: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
44bec23d6d48ecc169f1bec65a465edd7c32e973.1698590244.git.phfrohring@deeplinks.com
Change-Id: I5a743e71b2034ba1cfe71fe6121137b3194befed
---
gnu/packages/erlang-xyz.scm | 32 +++++++++++++++++++++++++++++++-
gnu/packages/erlang.scm | 31 -------------------------------
2 files changed, 31 insertions(+), 32 deletions(-)

Toggle diff (94 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 5815d19f..bfc4802a 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -25,7 +25,6 @@ (define-module (gnu packages erlang-xyz)
#:use-module (guix download)
#:use-module (guix gexp)
#:use-module (guix git-download)
- #:use-module (guix git-download)
#:use-module (guix hg-download)
#:use-module (guix packages)
#:use-module (guix utils)
@@ -89,6 +88,37 @@ (define-public erlang-edown
Markdown.")
(license license:asl2.0)))
+(define-public erlang-rebar3-git-vsn
+ (package
+ (name "erlang-rebar3-git-vsn")
+ (version "1.1.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1dfz56034pa25axly9vqdzv3phkn8ll0qwrkws96pbgcprhky1hx"))))
+ (build-system rebar-build-system)
+ (inputs
+ (list git-minimal/pinned))
+ (arguments
+ `(;; Running the tests require binary artifact (tar-file containing
+ ;; samples git repos) TODO: remove these from the source
+ #:tests? #f
+ #:phases
+ (modify-phases %standard-phases
+ (add-after 'unpack 'patch-path
+ (lambda* (#:key inputs #:allow-other-keys)
+ (let ((git (assoc-ref inputs "git-minimal")))
+ (substitute* "src/rebar3_git_vsn.erl"
+ (("rebar_utils:sh\\(\"git " _)
+ (string-append "rebar_utils:sh(\"" git "/bin/git ")))))))))
+ (home-page "https://github.com/soranoba/rebar3_git_vsn")
+ (synopsis "Rebar3 plugin for generating the version from git")
+ (description "This plugin adds support for generating the version from
+a git checkout.")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 5148abf0..6320e3d0 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -655,37 +655,6 @@ (define-public erlang-rebar3-raw-deps
applications as a dependent libraries.")
(license license:expat)))
-(define-public erlang-rebar3-git-vsn
- (package
- (name "erlang-rebar3-git-vsn")
- (version "1.1.1")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1dfz56034pa25axly9vqdzv3phkn8ll0qwrkws96pbgcprhky1hx"))))
- (build-system rebar-build-system)
- (inputs
- (list git-minimal/pinned))
- (arguments
- `(;; Running the tests require binary artifact (tar-file containing
- ;; samples git repos) TODO: remove these from the source
- #:tests? #f
- #:phases
- (modify-phases %standard-phases
- (add-after 'unpack 'patch-path
- (lambda* (#:key inputs #:allow-other-keys)
- (let ((git (assoc-ref inputs "git-minimal")))
- (substitute* "src/rebar3_git_vsn.erl"
- (("rebar_utils:sh\\(\"git " _)
- (string-append "rebar_utils:sh(\"" git "/bin/git ")))))))))
- (home-page "https://github.com/soranoba/rebar3_git_vsn")
- (synopsis "Rebar3 plugin for generating the version from git")
- (description "This plugin adds support for generating the version from
-a git checkout.")
- (license license:expat)))
-
(define-public erlang-rebar3-proper
(package
(name "erlang-rebar3-proper")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 07/32] gnu: erlang-rebar3-raw-deps: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
d2320a870e739b630a069a696fb9017f4d218996.1698590244.git.phfrohring@deeplinks.com
Change-Id: I42b34a1bba7e2eb3cce4c385f0c3d27c5bba146e
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index bfc4802a..61d7416a 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -119,6 +119,23 @@ (define-public erlang-rebar3-git-vsn
a git checkout.")
(license license:expat)))
+(define-public erlang-rebar3-raw-deps
+ (package
+ (name "erlang-rebar3-raw-deps")
+ (version "2.0.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1pzmm3m8gb2s9jn8fp6shzgfmy4mvh2vdci0z6nsm74ma3ffh1i3"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/soranoba/rebar3_raw_deps")
+ (synopsis "Rebar3 plugin for supporting \"raw\" dependencies")
+ (description "This plugin provides support for handling non-OTP
+applications as a dependent libraries.")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 6320e3d0..147b0451 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -638,23 +638,6 @@ (define-public rebar3
of locations (git, hg, etc).")
(license license:asl2.0)))
-(define-public erlang-rebar3-raw-deps
- (package
- (name "erlang-rebar3-raw-deps")
- (version "2.0.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1pzmm3m8gb2s9jn8fp6shzgfmy4mvh2vdci0z6nsm74ma3ffh1i3"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/soranoba/rebar3_raw_deps")
- (synopsis "Rebar3 plugin for supporting \"raw\" dependencies")
- (description "This plugin provides support for handling non-OTP
-applications as a dependent libraries.")
- (license license:expat)))
-
(define-public erlang-rebar3-proper
(package
(name "erlang-rebar3-proper")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 08/32] gnu: erlang-rebar3-proper: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
869a55bfe133cab64bb6c9e668ecc273568a0194.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ibd9df5c77fae83c3e90c4e2dc77b3cfb5e6a482b
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 61d7416a..426a5f95 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -136,6 +136,23 @@ (define-public erlang-rebar3-raw-deps
applications as a dependent libraries.")
(license license:expat)))
+(define-public erlang-rebar3-proper
+ (package
+ (name "erlang-rebar3-proper")
+ (version "0.12.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1f174fb6h2071wr7qbw9aqqvnglzsjlylmyi8215fhrmi38w94b6"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/ferd/rebar3_proper")
+ (synopsis "Rebar3 PropEr plugin")
+ (description "This plugin allows running PropEr test suites from within
+rebar3.")
+ (license license:bsd-3)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 147b0451..8269cba1 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -638,23 +638,6 @@ (define-public rebar3
of locations (git, hg, etc).")
(license license:asl2.0)))
-(define-public erlang-rebar3-proper
- (package
- (name "erlang-rebar3-proper")
- (version "0.12.1")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1f174fb6h2071wr7qbw9aqqvnglzsjlylmyi8215fhrmi38w94b6"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/ferd/rebar3_proper")
- (synopsis "Rebar3 PropEr plugin")
- (description "This plugin allows running PropEr test suites from within
-rebar3.")
- (license license:bsd-3)))
-
(define-public erlang-lfe
(package
(name "erlang-lfe")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 09/32] gnu: erlang-bbmustache: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
6d932942fee25dd60756618f5685d5960f88aa0e.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ied29a387cbaef59f16613d7425417da4fc8eed0c
---
gnu/packages/erlang-xyz.scm | 32 ++++++++++++++++++++++++++++++++
gnu/packages/erlang.scm | 32 --------------------------------
2 files changed, 32 insertions(+), 32 deletions(-)

Toggle diff (88 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 426a5f95..5a966d2a 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -153,6 +153,38 @@ (define-public erlang-rebar3-proper
rebar3.")
(license license:bsd-3)))
+(define-public erlang-bbmustache
+ (package
+ (name "erlang-bbmustache")
+ (version "1.12.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0fvvaxdpziygxl30j59g98qkh2n47xlb7w5dfpsm2bfcsnj372v8"))))
+ (build-system rebar-build-system)
+ (inputs
+ (list erlang-getopt erlang-rebar3-git-vsn
+ erlang-edown)) ; for building the docs
+ (arguments
+ `(#:tests? #f ;; requires mustache specification file
+ #:phases
+ (modify-phases %standard-phases
+ (add-before 'build 'build-more
+ (lambda _
+ (invoke "rebar3" "as" "dev" "escriptize")))
+ (add-after 'install 'install-escript
+ (lambda* (#:key outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out")))
+ (install-file "_build/dev/bin/bbmustache"
+ (string-append out "/bin"))))))))
+ (home-page "https://github.com/soranoba/bbmustache/")
+ (synopsis "Binary pattern match Based Mustache template engine for Erlang")
+ (description "This Erlang library provides a Binary pattern match Based
+Mustache template engine")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 8269cba1..c0cbf5a6 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,38 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-bbmustache
- (package
- (name "erlang-bbmustache")
- (version "1.12.2")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "0fvvaxdpziygxl30j59g98qkh2n47xlb7w5dfpsm2bfcsnj372v8"))))
- (build-system rebar-build-system)
- (inputs
- (list erlang-getopt erlang-rebar3-git-vsn
- erlang-edown)) ; for building the docs
- (arguments
- `(#:tests? #f ;; requires mustache specification file
- #:phases
- (modify-phases %standard-phases
- (add-before 'build 'build-more
- (lambda _
- (invoke "rebar3" "as" "dev" "escriptize")))
- (add-after 'install 'install-escript
- (lambda* (#:key outputs #:allow-other-keys)
- (let* ((out (assoc-ref outputs "out")))
- (install-file "_build/dev/bin/bbmustache"
- (string-append out "/bin"))))))))
- (home-page "https://github.com/soranoba/bbmustache/")
- (synopsis "Binary pattern match Based Mustache template engine for Erlang")
- (description "This Erlang library provides a Binary pattern match Based
-Mustache template engine")
- (license license:expat)))
-
(define-public erlang-cf
(package
(name "erlang-cf")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 10/32] gnu: erlang-cf: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
5e9792483fe15f4545729e452e25378ffa9e5761.1698590244.git.phfrohring@deeplinks.com
Change-Id: Idcb18977a9409268ae7258d8398772021a651c63
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 5a966d2a..1eb7437e 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -185,6 +185,23 @@ (define-public erlang-bbmustache
Mustache template engine")
(license license:expat)))
+(define-public erlang-cf
+ (package
+ (name "erlang-cf")
+ (version "0.3.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0wknz4xkqkhgvlx4vx5619p8m65v7g87lfgsvfy04jrsgm28spii"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/project-fifo/cf")
+ (synopsis "Terminal colour helper for Erlang io and io_lib")
+ (description "This package provides a helper library for termial colour
+printing extending the io:format syntax to add colours.")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c0cbf5a6..eeb1231e 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,23 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-cf
- (package
- (name "erlang-cf")
- (version "0.3.1")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "0wknz4xkqkhgvlx4vx5619p8m65v7g87lfgsvfy04jrsgm28spii"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/project-fifo/cf")
- (synopsis "Terminal colour helper for Erlang io and io_lib")
- (description "This package provides a helper library for termial colour
-printing extending the io:format syntax to add colours.")
- (license license:expat)))
-
(define-public erlang-yamerl
(package
(name "erlang-yamerl")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 11/32] gnu: erlang-yamerl: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
faad692641144d2bee7109043a75cfef628e82f9.1698590244.git.phfrohring@deeplinks.com
Change-Id: I1a9712519e8d243f506e60acf19d1607a705269d
---
gnu/packages/erlang-xyz.scm | 22 ++++++++++++++++++++++
gnu/packages/erlang.scm | 22 ----------------------
2 files changed, 22 insertions(+), 22 deletions(-)

Toggle diff (68 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 1eb7437e..78f829e9 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -202,6 +202,28 @@ (define-public erlang-cf
printing extending the io:format syntax to add colours.")
(license license:expat)))
+(define-public erlang-yamerl
+ (package
+ (name "erlang-yamerl")
+ (version "0.10.0")
+ (source
+ (origin
+ (method git-fetch)
+ (uri (git-reference
+ ;; There are no tests included on Hex.
+ (url "https://github.com/yakaz/yamerl")
+ (commit (string-append "v" version))))
+ (file-name (git-file-name name version))
+ (sha256
+ (base32 "0if8abgmispcfk7zhd0a5dndzwzbsmqrbyrm5shk375r2dbbwak6"))))
+ (build-system rebar-build-system)
+ (synopsis "YAML and JSON parser in pure Erlang")
+ (description
+ "Erlang application to parse YAML 1.1 and YAML 1.2 documents, as well as
+JSON documents.")
+ (home-page "https://hexdocs.pm/yamerl/")
+ (license license:bsd-2)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index eeb1231e..5ed11c28 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,28 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-yamerl
- (package
- (name "erlang-yamerl")
- (version "0.10.0")
- (source
- (origin
- (method git-fetch)
- (uri (git-reference
- ;; There are no tests included on Hex.
- (url "https://github.com/yakaz/yamerl")
- (commit (string-append "v" version))))
- (file-name (git-file-name name version))
- (sha256
- (base32 "0if8abgmispcfk7zhd0a5dndzwzbsmqrbyrm5shk375r2dbbwak6"))))
- (build-system rebar-build-system)
- (synopsis "YAML and JSON parser in pure Erlang")
- (description
- "Erlang application to parse YAML 1.1 and YAML 1.2 documents, as well as
-JSON documents.")
- (home-page "https://hexdocs.pm/yamerl/")
- (license license:bsd-2)))
-
(define-public erlang-covertool
(package
(name "erlang-covertool")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 12/32] gnu: erlang-covertool: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
c331299dde496ae8dcaa5033d5e0750620868488.1698590244.git.phfrohring@deeplinks.com
Change-Id: I1212ff469a12e926d4728106c15f12b181819e2c
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
gnu/packages/erlang.scm | 21 ---------------------
2 files changed, 21 insertions(+), 21 deletions(-)

Toggle diff (66 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 78f829e9..ae2193f5 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -224,6 +224,27 @@ (define-public erlang-yamerl
(home-page "https://hexdocs.pm/yamerl/")
(license license:bsd-2)))
+(define-public erlang-covertool
+ (package
+ (name "erlang-covertool")
+ (version "2.0.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1p0c1n3nl4063xwi1sv176l1x68xqf07qwvj444a5z888fx6i5aw"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/covertool/covertool")
+ (synopsis "Convert code-coverage data generated by @code{cover} into
+Cobertura XML reports")
+ (description "This package provides a build tool and plugin to convert
+exported Erlang @code{cover} data sets into Cobertura XML reports, which can
+then be feed to the Jenkins Cobertura plug-in.
+
+On @emph{hex.pm}, this plugin was previously called @code{rebar_covertool}.")
+ (license license:bsd-2)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 5ed11c28..55a6edb7 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,27 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-covertool
- (package
- (name "erlang-covertool")
- (version "2.0.4")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1p0c1n3nl4063xwi1sv176l1x68xqf07qwvj444a5z888fx6i5aw"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/covertool/covertool")
- (synopsis "Convert code-coverage data generated by @code{cover} into
-Cobertura XML reports")
- (description "This package provides a build tool and plugin to convert
-exported Erlang @code{cover} data sets into Cobertura XML reports, which can
-then be feed to the Jenkins Cobertura plug-in.
-
-On @emph{hex.pm}, this plugin was previously called @code{rebar_covertool}.")
- (license license:bsd-2)))
-
(define-public erlang-cth-readable
(package
(name "erlang-cth-readable")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 13/32] gnu: erlang-cth-readable: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
7ac66deef86c6e6fa09cb95ac19c01b0bfa18256.1698590244.git.phfrohring@deeplinks.com
Change-Id: I9ce2a8a7250f3176ff149d4fd1c3a9746c95edca
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
gnu/packages/erlang.scm | 21 ---------------------
2 files changed, 21 insertions(+), 21 deletions(-)

Toggle diff (66 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index ae2193f5..86e50656 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -245,6 +245,27 @@ (define-public erlang-covertool
On @emph{hex.pm}, this plugin was previously called @code{rebar_covertool}.")
(license license:bsd-2)))
+(define-public erlang-cth-readable
+ (package
+ (name "erlang-cth-readable")
+ (version "1.5.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "104xgybb6iciy6i28pyyrarqzliddi8kjyq43ajaav7y5si42rb8"))))
+ (build-system rebar-build-system)
+ (propagated-inputs
+ (list erlang-cf))
+ (arguments
+ `(#:tests? #f)) ;; no test-suite in hex-pm package
+ (home-page "https://github.com/ferd/cth_readable")
+ (synopsis "Common Test hooks for more readable logs for Erlang")
+ (description "This package provides an OTP library to be used for CT log
+outputs you want to be readable around all that noise they contain.")
+ (license license:bsd-3)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 55a6edb7..4cc530b7 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,27 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-cth-readable
- (package
- (name "erlang-cth-readable")
- (version "1.5.1")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "104xgybb6iciy6i28pyyrarqzliddi8kjyq43ajaav7y5si42rb8"))))
- (build-system rebar-build-system)
- (propagated-inputs
- (list erlang-cf))
- (arguments
- `(#:tests? #f)) ;; no test-suite in hex-pm package
- (home-page "https://github.com/ferd/cth_readable")
- (synopsis "Common Test hooks for more readable logs for Erlang")
- (description "This package provides an OTP library to be used for CT log
-outputs you want to be readable around all that noise they contain.")
- (license license:bsd-3)))
-
(define-public erlang-erlware-commons
(package
(name "erlang-erlware-commons")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 14/32] gnu: erlang-erlware-commons: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
ffea9377633c0203a8ddf147c959d9da70f94049.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ic2cfcfbd9d3623464200d26412c9af79b861a970
---
gnu/packages/erlang-xyz.scm | 27 +++++++++++++++++++++++++++
gnu/packages/erlang.scm | 27 ---------------------------
2 files changed, 27 insertions(+), 27 deletions(-)

Toggle diff (78 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 86e50656..66a2cd94 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -266,6 +266,33 @@ (define-public erlang-cth-readable
outputs you want to be readable around all that noise they contain.")
(license license:bsd-3)))
+(define-public erlang-erlware-commons
+ (package
+ (name "erlang-erlware-commons")
+ (version "1.6.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "18qam9xdzi74wppb0cj4zc8161i0i8djr79z8662m6d276f2jz5m"))))
+ (build-system rebar-build-system)
+ (propagated-inputs
+ (list erlang-cf))
+ (native-inputs
+ (list git-minimal/pinned)) ;; Required for tests
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (add-before 'check 'check-setup
+ (lambda _
+ (setenv "TERM" "xterm")))))) ; enable color in logs
+ (home-page "https://erlware.github.io/erlware_commons/")
+ (synopsis "Additional standard library for Erlang")
+ (description "Erlware Commons is an Erlware project focused on all aspects
+of reusable Erlang components.")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 4cc530b7..941674c4 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,33 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-erlware-commons
- (package
- (name "erlang-erlware-commons")
- (version "1.6.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "18qam9xdzi74wppb0cj4zc8161i0i8djr79z8662m6d276f2jz5m"))))
- (build-system rebar-build-system)
- (propagated-inputs
- (list erlang-cf))
- (native-inputs
- (list git-minimal/pinned)) ;; Required for tests
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-before 'check 'check-setup
- (lambda _
- (setenv "TERM" "xterm")))))) ; enable color in logs
- (home-page "https://erlware.github.io/erlware_commons/")
- (synopsis "Additional standard library for Erlang")
- (description "Erlware Commons is an Erlware project focused on all aspects
-of reusable Erlang components.")
- (license license:expat)))
-
(define-public erlang-eunit-formatters
(package
(name "erlang-eunit-formatters")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 15/32] gnu: erlang-eunit-formatters: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
af219dd4cee49ab2dd384a533b9bf87ab92a9d63.1698590244.git.phfrohring@deeplinks.com
Change-Id: I10bc54bbf240bc9db3f764408b2a80966cc1221a
---
gnu/packages/erlang-xyz.scm | 16 ++++++++++++++++
gnu/packages/erlang.scm | 16 ----------------
2 files changed, 16 insertions(+), 16 deletions(-)

Toggle diff (56 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 66a2cd94..47434a96 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -293,6 +293,22 @@ (define-public erlang-erlware-commons
of reusable Erlang components.")
(license license:expat)))
+(define-public erlang-eunit-formatters
+ (package
+ (name "erlang-eunit-formatters")
+ (version "0.5.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1jb3hzb216r29x2h4pcjwfmx1k81431rgh5v0mp4x5146hhvmj6n"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/seancribbs/eunit_formatters")
+ (synopsis "Better output for eunit suites")
+ (description "This package provides a better output for Erlang eunits.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 941674c4..ffca507e 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,22 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-eunit-formatters
- (package
- (name "erlang-eunit-formatters")
- (version "0.5.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1jb3hzb216r29x2h4pcjwfmx1k81431rgh5v0mp4x5146hhvmj6n"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/seancribbs/eunit_formatters")
- (synopsis "Better output for eunit suites")
- (description "This package provides a better output for Erlang eunits.")
- (license license:asl2.0)))
-
(define-public erlang-hex-core
(package
(name "erlang-hex-core")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 16/32] gnu: erlang-proper: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
c01ef43dd552adfdcbd9ffb2aa7d459e5afb78da.1698590244.git.phfrohring@deeplinks.com
Change-Id: I8a8e3d16a9b02e53615cf95b336895dc89367ce2
---
gnu/packages/erlang-xyz.scm | 27 +++++++++++++++++++++++++++
gnu/packages/erlang.scm | 27 ---------------------------
2 files changed, 27 insertions(+), 27 deletions(-)

Toggle diff (78 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 47434a96..b83bc6c0 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -293,6 +293,33 @@ (define-public erlang-erlware-commons
of reusable Erlang components.")
(license license:expat)))
+(define-public erlang-proper
+ (package
+ (name "erlang-proper")
+ (version "1.4.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1fwcas4a9kz3w3z1jqdk9lw8822srfjk9lcpvbxkxlsv3115ha0q"))))
+ (build-system rebar-build-system)
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (add-after 'unpack 'disable-covertool
+ ;; no need to generate a coverage report
+ (lambda _
+ (substitute* "rebar.config"
+ (("\\{plugins, \\[covertool\\]\\}\\." _) "")))))))
+ (home-page "https://proper-testing.github.io/")
+ (synopsis "QuickCheck-inspired property-based testing tool for Erlang")
+ (description "PropEr is a tool for the automated, semi-random,
+property-based testing of Erlang programs. It is fully integrated with
+Erlang's type language, and can also be used for the model-based random
+testing of stateful systems.")
+ (license license:gpl3+)))
+
(define-public erlang-eunit-formatters
(package
(name "erlang-eunit-formatters")
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index ffca507e..8d3b682c 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -305,33 +305,6 @@ (define-public erlang-parse-trans
compile-time constant.")
(license license:asl2.0)))
-(define-public erlang-proper
- (package
- (name "erlang-proper")
- (version "1.4.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1fwcas4a9kz3w3z1jqdk9lw8822srfjk9lcpvbxkxlsv3115ha0q"))))
- (build-system rebar-build-system)
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-after 'unpack 'disable-covertool
- ;; no need to generate a coverage report
- (lambda _
- (substitute* "rebar.config"
- (("\\{plugins, \\[covertool\\]\\}\\." _) "")))))))
- (home-page "https://proper-testing.github.io/")
- (synopsis "QuickCheck-inspired property-based testing tool for Erlang")
- (description "PropEr is a tool for the automated, semi-random,
-property-based testing of Erlang programs. It is fully integrated with
-Erlang's type language, and can also be used for the model-based random
-testing of stateful systems.")
- (license license:gpl3+)))
-
(define-public erlang-jsx
(package
(name "erlang-jsx")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 17/32] gnu: erlang-hex-core: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
14a87086ed3815e099c5bc2f641718f31b136939.1698590244.git.phfrohring@deeplinks.com
Change-Id: Id69281bb2ec1847723582a461b0fa87df1c3ace7
---
gnu/packages/erlang-xyz.scm | 26 ++++++++++++++++++++++++++
gnu/packages/erlang.scm | 26 --------------------------
2 files changed, 26 insertions(+), 26 deletions(-)

Toggle diff (76 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index b83bc6c0..2ce2e3f0 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -336,6 +336,32 @@ (define-public erlang-eunit-formatters
(description "This package provides a better output for Erlang eunits.")
(license license:asl2.0)))
+(define-public erlang-hex-core
+ (package
+ (name "erlang-hex-core")
+ (version "0.8.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "06p65hlm29ky03vs3fq3qz6px2ylwp8b0f2y75wdf5cm0kx2332b"))))
+ (build-system rebar-build-system)
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (replace 'check
+ (lambda* (#:key tests? #:allow-other-keys)
+ (when tests?
+ (invoke "rebar3" "as" "test" "proper")))))))
+ (inputs
+ (list erlang-proper erlang-rebar3-proper))
+ (home-page "https://github.com/hexpm/hex_core")
+ (synopsis "Reference implementation of Hex specifications")
+ (description "This package provides the reference implementation of Hex
+specifications.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index 8d3b682c..c509282d 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,32 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-hex-core
- (package
- (name "erlang-hex-core")
- (version "0.8.4")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "06p65hlm29ky03vs3fq3qz6px2ylwp8b0f2y75wdf5cm0kx2332b"))))
- (build-system rebar-build-system)
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (replace 'check
- (lambda* (#:key tests? #:allow-other-keys)
- (when tests?
- (invoke "rebar3" "as" "test" "proper")))))))
- (inputs
- (list erlang-proper erlang-rebar3-proper))
- (home-page "https://github.com/hexpm/hex_core")
- (synopsis "Reference implementation of Hex specifications")
- (description "This package provides the reference implementation of Hex
-specifications.")
- (license license:asl2.0)))
-
(define-public erlang-jsone
(package
(name "erlang-jsone")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 18/32] gnu: erlang-jsx: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
ea5b9984ce387f487f5c7e4755fa15df608bff59.1698590244.git.phfrohring@deeplinks.com
Change-Id: I5d71483d9e00b81f61d3339bbe1195865c05171f
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
gnu/packages/erlang.scm | 17 -----------------
2 files changed, 17 insertions(+), 17 deletions(-)

Toggle diff (58 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 2ce2e3f0..1d7984fb 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -362,6 +362,23 @@ (define-public erlang-hex-core
specifications.")
(license license:asl2.0)))
+(define-public erlang-jsx
+ (package
+ (name "erlang-jsx")
+ (version "3.1.0")
+ (source (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32
+ "1wr7jkxm6nlgvd52xhniav64xr9rml2ngb35rwjwqlqvq7ywhp0c"))))
+ (build-system rebar-build-system)
+ (synopsis "Streaming, evented JSON parsing toolkit")
+ (description
+ "An Erlang application for consuming, producing and manipulating json.")
+ (home-page "https://github.com/talentdeficit/jsx")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c509282d..eeaf7cf0 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -279,23 +279,6 @@ (define-public erlang-parse-trans
compile-time constant.")
(license license:asl2.0)))
-(define-public erlang-jsx
- (package
- (name "erlang-jsx")
- (version "3.1.0")
- (source (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32
- "1wr7jkxm6nlgvd52xhniav64xr9rml2ngb35rwjwqlqvq7ywhp0c"))))
- (build-system rebar-build-system)
- (synopsis "Streaming, evented JSON parsing toolkit")
- (description
- "An Erlang application for consuming, producing and manipulating json.")
- (home-page "https://github.com/talentdeficit/jsx")
- (license license:expat)))
-
(define-public erlang-providers
(package
(name "erlang-providers")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 19/32] gnu: erlang-relx: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
ca09ccea336fa4a03074e7e417f7916d29bb6e3d.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ibeaa35080cf5ef271ce79faa4f1eddc5451acb14
---
gnu/packages/erlang-xyz.scm | 22 ++++++++++++++++++++++
gnu/packages/erlang.scm | 22 ----------------------
2 files changed, 22 insertions(+), 22 deletions(-)

Toggle diff (68 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 1d7984fb..ad56b9d2 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -379,6 +379,28 @@ (define-public erlang-jsx
(home-page "https://github.com/talentdeficit/jsx")
(license license:expat)))
+(define-public erlang-relx
+ (package
+ (name "erlang-relx")
+ (version "4.6.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "02gmfx1vxg9m3mq4njsqhs4972l4nb8m5p1pdcf64g09ccf17y1g"))))
+ (build-system rebar-build-system)
+ (propagated-inputs
+ (list erlang-bbmustache))
+ (home-page "https://erlware.github.io/relx/")
+ (synopsis "Release assembler for Erlang/OTP Releases")
+ (description "Relx assembles releases for an Erlang/OTP release. Given a
+release specification and a list of directories in which to search for OTP
+applications it will generate a release output. That output depends heavily on
+what plugins available and what options are defined, but usually it is simply
+a well configured release directory.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index eeaf7cf0..c4e81aa2 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -297,28 +297,6 @@ (define-public erlang-providers
(description "This package provides an Erlang providers library.")
(license license:asl2.0)))
-(define-public erlang-relx
- (package
- (name "erlang-relx")
- (version "4.6.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "02gmfx1vxg9m3mq4njsqhs4972l4nb8m5p1pdcf64g09ccf17y1g"))))
- (build-system rebar-build-system)
- (propagated-inputs
- (list erlang-bbmustache))
- (home-page "https://erlware.github.io/relx/")
- (synopsis "Release assembler for Erlang/OTP Releases")
- (description "Relx assembles releases for an Erlang/OTP release. Given a
-release specification and a list of directories in which to search for OTP
-applications it will generate a release output. That output depends heavily on
-what plugins available and what options are defined, but usually it is simply
-a well configured release directory.")
- (license license:asl2.0)))
-
(define-public erlang-ssl-verify-fun
(package
(name "erlang-ssl-verify-fun")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 20/32] gnu: erlang-providers: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
61870c1c303646227bd75869b03c6582b0ab2f26.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ic418ef50076311c8f6f49b563710d404d5e39154
---
gnu/packages/erlang-xyz.scm | 35 +++++++++++++++++++++++++++++++++++
gnu/packages/erlang.scm | 35 -----------------------------------
2 files changed, 35 insertions(+), 35 deletions(-)

Toggle diff (94 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index ad56b9d2..65495d68 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -401,6 +401,41 @@ (define-public erlang-relx
a well configured release directory.")
(license license:asl2.0)))
+(define-public erlang-ssl-verify-fun
+ (package
+ (name "erlang-ssl-verify-fun")
+ (version "1.1.6")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1026l1z1jh25z8bfrhaw0ryk5gprhrpnirq877zqhg253x3x5c5x"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/deadtrickster/ssl_verify_fun.erl")
+ (synopsis "SSL verification functions for Erlang")
+ (description "This package provides SSL verification functions for
+Erlang.")
+ (license license:expat)))
+
+(define-public erlang-providers
+ (package
+ (name "erlang-providers")
+ (version "1.9.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "05y0kz3xgx77hzn1l05byaisvmk8bgds7c22hrh0a5ba81sfi1yj"))))
+ (build-system rebar-build-system)
+ (propagated-inputs
+ (list erlang-erlware-commons erlang-getopt))
+ (home-page "https://github.com/tsloughter/providers")
+ (synopsis "Erlang providers library")
+ (description "This package provides an Erlang providers library.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c4e81aa2..c5426381 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -279,41 +279,6 @@ (define-public erlang-parse-trans
compile-time constant.")
(license license:asl2.0)))
-(define-public erlang-providers
- (package
- (name "erlang-providers")
- (version "1.9.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "05y0kz3xgx77hzn1l05byaisvmk8bgds7c22hrh0a5ba81sfi1yj"))))
- (build-system rebar-build-system)
- (propagated-inputs
- (list erlang-erlware-commons erlang-getopt))
- (home-page "https://github.com/tsloughter/providers")
- (synopsis "Erlang providers library")
- (description "This package provides an Erlang providers library.")
- (license license:asl2.0)))
-
-(define-public erlang-ssl-verify-fun
- (package
- (name "erlang-ssl-verify-fun")
- (version "1.1.6")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1026l1z1jh25z8bfrhaw0ryk5gprhrpnirq877zqhg253x3x5c5x"))))
- (build-system rebar-build-system)
- (home-page "https://github.com/deadtrickster/ssl_verify_fun.erl")
- (synopsis "SSL verification functions for Erlang")
- (description "This package provides SSL verification functions for
-Erlang.")
- (license license:expat)))
-
(define-public rebar3
(package
(name "rebar3")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 21/32] gnu: erlang-jsone: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
42027d7f56afbfa7189bbef25b3c1bcb258799e0.1698590244.git.phfrohring@deeplinks.com
Change-Id: I1828e8c85296212540fe5562c1663c18f7585d11
---
gnu/packages/erlang-xyz.scm | 24 ++++++++++++++++++++++++
gnu/packages/erlang.scm | 24 ------------------------
2 files changed, 24 insertions(+), 24 deletions(-)

Toggle diff (72 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 65495d68..ed66aaee 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -436,6 +436,30 @@ (define-public erlang-providers
(description "This package provides an Erlang providers library.")
(license license:asl2.0)))
+(define-public erlang-jsone
+ (package
+ (name "erlang-jsone")
+ (version "1.7.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1gaxiw76syjp3s9rygskm32y9799b917q752rw8bxj3bxq93g8x3"))))
+ (build-system rebar-build-system)
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (add-after 'unpack 'disable-covertool
+ ;; no need to generate a coverage report
+ (lambda _
+ (substitute* "rebar.config"
+ (("\\{project_plugins, \\[covertool\\]\\}\\." _) "")))))))
+ (home-page "https://github.com/sile/jsone/")
+ (synopsis "Erlang JSON Library")
+ (description "An Erlang library for encoding and decoding JSON data.")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index c5426381..b9815901 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,30 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-jsone
- (package
- (name "erlang-jsone")
- (version "1.7.0")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "1gaxiw76syjp3s9rygskm32y9799b917q752rw8bxj3bxq93g8x3"))))
- (build-system rebar-build-system)
- (arguments
- `(#:phases
- (modify-phases %standard-phases
- (add-after 'unpack 'disable-covertool
- ;; no need to generate a coverage report
- (lambda _
- (substitute* "rebar.config"
- (("\\{project_plugins, \\[covertool\\]\\}\\." _) "")))))))
- (home-page "https://github.com/sile/jsone/")
- (synopsis "Erlang JSON Library")
- (description "An Erlang library for encoding and decoding JSON data.")
- (license license:expat)))
-
(define-public erlang-parse-trans
(package
(name "erlang-parse-trans")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 22/32] gnu: erlang-parse-trans: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
e94ac478ab7b3f5c3ec686ee2d976d2dee239a89.1698590244.git.phfrohring@deeplinks.com
Change-Id: I11422aca794584d34ee84ddcf77217245a7ce2b0
---
gnu/packages/erlang-xyz.scm | 23 +++++++++++++++++++++++
gnu/packages/erlang.scm | 23 -----------------------
2 files changed, 23 insertions(+), 23 deletions(-)

Toggle diff (70 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index ed66aaee..6947c9c2 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -460,6 +460,29 @@ (define-public erlang-jsone
(description "An Erlang library for encoding and decoding JSON data.")
(license license:expat)))
+(define-public erlang-parse-trans
+ (package
+ (name "erlang-parse-trans")
+ (version "3.4.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "16p4c2xjrvz16kzpr9pmcvi6nxq6rwckqi9fp0ksibaxwxn402k2"))))
+ (build-system rebar-build-system)
+ (inputs
+ (list erlang-getopt))
+ (home-page "https://github.com/uwiger/parse_trans")
+ (synopsis "Parse transform utilities for Erlang")
+ (description "This package captures some useful patterns in parse
+transformation and code generation for Erlang.
+
+For example generating standardized accessor functions for records or
+evaluating an expression at compile-time and substitute the result as a
+compile-time constant.")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm
index b9815901..d3844933 100644
--- a/gnu/packages/erlang.scm
+++ b/gnu/packages/erlang.scm
@@ -232,29 +232,6 @@ (define-public emacs-erlang
files.")
(license license:asl2.0)))
-(define-public erlang-parse-trans
- (package
- (name "erlang-parse-trans")
- (version "3.4.1")
- (source
- (origin
- (method url-fetch)
- (uri (hexpm-uri name version))
- (sha256
- (base32 "16p4c2xjrvz16kzpr9pmcvi6nxq6rwckqi9fp0ksibaxwxn402k2"))))
- (build-system rebar-build-system)
- (inputs
- (list erlang-getopt))
- (home-page "https://github.com/uwiger/parse_trans")
- (synopsis "Parse transform utilities for Erlang")
- (description "This package captures some useful patterns in parse
-transformation and code generation for Erlang.
-
-For example generating standardized accessor functions for records or
-evaluating an expression at compile-time and substitute the result as a
-compile-time constant.")
- (license license:asl2.0)))
-
(define-public rebar3
(package
(name "rebar3")
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 23/32] gnu: erlang-unicode-util-compat: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
3acfaf7db7ea3cb036afdeba7a73119534b6546e.1698590244.git.phfrohring@deeplinks.com
Change-Id: I8a946fc973f97608109a5e03809c343a1e18e97d
---
gnu/packages/erlang-xyz.scm | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

Toggle diff (29 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 6947c9c2..f0c8521c 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -483,6 +483,22 @@ (define-public erlang-parse-trans
compile-time constant.")
(license license:asl2.0)))
+(define-public erlang-unicode-util-compat
+ (package
+ (name "erlang-unicode-util-compat")
+ (version "0.7.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "08952lw8cjdw8w171lv8wqbrxc4rcmb3jhkrdb7n06gngpbfdvi5"))))
+ (build-system rebar-build-system)
+ (synopsis "Unicode compatibility library for Erlang < 20")
+ (description "Unicode compatibility library for Erlang < 20.")
+ (home-page "https://hex.pm/packages/unicode_util_compat")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 24/32] gnu: erlang-idna: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
ec0ba8e8b45e180f19e21917403869f11ffe8f88.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ifb67d5364658ee59bb8286c3f454ce4f95d0db2b
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

Toggle diff (34 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index f0c8521c..67be758c 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -499,6 +499,27 @@ (define-public erlang-unicode-util-compat
(home-page "https://hex.pm/packages/unicode_util_compat")
(license license:asl2.0)))
+(define-public erlang-idna
+ (package
+ (name "erlang-idna")
+ (version "6.1.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1sjcjibl34sprpf1dgdmzfww24xlyy34lpj7mhcys4j4i6vnwdwj"))))
+ (build-system rebar-build-system)
+ (propagated-inputs (list erlang-unicode-util-compat))
+ (synopsis
+ "Erlang Internationalized Domain Names in Applications (IDNA) protocol")
+ (description
+ "Library to register and look up IDNs in a way
+ that does not require changes to the DNS itself. IDNA is only meant for
+processing domain names, not free text. See: RFC 5891.")
+ (home-page "https://hexdocs.pm/idna/")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 25/32] gnu: erlang-bear: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
4d865f10776015de056b2bfd943b7f28cb4d17d1.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ia04e1bf291f8ca680c0d8c5c54b3c820f263e1cc
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

Toggle diff (30 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 67be758c..ff6254ac 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -520,6 +520,23 @@ (define-public erlang-idna
(home-page "https://hexdocs.pm/idna/")
(license license:expat)))
+(define-public erlang-bear
+ (package
+ (name "erlang-bear")
+ (version "1.0.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1nsri73b50n5v1a8252mm8car84j2b53bq7alq6zz16z3a86fyqm"))))
+ (build-system rebar-build-system)
+ (synopsis "Statistics functions for Erlang")
+ (description
+ "This package provides a set of statistics functions for erlang.")
+ (home-page "https://hex.pm/packages/bear")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 26/32] gnu: erlang-erlang-color: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
073f957f385cb1d7173599bdbc2579cbb9dde902.1698590244.git.phfrohring@deeplinks.com
Change-Id: I914c87d513dbbbe222f852144a706759023044bf
---
gnu/packages/erlang-xyz.scm | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

Toggle diff (29 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index ff6254ac..52a30530 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -537,6 +537,22 @@ (define-public erlang-bear
(home-page "https://hex.pm/packages/bear")
(license license:asl2.0)))
+(define-public erlang-erlang-color
+ (package
+ (name "erlang-erlang-color")
+ (version "1.0.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0f707vxihn3f9m3zxal38ajcihnfcwms77jcax0gbzn8i7jya5vb"))))
+ (build-system rebar-build-system)
+ (synopsis "ANSI colors for your Erlang")
+ (description "ANSI colors for your Erlang.")
+ (home-page "https://hex.pm/packages/erlang_color")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 27/32] gnu: erlang-tdiff: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
aeed477bbdf2b22163d8cf6e1ff9d1618349b470.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ia1214c866f62330a847444254ff47af01a59e760
---
gnu/packages/erlang-xyz.scm | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

Toggle diff (30 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 52a30530..c16ad5aa 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -553,6 +553,23 @@ (define-public erlang-erlang-color
(home-page "https://hex.pm/packages/erlang_color")
(license license:expat)))
+(define-public erlang-tdiff
+ (package
+ (name "erlang-tdiff")
+ (version "0.1.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0xbq7p9ii2kp49ms1kylj92ih2jiwvqwimb8jy4aalljz5lf3hp0"))))
+ (build-system rebar-build-system)
+ (synopsis "Library to compute the difference between two strings")
+ (description
+ "Erlang implementation of the O(ND) differnence algorithm by EUGENE W. MYERS.")
+ (home-page "https://hex.pm/packages/tdiff")
+ (license license:lgpl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 28/32] gnu: erlang-rebar3-ex-doc: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
7366852616997c18841d742916fbb4ea6f11a0aa.1698590244.git.phfrohring@deeplinks.com
Change-Id: I51d485dba18c317bf9b51cfad02809c4e991dedc
---
gnu/packages/erlang-xyz.scm | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

Toggle diff (32 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index c16ad5aa..11b765b7 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -570,6 +570,25 @@ (define-public erlang-tdiff
(home-page "https://hex.pm/packages/tdiff")
(license license:lgpl2.0)))
+(define-public erlang-rebar3-ex-doc
+ (package
+ (name "erlang-rebar3-ex-doc")
+ (version "0.2.21")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0c720shjf03y4slj56q5nxgyhqif0926cs3pvl3zbv1i64qh8wdm"))))
+ (build-system rebar-build-system)
+ (synopsis "rebar3 plugin for generating docs with ex_doc")
+ (description
+ "rebar3_ex_doc is a rebar3 plugin for creating documentation with ex_doc. It
+includes ex_doc as an escript, eliminating the need for Elixir installation or
+compiling ex_doc dependencies.")
+ (home-page "https://hexdocs.pm/rebar3_ex_doc/")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 29/32] gnu: erlang-samovar: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
e62d26cf8a56be98a8f60ddcbec005689aa90a1e.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ia1d6efa1eff8faa6e5e4ea181bde37fe630280b7
---
gnu/packages/erlang-xyz.scm | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

Toggle diff (29 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 11b765b7..bd4f78fe 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -589,6 +589,22 @@ (define-public erlang-rebar3-ex-doc
(home-page "https://hexdocs.pm/rebar3_ex_doc/")
(license license:asl2.0)))
+(define-public erlang-samovar
+ (package
+ (name "erlang-samovar")
+ (version "1.0.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1nfw5vbzcvqzpsahwxz7zjlshg31pa9f306g3hzm1kfx5rsyvry4"))))
+ (build-system rebar-build-system)
+ (synopsis "SEMVER library for Erlang")
+ (description "SEMVER library for Erlang")
+ (home-page "https://hexdocs.pm/samovar/")
+ (license license:isc)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 30/32] gnu: erlang-geas: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
f303240b4a699865db631ad4984a3dd52aa78459.1698590244.git.phfrohring@deeplinks.com
Change-Id: If9d92d8da4b50d0832fb51a8e331b5a30394e81f
---
gnu/packages/erlang-xyz.scm | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

Toggle diff (35 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index bd4f78fe..6642aeea 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -605,6 +605,28 @@ (define-public erlang-samovar
(home-page "https://hexdocs.pm/samovar/")
(license license:isc)))
+(define-public erlang-geas
+ (package
+ (name "erlang-geas")
+ (version "2.7.14")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1maxv5zg2ckrikr8xpxgg9kpfaxvahqilbkl9dl9ibchlgrbj6i4"))))
+ (build-system rebar-build-system)
+ (propagated-inputs (list erlang-samovar))
+ (synopsis
+ "Tool to detect the runnable official Erlang release window for your project")
+ (description
+ "Geas will tell you also what are the offending functions in the beam/source
+files that reduce the available window, if some beam files are compiled native
+and the installed patches and recommend patches that should be installed
+depending your code.")
+ (home-page "https://hexdocs.pm/geas/")
+ (license license:isc)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 31/32] gnu: erlang-covertool: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
c538a4f14350697ca3ab9e767c70277123df1c1f.1698590244.git.phfrohring@deeplinks.com
Change-Id: Ibbac6334f247f86f56386fc53ef176875a13cb2a
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

Toggle diff (34 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 6642aeea..366c5f2c 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -627,6 +627,27 @@ (define-public erlang-geas
(home-page "https://hexdocs.pm/geas/")
(license license:isc)))
+(define-public erlang-covertool
+ (package
+ (name "erlang-covertool")
+ (version "2.0.4")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1p0c1n3nl4063xwi1sv176l1x68xqf07qwvj444a5z888fx6i5aw"))))
+ (build-system rebar-build-system)
+ (home-page "https://github.com/covertool/covertool")
+ (synopsis "Convert code-coverage data generated by @code{cover} into
+Cobertura XML reports")
+ (description
+ "This package provides a build tool and plugin to convert
+exported Erlang @code{cover} data sets into Cobertura XML reports, which can
+then be feed to the Jenkins Cobertura plug-in. On @emph{hex.pm}, this plugin
+was previously called @code{rebar_covertool}.")
+ (license license:bsd-2)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 15:37
[PATCH va3e5ae0f..37252e07 32/32] gnu: erlang-telemetry: moved to erlang-xyz.scm
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
37252e07b4bdf9451b58dcd92f0eab37c3c73fa4.1698590244.git.phfrohring@deeplinks.com
Change-Id: I54cfe6fb244c26c6a226d76ee62a502a72e198a7
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

Toggle diff (34 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 366c5f2c..b43b4403 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -648,6 +648,27 @@ (define-public erlang-covertool
was previously called @code{rebar_covertool}.")
(license license:bsd-2)))
+(define-public erlang-telemetry
+ (package
+ (name "erlang-telemetry")
+ (version "1.2.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1mgyx9zw92g6w8fp9pblm3b0bghwxwwcbslrixq23ipzisfwxnfs"))))
+ (build-system rebar-build-system)
+ (native-inputs (list erlang-covertool))
+ (synopsis "Dynamic dispatching library for metrics and instrumentations")
+ (description
+ "Telemetry is a lightweight library for dynamic dispatching of events, with a
+focus on metrics and instrumentation. Any Erlang or Elixir library can use
+telemetry to emit events. Application code and other libraries can then hook
+into those events and run custom handlers.")
+ (home-page "https://hexdocs.pm/telemetry/")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 18:19
Re: [bug#66801] [PATCH] mix-build-system: draft 1
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)
CAP84DVXKW47uFT9u+5MaiaRXXk42J29xD3dofqhRj=xa4HcxjA@mail.gmail.com
I suppose it would have been better to send each patch individually
after discussion, rather than all at once. My mistake.

Cheers.
Attachment: file
L
L
Liliana Marie Prikler wrote on 29 Oct 2023 19:29
Re: [PATCH va3e5ae0f..37252e07 01/32] rebar-build-system and packages.
7ceab0dcbe069f664377786b5bb531e2196fffc1.camel@gmail.com
Am Sonntag, dem 29.10.2023 um 15:36 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (1 lines)
> [PATCH va3e5ae0f..37252e07 01/32]
The middle should indicate a revision number and an optional branch (as
well as optional WIP and RFC). Since this goes to master (I assume),
it should just be v2, v3, … vN

Toggle quote (77 lines)
> The builder now accepts the `#:sources-erlang` parameter, which
> expects a list of "Source" items. Each "Source" corresponds to the
> source code of a library directory, which is where Erlang looks for
> compiled modules.
> Documentation:
> https://www.erlang.org/doc/man/code#code-path. Each Source is
> installed as a "Checkout", which are local dependencies linked to
> directories managed by rebar. For more information, see
> https://rebar3.org/docs/configuration/dependencies/#checkout-dependencies
> . Lacking checkouts, rebar3 will not compile if there is no network
> access.
>
> Change-Id: Idc3aa8bb204f55d0594c1669399845cd9b9e86ab
> ---
>  guix/build-system/rebar.scm       | 274 +++++++++++++++++++---------
> --
>  guix/build/rebar-build-system.scm | 255 +++++++++++++++++----------
>  2 files changed, 339 insertions(+), 190 deletions(-)
>
> diff --git a/guix/build-system/rebar.scm b/guix/build-
> system/rebar.scm
> index de1294ec..862721ee 100644
> --- a/guix/build-system/rebar.scm
> +++ b/guix/build-system/rebar.scm
> @@ -1,6 +1,7 @@
>  ;;; GNU Guix --- Functional package management for GNU
>  ;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
>  ;;; Copyright © 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
>  ;;;
>  ;;; This file is part of GNU Guix.
>  ;;;
> @@ -18,102 +19,117 @@
>  ;;; along with GNU Guix.  If not, see
> <http://www.gnu.org/licenses/>.
>  
>  (define-module (guix build-system rebar)
> -  #:use-module (guix store)
> -  #:use-module (guix utils)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix build-system)
>    #:use-module (guix gexp)
> -  #:use-module (guix packages)
>    #:use-module (guix monads)
> +  #:use-module (guix packages)
>    #:use-module (guix search-paths)
> -  #:use-module (guix build-system)
> -  #:use-module (guix build-system gnu)
> -  #:export (hexpm-uri
> -            hexpm-package-url
> -            %rebar-build-system-modules
> -            rebar-build
> -            rebar-build-system))
> +  #:use-module (guix store)
> +  #:use-module (guix utils)
> +  #:use-module (ice-9 match)
> +  #:use-module (ice-9 regex)
> +  #:use-module (srfi srfi-1)
> +  #:export (hexpm-uri hexpm-package-url %rebar-build-system-modules
> +                      rebar-build rebar-build-system))
>  
> -;;;
> -;;; Definitions for the hex.pm repository,
> -;;;
> +;; Source
> +;;   A « Source » reprensents the source code to a library
> directory. It is
> +;;   defined as (list <name> <origin>) where: <name> is a string
> representing
> +;;   the name of a library directory and <origin> is an origin as
> defined
> +;;   (guix packages).
> +
> +
> +;; Pattern that an Erlang Guix package name is expected to match.
> +(define pkg-name-re "^erlang-(.*)")
Emacs, Rust, etc. build systems just strip out the prefix. No need to
go all fancy regexpy :)

Toggle quote (60 lines)
> +(define (pkg-name->match name)
> +  "Return the match object from NAME if NAME starts with pkg-name-
> prefix."
> +  (string-match pkg-name-re name))
> +
> +(define (pkg-name? name)
> +  "Test if NAME is the name of an Erlang Guix package."
> +  (or (pkg-name->match name) #f))
>  
> -;; URL and paths from
> -;; https://github.com/hexpm/specifications/blob/master/endpoints.md
> -(define %hexpm-repo-url
> -  (make-parameter "https://repo.hex.pm"))
> +(define (pkg-name->suffix name)
> +  "Return the suffix of the name of an Erlang Guix package."
> +  (regexp-substitute #f (pkg-name->match name) 1))
>  
> -(define hexpm-package-url
> -  (string-append (%hexpm-repo-url) "/tarballs/"))
> +(define* (pkg-name->library-directory-name name #:key (version ""))
> +  "Return the name of the library directory associated with the
> Erlang Guix package name NAME."
> +  (string-append (string-replace-substring (pkg-name->suffix name)
> "-" "_")
> +                 (if (string= version "") "" (string-append "-"
> version))))
> +
> +;; See:
> https://github.com/hexpm/specifications/blob/master/endpoints.md
> +(define hexpm (make-parameter "https://repo.hex.pm"))
> +
> +(define hexpm-tarballs (string-append (hexpm) "/tarballs/"))
>  
>  (define (hexpm-uri name version)
>    "Return a URI string for the package hosted at hex.pm
> corresponding to NAME
> -and VERSION."
> -  (string-append hexpm-package-url name "-" version ".tar"))
> +and VERSION.
>  
> -;;
> -;; Standard build procedure for Erlang packages using Rebar.
> -;;
> +XXX: should a warning be emitted?
> +If NAME is not an Erlang Guix package name, then emit a warning. The
> download
> +will fail if it is not correct anyway."
>  
> -(define %rebar-build-system-modules
> -  ;; Build-side modules imported by default.
> -  `((guix build rebar-build-system)
> -    ,@%gnu-build-system-modules))
> +  (define (warn-about name)
> +    (format #t "AssertionWarning 4dcbff27
> +  Assertion: re matches name.
> +    re = ~a
> +    name = ~a
> +" pkg-name-re name)
> +
> +    name)
???

Toggle quote (15 lines)
>  
> -(define (default-rebar3)
> -  "Return the default Rebar3 package."
> +  (define (name->archive-name name)
> +    (if (pkg-name? name)
> +        (string-append (pkg-name->library-directory-name name
> #:version version) ".tar")
> +        (string-append (warn-about name) "-" version ".tar")))
> +
> +  (string-append hexpm-tarballs (name->archive-name name)))
> +
> +(define (rebar-default)
>    ;; Lazily resolve the binding to avoid a circular dependency.
>    (let ((erlang-mod (resolve-interface '(gnu packages erlang))))
>      (module-ref erlang-mod 'rebar3)))
I suggest not to rename these procedures. default-X reads more
naturally than X-default.

Toggle quote (120 lines)
> -(define (default-erlang)
> -  "Return the default Erlang package."
> +(define (erlang-default)
>    ;; Lazily resolve the binding to avoid a circular dependency.
>    (let ((erlang-mod (resolve-interface '(gnu packages erlang))))
>      (module-ref erlang-mod 'erlang)))
>  
> -(define* (lower name
> -                #:key source inputs native-inputs outputs system
> target
> -                (rebar (default-rebar3))
> -                (erlang (default-erlang))
> -                #:allow-other-keys
> -                #:rest arguments)
> -  "Return a bag for NAME from the given arguments."
> -  (define private-keywords
> -    '(#:target #:rebar #:erlang #:inputs #:native-inputs))
> -
> -  (and (not target)                               ;XXX: no cross-
> compilation
> -       (bag
> -         (name name)
> -         (system system)
> -         (host-inputs `(,@(if source
> -                              `(("source" ,source))
> -                              '())
> -                        ,@inputs))
> -         (build-inputs `(("rebar" ,rebar)
> -                         ("erlang" ,erlang) ;; for escriptize
> -                         ,@native-inputs
> -                         ;; Keep the standard inputs of 'gnu-build-
> system'.
> -                         ,@(standard-packages)))
> -         (outputs outputs)
> -         (build rebar-build)
> -         (arguments (strip-keyword-arguments private-keywords
> arguments)))))
> -
> -(define* (rebar-build name inputs
> -                       #:key
> -                       guile source
> -                       (rebar-flags ''("skip_deps=true" "-vv"))
> -                       (tests? #t)
> -                       (test-target "eunit")
> -                       ;; TODO: install-name  ; default: based on
> guix package name
> -                       (install-profile "default")
> -                       (phases '(@ (guix build rebar-build-system)
> -                                   %standard-phases))
> -                       (outputs '("out"))
> -                       (search-paths '())
> -                       (native-search-paths '())
> -                       (system (%current-system))
> -                       (imported-modules %rebar-build-system-
> modules)
> -                       (modules '((guix build rebar-build-system)
> -                                  (guix build utils))))
> +(define imported-modules
> +  `((guix build rebar-build-system)
> +    ,@%gnu-build-system-modules))
> +
> +(define (input->source input)
> +  "Return a Source associated to the Input INPUT."
> +  (match input
> +    ((name package)
> +     (list (pkg-name->library-directory-name name)
> +           (package-source package)))))
> +
> +(define* (rebar-build name
> +                      inputs
> +                      #:key
> +                      guile
> +                      source
> +                      (rebar-flags ''())
> +                      (tests? #t)
> +                      (test-target "eunit")
> +                      ;; TODO: install-name  ; default: based on
> guix package name
> +                      (install-profile "default")
> +                      (phases '(@ (guix build rebar-build-system)
> +                                  %standard-phases))
> +                      (outputs '("out"))
> +                      (search-paths '())
> +                      (native-search-paths '())
> +                      (system (%current-system))
> +                      (imported-modules imported-modules)
> +                      (modules '((guix build rebar-build-system)
> +                                 (guix build utils)))
> +                      (sources-erlang '()))
>    "Build SOURCE with INPUTS."
>  
>    (define builder
> @@ -122,35 +138,95 @@ (define* (rebar-build name inputs
>            (use-modules #$@(sexp->gexp modules))
>  
>            #$(with-build-variables inputs outputs
> +
>                #~(rebar-build #:source #+source
> -                      #:system #$system
> -                      #:name #$name
> -                      #:rebar-flags #$rebar-flags
> -                      #:tests? #$tests?
> -                      #:test-target #$test-target
> -                      ;; TODO: #:install-name #$install-name
> -                      #:install-profile #$install-profile
> -                      #:phases #$(if (pair? phases)
> -                                     (sexp->gexp phases)
> -                                     phases)
> -                      #:outputs %outputs
> -                      #:search-paths '#$(sexp->gexp
> -                                         (map search-path-
> specification->sexp
> -                                              search-paths))
> -                      #:inputs %build-inputs)))))
> -
> -  (mlet %store-monad ((guile (package->derivation (or guile
> (default-guile))
> -                                                  system #:graft?
> #f)))
> +                             #:sources-erlang '#$sources-erlang
This reeks of the hack that we need for cargo-build-system, except with
a worse variable name. I strongly suggest looking into ways we can do
without it.
Toggle quote (177 lines)
> +                             #:system #$system
> +                             #:name #$name
> +                             #:rebar-flags #$rebar-flags
> +                             #:tests? #$tests?
> +                             #:test-target #$test-target
> +                             ;; TODO: #:install-name #$install-name
> +                             #:install-profile #$install-profile
> +                             #:phases #$(if (pair?
> +                                             phases)
> +                                            (sexp->gexp
> +                                             phases)
> +                                            phases)
> +                             #:outputs %outputs
> +                             #:search-paths '#$(sexp->gexp
> +                                                (map
> +                                                 search-path-
> specification->sexp
> +                                                 search-paths))
> +                             #:inputs
> +                             %build-inputs)))))
> +
> +  (mlet %store-monad
> +      ((guile (package->derivation (or guile
> +                                       (default-guile)) system
> +                                       #:graft? #f)))
> +
>      ;; Note: Always pass #:graft? #f.  Without it, ALLOWED-
> REFERENCES &
>      ;; co. would be interpreted as referring to grafted packages.
> -    (gexp->derivation name builder
> +    (gexp->derivation name
> +                      builder
>                        #:system system
>                        #:target #f
>                        #:graft? #f
>                        #:guile-for-build guile)))
>  
> +(define* (lower name
> +                      #:key
> +                      (erlang (erlang-default))
> +                      inputs
> +                      native-inputs
> +                      outputs
> +                      (rebar (rebar-default))
> +                      source
> +                      system
> +                      target
> +                      #:allow-other-keys #:rest arguments)
> +  "Return a bag for NAME from the given arguments."
> +
> +  (let* ((erlang-packages
> +          (filter (lambda (input)
> +                    (match input
> +                      ((name _) (pkg-name? name))))
> +                  (append inputs native-inputs)))
> +
> +         (erlang-sources (map input->source erlang-packages)))
> +
> +    (define private-keywords
> +      '(#:target #:rebar #:erlang #:inputs #:native-inputs
> #:sources-erlang))
> +
> +    (and (not target) ;XXX: no cross-compilation
> +         (bag (name name)
> +              (system system)
> +              (host-inputs inputs)
> +              (build-inputs `(,@(standard-packages)
> +                              ("erlang" ,erlang)
> +                              ("rebar" ,rebar)
> +                              ,@inputs
> +                              ,@native-inputs))
> +              (outputs outputs)
> +              (build rebar-build)
> +              (arguments (append (list #:sources-erlang erlang-
> sources)
> +                                 (strip-keyword-arguments private-
> keywords
> +                                                         
> arguments)))))))
> +
>  (define rebar-build-system
> -  (build-system
> -    (name 'rebar)
> -    (description "The standard Rebar build system")
> -    (lower lower)))
> +  (build-system (name 'rebar)
> +                (description "The standard Rebar build system")
> +                (lower lower)))
> +
> +
> +;;;
> +;;; Exports
> +;;;
> +
> +(define hexpm-package-url hexpm-tarballs)
> +
> +(define %rebar-build-system-modules imported-modules)
> +
> +
> +;;; rebar.scm ends here
> diff --git a/guix/build/rebar-build-system.scm b/guix/build/rebar-
> build-system.scm
> index fb664228..b68348bd 100644
> --- a/guix/build/rebar-build-system.scm
> +++ b/guix/build/rebar-build-system.scm
> @@ -2,6 +2,7 @@
>  ;;; Copyright © 2016, 2018 Ricardo Wurmus <rekado@elephly.net>
>  ;;; Copyright © 2019 Björn Höfling
> <bjoern.hoefling@bjoernhoefling.de>
>  ;;; Copyright © 2020, 2022 Hartmut Goebel
> <h.goebel@crazy-compilers.com>
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
>  ;;;
>  ;;; This file is part of GNU Guix.
>  ;;;
> @@ -23,125 +24,197 @@ (define-module (guix build rebar-build-system)
>    #:use-module ((guix build utils) #:hide (delete))
>    #:use-module (ice-9 match)
>    #:use-module (ice-9 ftw)
> +  #:use-module (ice-9 string-fun)
> +  #:use-module (ice-9 receive)
> +  #:use-module (ice-9 regex)
>    #:use-module (srfi srfi-1)
>    #:use-module (srfi srfi-26)
> -  #:export (rebar-build
> -            %standard-phases))
> +  #:export (rebar-build %standard-phases))
>  
>  ;;
>  ;; Builder-side code of the standard build procedure for Erlang
> packages using
>  ;; rebar3.
>  ;;
> -;; TODO: Think about whether bindir ("ebin"), libdir ("priv") and
> includedir
> -;; "(include") need to be configurable
> +;; Library directory
> +;;   A « library directory » is a directory where Erlang searches
> for compiled
> +;;   code. Its name should look like: `a_name-1.2.3' where the
> suffix `-1.2.3'
> +;;   is optional. See:
> https://www.erlang.org/doc/man/code#code-path.
> +;;
> +;; Package name
> +;;   A « package name » is the value of the name field of a package
> +;;   definition. It looks like: `prefix-a-name-1.2.3'. See:
> +;;   https://guix.gnu.org/manual/en/html_node/Package-Naming.html
> +;;
> +;; Profile
> +;;   For Rebar3, a « profile » is a name associated to a set of
> configuration
> +;;   settings overriding or complementing the regular configuration.
> See:
> +;;   https://rebar3.org/docs/configuration/profiles
> +;;
> +;; Source
> +;;   A « source » represents the source code associated to a Guix
> package as
> +;;   defined by its `source' field. Here, the data sctructure used
> to
> +;;   represent a source has the form `(list name path)' where `name'
> is a
> +;;   library directory name and `path' is the store path where to
> find the
> +;;   source code.
> +;;
> +;; Checkout
> +;;   A « checkout » is a locally defined dependency related to a
> directory
> +;;   managed by rebar.  See:
> +;;  
> https://rebar3.org/docs/configuration/dependencies/#checkout-dependencies
>  
> -(define %erlang-libdir "/lib/erlang/lib")
> +(define sep "/")
Uhm, did you mean file-name-separator-string from Guile core?

Toggle quote (34 lines)
> -(define* (erlang-depends #:key inputs #:allow-other-keys)
> -  (define input-directories
> -    (match inputs
> -      (((_ . dir) ...)
> -       dir)))
> -  (mkdir-p "_checkouts")
> -
> -  (for-each
> -   (lambda (input-dir)
> -     (let ((elibdir (string-append input-dir %erlang-libdir)))
> -       (when (directory-exists? elibdir)
> -         (for-each
> -          (lambda (dirname)
> -            (let ((dest (string-append elibdir "/" dirname))
> -                  (link (string-append "_checkouts/" dirname)))
> -              (when (not (file-exists? link))
> -                ;; RETHINK: Maybe better copy and make writable to
> avoid some
> -                ;; error messages e.g. when using with rebar3-git-
> vsn.
> -                (symlink dest link))))
> -          (list-directories elibdir)))))
> -   input-directories))
> +;; Where Erlang libraries are installed relative to a package path
> in the store.
> +(define lib-erlang-lib "lib/erlang/lib")
> +
> +(define (list-directories directory)
> +  "Return file names of the sub-directory of DIRECTORY."
> +  (scandir directory
> +           (lambda (file)
> +             (and (not (member file '("." "..")))
> +                  (file-is-directory? (string-append directory sep
> file))))))
We have find-files?
Toggle quote (29 lines)
> +
> +(define* (pkg-name->libdir-name name)
> +  "Return the library name deduced from the Erlang package name
> NAME."
> +  (let* ((suffix (regexp-substitute #f (string-match "^erlang-(.*)"
> name) 1))
> +         (elements (string-split suffix #\-)))
> +    (string-append (string-join (drop-right elements 1) "_") "-"
> (last elements))))
> +
> +(define (libdir-name->prefix name)
> +  "Return the prefix of a library directory name NAME."
> +  (car (string-split name #\-)))
> +
> +(define (rebar-build-dir profile)
> +  "Return the path where rebar builds libraries given the profile
> PROFILE."
> +  (format #f "_build/~a/lib" profile))
> +
> +(define* (pkg-name->build-dir name #:key (profile "default"))
> +  "Return the path of library directory where rebar3 builds code of
> an Erlang package named NAME given the profile PROFILE."
> +  (string-append (rebar-build-dir profile) sep (libdir-name->prefix
> (pkg-name->libdir-name name))))
>  
>  (define* (unpack #:key source #:allow-other-keys)
> -  "Unpack SOURCE in the working directory, and change directory
> within the
> -source.  When SOURCE is a directory, copy
This message was truncated. Download the full message here.
L
L
Liliana Marie Prikler wrote on 29 Oct 2023 20:22
Re: [PATCH va3e5ae0f..37252e07 02/32] gnu: erlang updated.
6b3ad269ac93de275c0f2b2b2b1a52359bab602a.camel@gmail.com
Am Sonntag, dem 29.10.2023 um 15:36 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (9 lines)
> Wrapped Erlang programs (`erl`, `erlc`, `escript`) now prepend
> ERL_LIBS with
> GUIX_ERL_LIBS. Reference:
> https://www.erlang.org/doc/man/code#code-path. The
> `native-search-paths` field in the package specification sets
> GUIX_ERL_LIBS,
> which aggregates all compiled libraries for Erlang and Elixir, akin
> to the
> functionality of GUIX_PYTHONPATH.
You're missing a ChangeLog, plus this patch appears to be making two
changes at once – one described here, the other seemingly stylistic.


Cheers
L
L
Liliana Marie Prikler wrote on 29 Oct 2023 20:25
Re: [PATCH va3e5ae0f..37252e07 03/32] gnu: erlang-certifi: moved to erlang-xyz.scm
76b0596075a2d12407faf6fd3d734e0f4ca69e64.camel@gmail.com
Am Sonntag, dem 29.10.2023 um 15:36 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (1 lines)
> Change-Id: I7491af542af5ffb2d82b5555675f4f7dbef167af
Missing ChangeLog.
Toggle quote (18 lines)
> ---
>  gnu/packages/erlang-xyz.scm | 62
> +++++++++++++++++++++++++++++++++++++
>  gnu/packages/erlang.scm     | 25 +--------------
>  2 files changed, 63 insertions(+), 24 deletions(-)
>  create mode 100644 gnu/packages/erlang-xyz.scm
>
> diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-
> xyz.scm
> new file mode 100644
> index 00000000..444fa648
> --- /dev/null
> +++ b/gnu/packages/erlang-xyz.scm
> @@ -0,0 +1,62 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
> +;;;
Don't forget to carry over all other relevant copyright headers.
Likewise for the following patches.

Cheers
L
L
Liliana Marie Prikler wrote on 29 Oct 2023 20:31
Re: [PATCH va3e5ae0f..37252e07 06/32] gnu: erlang-rebar3-git-vsn: moved to erlang-xyz.scm
23f237231ad267458865ebb4a077d2697bf2d7a6.camel@gmail.com
Am Sonntag, dem 29.10.2023 um 15:36 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (2 lines)
> Change-Id: I5a743e71b2034ba1cfe71fe6121137b3194befed
> ---
Depending on how many packages you want to add, you might want to do an
even stronger split, e.g. erlang-build for rebar and mix, erlang-check,
erlang-WHATEVER, and then erlang-xyz for what doesn't fit into any of
the other categories.

Also missing ChangeLog as with the rest.

I don't see mix in the mix yet. Is this going to be a two series
thing?

Cheers
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 20:42
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVW1Up2mR_qcS72tEoTN=360wzb1=UOS+OyS75zr09LHEA@mail.gmail.com
Thank you for being so responsive ; it's pleasantly surprising.
I will address the mix-build-system in 15 additional commits,
which I will send after incorporating your feedback to prevent any further
errors.
I plan to tackle this tomorrow.

Cheers.
Attachment: file
P
P
Pierre-Henry Fröhring wrote on 29 Oct 2023 23:14
Re: [PATCH va3e5ae0f..37252e07 01/32] rebar-build-system and packages.
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVWZsx4uRTbef6u4=62nPzLdNJi_FjV7XBwrgNYbexh-VQ@mail.gmail.com
Toggle quote (4 lines)
> The middle should indicate a revision number and an optional branch
> (as well as optional WIP and RFC). Since this goes to master (I
> assume), it should just be v2, v3, … vN.

DONE: Ok. If I understood correctly, it means that it should have been
[PATCH v2]. So this time, it will be [PATCH v3].

Toggle quote (3 lines)
> Emacs, Rust, etc., build systems just strip out the prefix. No need
> to go all fancy regexpy :)???

WAITING: Well, it makes the warning message completely explicit, for
example:
?????
? AssertionWarning 4dcbff27
? Assertion: re matches name.
? re = ^erlang-(.*)
? name = something-else
?????
Is it OK if it stays like this?

Toggle quote (3 lines)
> I suggest not renaming these procedures. default-X reads more
> naturally than X-default.

DONE.

Toggle quote (4 lines)
> This reeks of the hack that we need for cargo-build-system, except
> with a worse variable name. I strongly suggest looking into ways we
> can do without it.

WAITING: this idea came from a discussion with jpoiret. See:
the idea you suggest is to use `search-path-as-list' as hinted below. Is
this correct?

Toggle quote (2 lines)
> Uhm, did you mean file-name-separator-string from Guile core?

DONE: Great. That is what I was searching for; I'm not yet familiar with
the standard library.

Toggle quote (2 lines)
> We have find-files?

DONE: replaced.

Toggle quote (2 lines)
> Uhm, how are you improving the status quo here?

WAITING: comment updated with:
?????
? ;; If these directories exist, then no error occurs. So, we make sure
? ;; they exist.
?????
Is this OK?

Toggle quote (4 lines)
> The canonical way is to use (getcwd) as HOME. You could also try
> something like (canonicalize-path "../hexpm-home"). Anyhow, you might
> want to try using a variable that is less global than HOME.

DONE: HOME has been replaced by REBAR_CACHE_DIR.

Toggle quote (3 lines)
> I suggest not using French examples – they are confusing between
> French and German native speakers :)

DONE: « → “, » → ”

Toggle quote (3 lines)
> You might want to look into possible PATH variables or put these
> sources into a special folder so that you can use search-path-as-list.

WAITING: Perhaps an idea:
1) If we require all Erlang packages to have an output “src” something
like: /gnu/store/…elixir-pkg-1.2.3/src/elixir/src/…,
2) then (search-path-as-list '("src/elixir/src")
'("/gnu/store…elixir-pkg-1.2.3" …)) would return
'("/gnu/store…elixir-pkg-1.2.3/src/elixir/src" …) ≡ lst-src.
3) Given lst-src, it would be enough to install each source under
_checkouts, i.e., _checkouts/lib-name/src. It is probably feasible to
retrieve lib-name from somewhere.
What do you think?

Toggle quote (3 lines)
> Also, IIUC, erlang-depends already does something rather similar. Is
> there any reason it's broken for you?

WAITING: Without that (i.e., _checkouts/lib-name/src), rebar3 will not
compile things. Is this a satisfaying explaination?
Attachment: file
L
L
Liliana Marie Prikler wrote on 30 Oct 2023 06:29
(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)(address . 66801@debbugs.gnu.org)
fc4b7ccb31d3bfbf59d41b437c30423e0e451368.camel@gmail.com
Am Sonntag, dem 29.10.2023 um 23:14 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (14 lines)
> n [PATCH v2]. So this time, it will be [PATCH v3].
>
> > Emacs, Rust, etc., build systems just strip out the prefix.  No
> > need to go all fancy regexpy :)???
>
> WAITING: Well, it makes the warning message completely explicit, for
> example:
> ?????
> ? AssertionWarning 4dcbff27
> ?   Assertion: re matches name.
> ?     re = ^erlang-(.*)
> ?     name = something-else
> ?????
> Is it OK if it stays like this?
You can use a shorter error and explain the problem better: 
"~a does not start with \"erlang-\"" name

Toggle quote (29 lines)
>
> > Uhm, how are you improving the status quo here?
>
> WAITING: comment updated with:
> ?????
> ? ;;   If these directories exist, then no error occurs. So, we make
> sure
> ? ;;   they exist.
> ?????
> Is this OK?
>
>
> [...]
> > You might want to look into possible PATH variables or put these
> > sources into a special folder so that you can use search-path-as-
> > list.
>
> WAITING: Perhaps an idea:
> 1) If we require all Erlang packages to have an output “src”
> something
>    like: /gnu/store/…elixir-pkg-1.2.3/src/elixir/src/…,
> 2) then (search-path-as-list '("src/elixir/src")
>    '("/gnu/store…elixir-pkg-1.2.3" …)) would return
>    '("/gnu/store…elixir-pkg-1.2.3/src/elixir/src" …) ≡ lst-src.
> 3) Given lst-src, it would be enough to install each source under
>    _checkouts, i.e., _checkouts/lib-name/src. It is probably feasible
> to
>    retrieve lib-name from somewhere.
> What do you think?
Rather than require, you can add a phase to ensure that this is the
case. I'm not sure whether we should make that an extra output,
however; there might be many packages for which we don't need those
sources and where we do need them, we could potentially add them as
native-inputs.

Another alternative would be to keep the sources in 
lib/erlang/lib/lib-name/src so that it gets symlinked by the phase we
have. Though at that point we can surely go with a less surprising
install directory.

Toggle quote (5 lines)
> > Also, IIUC, erlang-depends already does something rather similar. 
> > Is there any reason it's broken for you?
>
> WAITING: Without that (i.e., _checkouts/lib-name/src), rebar3 will
> not compile things. Is this a satisfaying explaination?
I mean, ideally we would store these things in some other directory,
given that _checkouts/lib-name already contains the precompiled stuff
after erlang-depends. However, if the tooling insists on storing both
in the same place, you could simply amend the existing erlang-depends
phase to
1. Copy instead of symlinking
2. Also copy the sources

Cheers
P
P
Pierre-Henry Fröhring wrote on 30 Oct 2023 13:30
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVV0wThtpDvhKwhY=u4HCcFCvtVbqH35ex_1d1yVqQ3f=g@mail.gmail.com
I've collected your comments in an org-file so that it's easier (at least
for me, but I hope it's the case for you too)
to follow multiple discussions at the same time. I've only included the
ones that are still open to discussion.
The structure should be self-evident. The most important comment may be
Comment 9.
Cheers.

* TODO Comment 4
** LMP
This reeks of the hack that we need for cargo-build-system, except with a
worse variable name. I strongly suggest looking into ways we can do without
it.

** PHF
This idea came from a discussion with jpoiret. See:
you suggest is to use =search-path-as-list= as hinted below (=Comment 9=).
Is this
correct?

* TODO Comment 6
** LMP
Uhm, how are you improving the status quo here?

** PHF
Comment updated with:
#+begin_example
;; If these directories exist, then no error occurs. So, we make sure
;; they exist.
#+end_example
Is this OK?

I don't see how to prevent rebar3 to do that. It's apparently an opened
issue:

* TODO Comment 9
** LMP
You might want to look into possible PATH variables or put these sources
into
a special folder so that you can use search-path-as-list.

** PHF
Perhaps an idea:
1) If we require all Erlang packages to have an output “src” something
like: /gnu/store/…elixir-pkg-1.2.3/src/elixir/src/…,
2) then (search-path-as-list '("src/elixir/src")
'("/gnu/store…elixir-pkg-1.2.3" …)) would return
'("/gnu/store…elixir-pkg-1.2.3/src/elixir/src" …) ≡ lst-src.
3) Given lst-src, it would be enough to install each source under
_checkouts,
i.e., _checkouts/lib-name/src. It is probably feasible to retrieve
lib-name
from somewhere.
What do you think?

** LMP
Rather than require, you can add a phase to ensure that this is the case.
I'm not sure whether we should make that an extra output, however; there
might be many packages for which we don't need those sources and where we do
need them, we could potentially add them as native-inputs.

** PHF
Agreed.

** LMP
Another alternative would be to keep the sources in
=lib/erlang/lib/lib-name/src= so that it gets symlinked by the phase we
have.
Though at that point we can surely go with a less surprising install
directory.

** PHF
Here is the approach taken so far:
1) The objective is to ensure that =mix compile= does not attempt to use the
network and, as a result, fails to compile.
2) For the above to be true, it is necessary to have — at build time — the
sources of all Erlang input packages and install them as checkouts.
3) Thus, the question becomes: How to access all the Erlang package sources
at
build time?
4) One idea was to have the client side of the build code send all the
sources
to the server through the poorly named argument =#:sources-erlang=. This
led
to the current code. It relies on the fact that for a given Erlang
package,
it is possible to access its source in the store, for example,
=/gnu/store/…erlang-kv/erlang-kv.tar=.
5) Instead, you propose modifying the installation process so that sources
are
installed along with the built libraries. The source might be collected
with =search-path-as-list=.

The downside seems to be that the source code is stored twice: first in
the
archive, then in the package.

However, this could lead to a much cleaner method of passing the sources
to
the build-side code, that is, the source code would not be passed through
=arguments=.

I'm sending a patch based on this latter idea. Are you OK with that?

* TODO Comment 10
** LMP
Also, IIUC, erlang-depends already does something rather similar. Is there
any reason it's broken for you?

** PHF
Without that (i.e., _checkouts/lib-name/src), rebar3 will not compile
things. Is this a satisfying explanation?

** LMP
I mean, ideally we would store these things in some other directory,
given that _checkouts/lib-name already contains the precompiled stuff
after erlang-depends. However, if the tooling insists on storing both
in the same place, you could simply amend the existing erlang-depends
phase to:
1. Copy instead of symlinking
2. Also copy the sources

** PHF
If I understand correctly, this should be addressed with the patch from
=Comment 9= section above.
Attachment: file
L
L
Liliana Marie Prikler wrote on 30 Oct 2023 21:40
(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)(address . 66801@debbugs.gnu.org)
683bb1149e6bfd3f1ade1976463a834edc6d16a3.camel@gmail.com
Am Montag, dem 30.10.2023 um 13:30 +0100 schrieb Pierre-Henry Fröhring:
Toggle quote (12 lines)
> [...]
> Comment updated with:
> #+begin_example
> ;; If these directories exist, then no error occurs. So, we make
> sure
> ;; they exist.
> #+end_example
> Is this OK?
>
> I don't see how to prevent rebar3 to do that. It's apparently an
> opened issue:
> https://github.com/erlang/rebar3/issues/1173
I'd recommend sticking with the current flow, however, and either
create those directories unconditionally or inside the 
(when (file-exists? …) …)
In general, don't mix gratuitous "styling" changes into your commits.
Try to keep your edits minimal and reviewable.

Toggle quote (9 lines)
> Here is the approach taken so far:
> 1) The objective is to ensure that =mix compile= does not attempt to
> use the network and, as a result, fails to compile.
> 2) For the above to be true, it is necessary to have — at build time
> — the sources of all Erlang input packages and install them as
> checkouts.
> 3) Thus, the question becomes: How to access all the Erlang package 
> sources at build time?
> [...]
One idea both of us haven't voiced so far is to actually grab these in
the (guix build-system …) code rather than the (guix build …) side and
make the sources available via a mapping. Think package → (package-
source package).

The downsides of this are quite obvious. First, to my knowledge
something like that hasn't been done yet, so there's no reference
point. Second, the (guix build …) side would still need to identify
what's an erlang source. Given our code for the unpack phase, I'd
hazard a guess that this is non-trivial. Thus, even if there's
theoretically a way to not store the same tarball twice, in practice it
doesn't really matter.

You could alternatively also write the sources to a special source
output if and only if one such output is requested via the outputs
field. Again, I'd hazard a guess that this would be a very standard
output for anything that needs to go into mix-build-system and thus not
worth the split after all.

Alternatively² you could patch mix to only look for compiled stuff and
not sources. That would tackle the issue at the root instead of trying
to work around it, with the caveat being that we would need to maintain
this patch ourselves if upstream doesn't accept it.

Cheers
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:21
A minimal set of changes.
CAP84DVUp7gnNP4U_Wqfb-DhX5pBQ7eTObRGkKBVepDitzsk-_Q@mail.gmail.com
Dear Liliana,

Learning from our previous exchanges, I would like to first thank you
for your patience and propose refocusing our conversation on a more
concise set of changes.

I am preparing to send a cover letter as recommended in the "Sending a
Patch Series" section of the Guix manual, accompanied by a couple of
patches. These will contain just enough code to validate the approach
taken, along with a few packages for testing purposes.

If the approach is deemed satisfactory, I will make any necessary
corrections based on your feedback and continue to send more patches
until the Phoenix package can be successfully built.

Cheers.
Attachment: file
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 0/5] build Erlang packages with dependencies
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
cover.1699434044.git.phfrohring@deeplinks.com
Introduction
????????????

• The objective is to introduce a `mix-build-system' for building
Elixir packages.
• It is first necessary to have `rebar-build-system' to build Erlang
packages.
• We start by showing a build procedure using a package named `lager'
that operates without the need for network access.
• We generalize the build procedure to any Erlang package by using
[Checkout Dependencies].
• To align this build procedure with Guix, we ensure that for any
Erlang Guix package, all its dependencies, including the transitive
ones, can be identified.
• We show that the source code for each dependency is retrievable from
the store.
• We modify `rebar.scm' and `rebar-build-system.scm' to build
procedure into Guix.
• The packages defined in `erlang-xyz.scm' serve as the test cases for
this implementation.
• The changes to the Guix source code are minimal. While the primary
goal is to validate the approach, it may be necessary to resolve
stylistic issues or potential bugs.


[Checkout Dependencies]


Bash
????

Rebar3 compiles and tests Lager without network access
??????????????????????????????????????????????????????

There is a directory and an environment such that `rebar3 compile' and
`rebar3 test' compile and test the [lager package] without network
access.



Sources are fetched and unpacked
????????????????????????????????

?????
? #! /usr/bin/env bash
? set -euo pipefail
? IFS=$'\n\t'
?
? tmpdir=$(mktemp -d)
? cd $tmpdir
? tar xf source.tar
? tar xf contents.tar.gz
?????


Dependencies are fetched
????????????????????????

?????
? rebar3 compile
? rebar3 eunit
?????


Checkouts are built
???????????????????

#+begin_src bash mkdir _checkouts mv _build/default/lib/goldrush
_checkouts rm -rf _build #+end_srcè


The directory is built
??????????????????????

?????
? .
? ??? _checkouts
? ?   ??? goldrush
? ?   ??? ebin
? ?   ?   ??? …
? ?   ?   ??? gr_sup.beam
? ?   ??? hex_metadata.config
? ?   ??? LICENSE
? ?   ??? priv
? ?   ?   ??? edoc.css
? ?   ??? README.org
? ?   ??? rebar.config
? ?   ??? rebar.lock
? ?   ??? src
? ?   ??? …
? ?   ??? gr_sup.erl
? ??? CHECKSUM
? ??? contents.tar.gz
? ??? include
? ?   ??? lager.hrl
? ??? LICENSE
? ??? metadata.config
? ??? priv
? ?   ??? edoc.css
? ??? README.md
? ??? rebar.config
? ??? rebar.config.script
? ??? rebar.lock
? ??? source.tar
? ??? src
? ?   ??? …
? ?   ??? lager_util.erl
? ??? VERSION
?
? 9 directories, 73 files
?????


The environment is defined
??????????????????????????

?????
? (specifications->manifest '("coreutils" "rebar3"))
?????


Lager is compiled and tested without network access
???????????????????????????????????????????????????

?????
? guix shell -C -m manifest.scm -- rebar3 compile
? guix shell -C -m manifest.scm -- rebar3 eunit
?????


Erlang can find and use the compiled module
???????????????????????????????????????????

?????
? ERL_LIBS=_build/default/lib erl -noshell -eval 'io:format("~p~n", [code:which(lager)]).' -s init stop
?????

?????
? "_build/default/lib/lager/ebin/lager.beam"
?????


Discussion
??????????

Several observations can be made, and alternative approaches can be
proposed, as listed below. Meanwhile, with the implementation
described above, it becomes feasible to build Erlang packages with
Guix, which is an essential step towards building Elixir packages.


Wasted Computations
???????????????????

This build procedure needs to re-build of all Erlang dependencies for
an Erlang package, even if they have been previously built. This is
due to the `rebar3' build system's refusal to operate without network
access unless the dependencies are checked out. If checked out, it
insists on rebuilding them from sources.


Expensive computations
??????????????????????

For a given Erlang dependency, it is necessary to retreive all its
transitive dependencies which might be expensive to compute. See:
[all-transitive-inputs].


[all-transitive-inputs] <./guix/build-system/rebar.scm::(define
(all-transitive-inputs>


Wasted Space
????????????

The source code for all Erlang dependencies of a specific Erlang
package must be available on the build machine, whereas it might be
assumed that the build artifacts alone would suffice.


Alternatives
????????????

Liliana Marie Pinker has suggested several alternatives listed below.


Store sources along the build artifacts
???????????????????????????????????????

From [issue/66801]:
keep the sources in lib/erlang/lib/lib-name/src so that it
gets symlinked by the phase we have. Though at that point
we can surely go with a less surprising install directory.




Write the sources to a special source output
????????????????????????????????????????????

From [issue/66801]:
You could alternatively also write the sources to a
special source output if and only if one such output is
requested via the outputs field. Again, I'd hazard a
guess that this would be a very standard output for
anything that needs to go into mix-build-system and thus
not worth the split after all.




Patch Rebar3
????????????

From [issue/66801]:
you could patch mix to only look for compiled stuff and
not sources. That would tackle the issue at the root
instead of trying to work around it, with the caveat being
that we would need to maintain this patch ourselves if
upstream doesn't accept it.




Pierre-Henry Fröhring (5):
guix: build-system: rebar: build Erlang packages with dependencies.
gnu: Add erlang-goldrush.
gnu: Add erlang-lager.
gnu: Add erlang-unicode-util-compat.
gnu: Add erlang-idna.

gnu/packages/erlang-xyz.scm | 111 +++++++++++++++
guix/build-system/rebar.scm | 223 ++++++++++++++++++++++--------
guix/build/rebar-build-system.scm | 43 +++---
3 files changed, 300 insertions(+), 77 deletions(-)
create mode 100644 gnu/packages/erlang-xyz.scm


base-commit: 4dfbc536689b07e56aead3dd864b8af54613d091
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 1/5] guix: build-system: rebar: build Erlang packages with dependencies.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
18844f77e7b742e93525ee1faa48e4808bf32b01.1699434044.git.phfrohring@deeplinks.com
Change-Id: Ie221d47fd1c9a766c2e2cdf76460ddfdf65e090d
---
guix/build-system/rebar.scm | 223 ++++++++++++++++++++++--------
guix/build/rebar-build-system.scm | 43 +++---
2 files changed, 189 insertions(+), 77 deletions(-)

Toggle diff (345 lines)
diff --git a/guix/build-system/rebar.scm b/guix/build-system/rebar.scm
index de1294ec..cdff85a6 100644
--- a/guix/build-system/rebar.scm
+++ b/guix/build-system/rebar.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -18,20 +19,120 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix build-system rebar)
- #:use-module (guix store)
- #:use-module (guix utils)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
#:use-module (guix gexp)
- #:use-module (guix packages)
#:use-module (guix monads)
+ #:use-module (guix packages)
#:use-module (guix search-paths)
- #:use-module (guix build-system)
- #:use-module (guix build-system gnu)
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
#:export (hexpm-uri
hexpm-package-url
%rebar-build-system-modules
rebar-build
rebar-build-system))
+
+;;;
+;;; Utils
+;;;
+
+(define (flatten lst) (fold append '() lst))
+
+
+;;;
+;;; Packages
+;;;
+
+(define %erlang-package-prefix "erlang-")
+
+(define (erlang-package-name? name)
+ "Indicates if NAME is an Erlang package name.
+If a package name starts with %erlang-package-prefix, then it is an Erlang package name.
+An Erlang package name must start with %erlang-package-prefix."
+ (string-prefix? %erlang-package-prefix name))
+
+(define (hexpm-name pkg-name)
+ "Given a package name PKG-NAME, returns the corresponding hex.pm package name."
+ (let ((suffix (string-drop pkg-name (string-length %erlang-package-prefix))))
+ (string-replace-substring suffix "-" "_")))
+
+(define (all-transitive-inputs pkg pred)
+ "Given a package PKG and a predicate PRED, return all transitive inputs of PKG
+that match the predicate PRED."
+ (delete-duplicates
+ (append
+ (filter pred (package-transitive-inputs pkg))
+ (filter pred (package-transitive-native-inputs pkg))
+ (filter pred (package-transitive-propagated-inputs pkg)))
+ input=?))
+
+
+;;;
+;;; Input
+;;;
+
+(define (input-mk name package)
+ "Build an Input."
+ (list name package))
+
+(define (input->name input)
+ "Return the name of INPUT."
+ (car input))
+
+(define (input->package input)
+ "Return the package of INPUT."
+ (cadr input))
+
+(define (input=? i1 i2)
+ "Test whether Inputs I1 and I2 are equal."
+ (string=? (input->name i1) (input->name i2)))
+
+(define (erlang-input? input)
+ "Test whether INPUT is an Erlang Input."
+ (erlang-package-name? (input->name input)))
+
+(define (input->all-inputs input pred)
+ "Return the list of implicit satisfying PRED Inputs associated to INPUT, including INPUT."
+ (cons input (all-transitive-inputs (input->package input) pred)))
+
+(define (inputs->all-erlang-inputs erlang-inputs)
+ "Return a list of implicit Erlang Inputs associated to INPUT, including INPUT."
+ (let ((all-inputs (flatten (map (cut input->all-inputs <> erlang-package-name?) erlang-inputs))))
+ (delete-duplicates all-inputs input=?)))
+
+
+;;;
+;;; Source
+;;;
+
+(define (source-mk name origin)
+ "Build a source.
+NAME is an hex.pm package name.
+ORIGIN is an Origin."
+ (list name origin))
+
+(define (source->name source)
+ "Return the name of SOURCE."
+ (car source))
+
+(define (source->origin source)
+ "Return the origin of SOURCE."
+ (cadr source))
+
+(define (source=? s1 s2)
+ "Test whether Sources S1 and S2 are equal."
+ (string=? (source->name s1) (source->name s2)))
+
+(define (input->source input)
+ "Given an Input INPUT, return its associated Source."
+ (source-mk (hexpm-name (input->name input))
+ (package-source (input->package input))))
+
+
;;;
;;; Definitions for the hex.pm repository,
;;;
@@ -44,10 +145,11 @@ (define %hexpm-repo-url
(define hexpm-package-url
(string-append (%hexpm-repo-url) "/tarballs/"))
-(define (hexpm-uri name version)
+(define (hexpm-uri pkg-name version)
"Return a URI string for the package hosted at hex.pm corresponding to NAME
and VERSION."
- (string-append hexpm-package-url name "-" version ".tar"))
+ (let ((name (if (erlang-package-name? pkg-name) (hexpm-name pkg-name) pkg-name)))
+ (string-append hexpm-package-url name "-" version ".tar")))
;;
;; Standard build procedure for Erlang packages using Rebar.
@@ -78,42 +180,50 @@ (define* (lower name
#:rest arguments)
"Return a bag for NAME from the given arguments."
(define private-keywords
- '(#:target #:rebar #:erlang #:inputs #:native-inputs))
-
- (and (not target) ;XXX: no cross-compilation
- (bag
- (name name)
- (system system)
- (host-inputs `(,@(if source
- `(("source" ,source))
- '())
- ,@inputs))
- (build-inputs `(("rebar" ,rebar)
- ("erlang" ,erlang) ;; for escriptize
- ,@native-inputs
- ;; Keep the standard inputs of 'gnu-build-system'.
- ,@(standard-packages)))
- (outputs outputs)
- (build rebar-build)
- (arguments (strip-keyword-arguments private-keywords arguments)))))
+ '(#:target #:rebar #:erlang #:inputs #:native-inputs #:erlang-sources))
+
+ (let* ((inputs-all (append inputs native-inputs))
+ (erlang-inputs (filter erlang-input? inputs-all))
+ (all-erlang-inputs (inputs->all-erlang-inputs erlang-inputs))
+ (all-erlang-sources (map input->source all-erlang-inputs)))
+
+ (and (not target) ;XXX: no cross-compilation
+ (bag
+ (name name)
+ (system system)
+ (host-inputs `(,@(if source
+ `(("source" ,source))
+ '())
+ ,@inputs))
+ (build-inputs `(("rebar" ,rebar)
+ ("erlang" ,erlang) ;; for escriptize
+ ,@inputs
+ ,@native-inputs
+ ;; Keep the standard inputs of 'gnu-build-system'.
+ ,@(standard-packages)))
+ (outputs outputs)
+ (build rebar-build)
+ (arguments (append (list #:erlang-sources all-erlang-sources)
+ (strip-keyword-arguments private-keywords arguments)))))))
(define* (rebar-build name inputs
- #:key
- guile source
- (rebar-flags ''("skip_deps=true" "-vv"))
- (tests? #t)
- (test-target "eunit")
- ;; TODO: install-name ; default: based on guix package name
- (install-profile "default")
- (phases '(@ (guix build rebar-build-system)
- %standard-phases))
- (outputs '("out"))
- (search-paths '())
- (native-search-paths '())
- (system (%current-system))
- (imported-modules %rebar-build-system-modules)
- (modules '((guix build rebar-build-system)
- (guix build utils))))
+ #:key
+ guile source
+ (rebar-flags ''("skip_deps=true" "-vv"))
+ (tests? #t)
+ (test-target "eunit")
+ ;; TODO: install-name ; default: based on guix package name
+ (install-profile "default")
+ (phases '(@ (guix build rebar-build-system)
+ %standard-phases))
+ (outputs '("out"))
+ (search-paths '())
+ (native-search-paths '())
+ (erlang-sources '())
+ (system (%current-system))
+ (imported-modules %rebar-build-system-modules)
+ (modules '((guix build rebar-build-system)
+ (guix build utils))))
"Build SOURCE with INPUTS."
(define builder
@@ -123,21 +233,22 @@ (define* (rebar-build name inputs
#$(with-build-variables inputs outputs
#~(rebar-build #:source #+source
- #:system #$system
- #:name #$name
- #:rebar-flags #$rebar-flags
- #:tests? #$tests?
- #:test-target #$test-target
- ;; TODO: #:install-name #$install-name
- #:install-profile #$install-profile
- #:phases #$(if (pair? phases)
- (sexp->gexp phases)
- phases)
- #:outputs %outputs
- #:search-paths '#$(sexp->gexp
- (map search-path-specification->sexp
- search-paths))
- #:inputs %build-inputs)))))
+ #:system #$system
+ #:name #$name
+ #:rebar-flags #$rebar-flags
+ #:tests? #$tests?
+ #:test-target #$test-target
+ ;; TODO: #:install-name #$install-name
+ #:install-profile #$install-profile
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map search-path-specification->sexp
+ search-paths))
+ #:inputs %build-inputs
+ #:erlang-sources '#$erlang-sources)))))
(mlet %store-monad ((guile (package->derivation (or guile (default-guile))
system #:graft? #f)))
diff --git a/guix/build/rebar-build-system.scm b/guix/build/rebar-build-system.scm
index fb664228..286e4e1a 100644
--- a/guix/build/rebar-build-system.scm
+++ b/guix/build/rebar-build-system.scm
@@ -28,6 +28,13 @@ (define-module (guix build rebar-build-system)
#:export (rebar-build
%standard-phases))
+;;
+;; Utils
+;;
+
+(define sep file-name-separator-string)
+
+
;;
;; Builder-side code of the standard build procedure for Erlang packages using
;; rebar3.
@@ -37,27 +44,20 @@ (define-module (guix build rebar-build-system)
(define %erlang-libdir "/lib/erlang/lib")
-(define* (erlang-depends #:key inputs #:allow-other-keys)
- (define input-directories
- (match inputs
- (((_ . dir) ...)
- dir)))
- (mkdir-p "_checkouts")
-
- (for-each
- (lambda (input-dir)
- (let ((elibdir (string-append input-dir %erlang-libdir)))
- (when (directory-exists? elibdir)
- (for-each
- (lambda (dirname)
- (let ((dest (string-append elibdir "/" dirname))
- (link (string-append "_checkouts/" dirname)))
- (when (not (file-exists? link))
- ;; RETHINK: Maybe better copy and make writable to avoid some
- ;; error messages e.g. when using with rebar3-git-vsn.
- (symlink dest link))))
- (list-directories elibdir)))))
- input-directories))
+(define (configure-environment . _)
+ (setenv "REBAR_CACHE_DIR" (getcwd)))
+
+(define* (erlang-depends #:key erlang-sources #:allow-other-keys)
+ (let ((checkouts "_checkouts"))
+ (mkdir-p checkouts)
+ (for-each (lambda (source)
+ (match source
+ ((name archive)
+ (let ((libdir (string-append checkouts sep name)))
+ (mkdir-p libdir)
+ (with-directory-excursion libdir
+ (unpack #:source archive))))))
+ erlang-sources)))
(define* (unpack #:key source #:allow-other-keys)
"Unpack SOURCE in the working directory, and change directory within the
@@ -134,6 +134,7 @@ (define* (install #:key name outputs
(define %standard-phases
(modify-phases gnu:%standard-phases
(replace 'unpack unpack)
+ (add-after 'unpack 'configure-environment configure-environment)
(delete 'bootstrap)
(delete 'configure)
(add-before 'build 'erlang-depends erlang-depends)
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 2/5] gnu: Add erlang-goldrush.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
a93213f233d9d2f4106a40629cc5b7a3b7f23297.1699434044.git.phfrohring@deeplinks.com
Change-Id: If978f3936375c9391f1655402a4504d708cfa67d
---
gnu/packages/erlang-xyz.scm | 55 +++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 gnu/packages/erlang-xyz.scm

Toggle diff (63 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
new file mode 100644
index 00000000..082af121
--- /dev/null
+++ b/gnu/packages/erlang-xyz.scm
@@ -0,0 +1,55 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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 (gnu packages erlang-xyz)
+ #:use-module ((guix licenses) #:prefix license:)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages)
+ #:use-module (guix build-system rebar)
+ #:use-module (guix download)
+ #:use-module (guix gexp)
+ #:use-module (guix git-download)
+ #:use-module (guix hg-download)
+ #:use-module (guix packages)
+ #:use-module (guix utils)
+ #:use-module (srfi srfi-1)
+ #:use-module (guix git-download)
+ #:use-module (gnu packages version-control)
+ #:use-module (srfi srfi-26))
+
+(define-public erlang-goldrush
+ (package
+ (name "erlang-goldrush")
+ (version "0.1.9")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1ssck5yr7rnrfwzm55pbyi1scgs1sl1xim75h5sj5czwrwl43jwr"))))
+ (build-system rebar-build-system)
+ (synopsis "Erlang event stream processor")
+ (description "Erlang event stream processor")
+ (home-page "https://hex.pm/packages/goldrush")
+ (license license:isc)))
+
+;;;
+;;; Avoid adding new packages to the end of this file. To reduce the chances
+;;; of a merge conflict, place them above by existing packages with similar
+;;; functionality or similar names.
+;;;
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 3/5] gnu: Add erlang-lager.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
a97b7b5d5fb4ea5560816c1937466d1379ede6ba.1699434044.git.phfrohring@deeplinks.com
Change-Id: Iee1182644d57b7cca08afc6078102cc2409ede18
---
gnu/packages/erlang-xyz.scm | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

Toggle diff (32 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 082af121..4ed8099f 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -48,6 +48,25 @@ (define-public erlang-goldrush
(home-page "https://hex.pm/packages/goldrush")
(license license:isc)))
+(define-public erlang-lager
+ (package
+ (name "erlang-lager")
+ (version "3.9.2")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "0a0c6kvc2jman62vrx2l3nx6xqn8s5l1glvf2mk7xjx8hyg4v43z"))))
+ (build-system rebar-build-system)
+ ;; XXX: tests fail.
+ (arguments (list #:tests? #f))
+ (propagated-inputs (list erlang-goldrush))
+ (synopsis "Erlang logging framework")
+ (description "Erlang logging framework")
+ (home-page "https://hexdocs.pm/lager/")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 4/5] gnu: Add erlang-unicode-util-compat.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
88315e12fd0e624d5f41f92fb8f334f4f5332ff0.1699434044.git.phfrohring@deeplinks.com
Change-Id: I15009c5dbe10c48bcdba9a143576122c877974b4
---
gnu/packages/erlang-xyz.scm | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

Toggle diff (29 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 4ed8099f..0c614542 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -67,6 +67,22 @@ (define-public erlang-lager
(home-page "https://hexdocs.pm/lager/")
(license license:asl2.0)))
+(define-public erlang-unicode-util-compat
+ (package
+ (name "erlang-unicode-util-compat")
+ (version "0.7.0")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "08952lw8cjdw8w171lv8wqbrxc4rcmb3jhkrdb7n06gngpbfdvi5"))))
+ (build-system rebar-build-system)
+ (synopsis "Unicode compatibility library for Erlang < 20")
+ (description "Unicode compatibility library for Erlang < 20.")
+ (home-page "https://hex.pm/packages/unicode_util_compat")
+ (license license:asl2.0)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
P
P
Pierre-Henry Fröhring wrote on 8 Nov 2023 10:22
[PATCH 5/5] gnu: Add erlang-idna.
(address . 66801@debbugs.gnu.org)(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)
0ac400beb2e94456ae681c6e2d6e09d5513053e6.1699434044.git.phfrohring@deeplinks.com
Change-Id: Ie747409e9ef1f8a62ebefbc07131fef91e441a67
---
gnu/packages/erlang-xyz.scm | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

Toggle diff (34 lines)
diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm
index 0c614542..fb614505 100644
--- a/gnu/packages/erlang-xyz.scm
+++ b/gnu/packages/erlang-xyz.scm
@@ -83,6 +83,27 @@ (define-public erlang-unicode-util-compat
(home-page "https://hex.pm/packages/unicode_util_compat")
(license license:asl2.0)))
+(define-public erlang-idna
+ (package
+ (name "erlang-idna")
+ (version "6.1.1")
+ (source
+ (origin
+ (method url-fetch)
+ (uri (hexpm-uri name version))
+ (sha256
+ (base32 "1sjcjibl34sprpf1dgdmzfww24xlyy34lpj7mhcys4j4i6vnwdwj"))))
+ (build-system rebar-build-system)
+ (propagated-inputs (list erlang-unicode-util-compat))
+ (synopsis
+ "Erlang Internationalized Domain Names in Applications (IDNA) protocol")
+ (description
+ "Library to register and look up IDNs in a way
+ that does not require changes to the DNS itself. IDNA is only meant for
+processing domain names, not free text. See: RFC 5891.")
+ (home-page "https://hexdocs.pm/idna/")
+ (license license:expat)))
+
;;;
;;; Avoid adding new packages to the end of this file. To reduce the chances
;;; of a merge conflict, place them above by existing packages with similar
--
2.41.0
L
L
Liliana Marie Prikler wrote on 8 Nov 2023 21:40
Re: [PATCH 1/5] guix: build-system: rebar: build Erlang packages with dependencies.
196ea16d78b1f2292b0dd7f3bfae254ae83c496f.camel@gmail.com
Am Mittwoch, dem 08.11.2023 um 10:22 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (2 lines)
> Change-Id: Ie221d47fd1c9a766c2e2cdf76460ddfdf65e090d
> ---
Missing the ChangeLog :)

Also, don't forget to add me to CC so that I can see the changes more
easily.

Toggle quote (51 lines)
>  guix/build-system/rebar.scm       | 223 ++++++++++++++++++++++------
> --
>  guix/build/rebar-build-system.scm |  43 +++---
>  2 files changed, 189 insertions(+), 77 deletions(-)
>
> diff --git a/guix/build-system/rebar.scm b/guix/build-
> system/rebar.scm
> index de1294ec..cdff85a6 100644
> --- a/guix/build-system/rebar.scm
> +++ b/guix/build-system/rebar.scm
> @@ -1,6 +1,7 @@
>  ;;; GNU Guix --- Functional package management for GNU
>  ;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
>  ;;; Copyright © 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
>  ;;;
>  ;;; This file is part of GNU Guix.
>  ;;;
> @@ -18,20 +19,120 @@
>  ;;; along with GNU Guix.  If not, see
> <http://www.gnu.org/licenses/>.
>  
>  (define-module (guix build-system rebar)
> -  #:use-module (guix store)
> -  #:use-module (guix utils)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix build-system)
>    #:use-module (guix gexp)
> -  #:use-module (guix packages)
>    #:use-module (guix monads)
> +  #:use-module (guix packages)
>    #:use-module (guix search-paths)
> -  #:use-module (guix build-system)
> -  #:use-module (guix build-system gnu)
> +  #:use-module (guix store)
> +  #:use-module (guix utils)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (srfi srfi-26)
>    #:export (hexpm-uri
>              hexpm-package-url
>              %rebar-build-system-modules
>              rebar-build
>              rebar-build-system))
>  
> +
> +;;;
> +;;; Utils
> +;;;
> +
> +(define (flatten lst) (fold append '() lst))
You use this procedure once and you can probably replace it with
append-map from SRFI-1.

Toggle quote (30 lines)
> +;;;
> +;;; Packages
> +;;;
> +
> +(define %erlang-package-prefix "erlang-")
> +
> +(define (erlang-package-name? name)
> +  "Indicates if NAME is an Erlang package name.
> +If a package name starts with %erlang-package-prefix, then it is an
> Erlang package name.
> +An Erlang package name must start with %erlang-package-prefix."
> +  (string-prefix? %erlang-package-prefix name))
> +
> +(define (hexpm-name pkg-name)
> +  "Given a package name PKG-NAME, returns the corresponding hex.pm
> package name."
> +  (let ((suffix (string-drop pkg-name (string-length %erlang-
> package-prefix))))
> +    (string-replace-substring suffix "-" "_")))
> +
> +(define (all-transitive-inputs pkg pred)
> +  "Given a package PKG and a predicate PRED, return all transitive
> inputs of PKG
> +that match the predicate PRED."
> +  (delete-duplicates
> +   (append
> +    (filter pred (package-transitive-inputs pkg))
> +    (filter pred (package-transitive-native-inputs pkg))
> +    (filter pred (package-transitive-propagated-inputs pkg)))
> +   input=?))
We already have package-direct-inputs. Instead of matching labels, you
might want to match package names instead anyway.

Toggle quote (16 lines)
> +
> +;;;
> +;;; Input
> +;;;
> +
> +(define (input-mk name package)
> +  "Build an Input."
> +  (list name package))
> +
> +(define (input->name input)
> +  "Return the name of INPUT."
> +  (car input))
> +
> +(define (input->package input)
> +  "Return the package of INPUT."
> +  (cadr input))
You shouldn't define such destructuring procedures. Use (ice-9 match)
where needed.

Toggle quote (3 lines)
> +(define (input=? i1 i2)
> +  "Test whether Inputs I1 and I2 are equal."
> +  (string=? (input->name i1) (input->name i2)))
Yeah, don't compare labels.

Toggle quote (15 lines)
> +(define (erlang-input? input)
> +  "Test whether INPUT is an Erlang Input."
> +  (erlang-package-name? (input->name input)))
> +
> +(define (input->all-inputs input pred)
> +  "Return the list of implicit satisfying PRED Inputs associated to
> INPUT, including INPUT."
> +  (cons input (all-transitive-inputs (input->package input) pred)))
> +
> +(define (inputs->all-erlang-inputs erlang-inputs)
> +  "Return a list of implicit Erlang Inputs associated to INPUT,
> including INPUT."
> +  (let ((all-inputs (flatten (map (cut input->all-inputs <> erlang-
> package-name?) erlang-inputs))))
> +    (delete-duplicates all-inputs input=?)))
The name, arguments, and docstring of this function do not match in any
way. Consider expressing yourself in terms of known Guile functions.

(define (transitive-erlang-inputs inputs)
(define (erlang-inputs inputs)
(filter-map
(match-lambda ((name package . output)
(and (erlang-package-name?) 
(cons* name package output))))
inputs))
(delete-duplicates
(append-map erlang-inputs 
(append-map
package-transitive-inputs
(map cadr inputs)))))

Note that there's almost certainly a smarter way than nesting two
append-maps, but am currently too lazy to look that up.

Toggle quote (27 lines)
> +
> +;;;
> +;;; Source
> +;;;
> +
> +(define (source-mk name origin)
> +  "Build a source.
> +NAME is an hex.pm package name.
> +ORIGIN is an Origin."
> +  (list name origin))
> +
> +(define (source->name source)
> +  "Return the name of SOURCE."
> +  (car source))
> +
> +(define (source->origin source)
> +  "Return the origin of SOURCE."
> +  (cadr source))
> +
> +(define (source=? s1 s2)
> +  "Test whether Sources S1 and S2 are equal."
> +  (string=? (source->name s1) (source->name s2)))
> +
> +(define (input->source input)
> +  "Given an Input INPUT, return its associated Source."
> +  (source-mk (hexpm-name (input->name input))
> +             (package-source (input->package input))))
Again, use ice-9 match instead of manually defining all those
destructuring procedures.

Toggle quote (53 lines)
> +
>  ;;;
>  ;;; Definitions for the hex.pm repository,
>  ;;;
> @@ -44,10 +145,11 @@ (define %hexpm-repo-url
>  (define hexpm-package-url
>    (string-append (%hexpm-repo-url) "/tarballs/"))
>  
> -(define (hexpm-uri name version)
> +(define (hexpm-uri pkg-name version)
>    "Return a URI string for the package hosted at hex.pm
> corresponding to NAME
>  and VERSION."
> -  (string-append hexpm-package-url name "-" version ".tar"))
> +  (let ((name (if (erlang-package-name? pkg-name) (hexpm-name pkg-
> name) pkg-name)))
> +    (string-append hexpm-package-url name "-" version ".tar")))
>  
>  ;;
>  ;; Standard build procedure for Erlang packages using Rebar.
> @@ -78,42 +180,50 @@ (define* (lower name
>                  #:rest arguments)
>    "Return a bag for NAME from the given arguments."
>    (define private-keywords
> -    '(#:target #:rebar #:erlang #:inputs #:native-inputs))
> -
> -  (and (not target)                               ;XXX: no cross-
> compilation
> -       (bag
> -         (name name)
> -         (system system)
> -         (host-inputs `(,@(if source
> -                              `(("source" ,source))
> -                              '())
> -                        ,@inputs))
> -         (build-inputs `(("rebar" ,rebar)
> -                         ("erlang" ,erlang) ;; for escriptize
> -                         ,@native-inputs
> -                         ;; Keep the standard inputs of 'gnu-build-
> system'.
> -                         ,@(standard-packages)))
> -         (outputs outputs)
> -         (build rebar-build)
> -         (arguments (strip-keyword-arguments private-keywords
> arguments)))))
> +    '(#:target #:rebar #:erlang #:inputs #:native-inputs #:erlang-
> sources))
> +
> +  (let* ((inputs-all (append inputs native-inputs))
> +         (erlang-inputs (filter erlang-input? inputs-all))
> +         (all-erlang-inputs (inputs->all-erlang-inputs erlang-
> inputs))
> +         (all-erlang-sources (map input->source all-erlang-inputs)))
Instead of let-binding these, you might want to define a procedure
(erlang-sources inputs native-inputs) and then use that for #:erlang-
sources.

Toggle quote (118 lines)
> +    (and (not target)                   ;XXX: no cross-compilation
> +         (bag
> +           (name name)
> +           (system system)
> +           (host-inputs `(,@(if source
> +                                `(("source" ,source))
> +                                '())
> +                          ,@inputs))
> +           (build-inputs `(("rebar" ,rebar)
> +                           ("erlang" ,erlang) ;; for escriptize
> +                           ,@inputs
> +                           ,@native-inputs
> +                           ;; Keep the standard inputs of 'gnu-
> build-system'.
> +                           ,@(standard-packages)))
> +           (outputs outputs)
> +           (build rebar-build)
> +           (arguments (append (list #:erlang-sources all-erlang-
> sources)
> +                              (strip-keyword-arguments private-
> keywords arguments)))))))
>  
>  (define* (rebar-build name inputs
> -                       #:key
> -                       guile source
> -                       (rebar-flags ''("skip_deps=true" "-vv"))
> -                       (tests? #t)
> -                       (test-target "eunit")
> -                       ;; TODO: install-name  ; default: based on
> guix package name
> -                       (install-profile "default")
> -                       (phases '(@ (guix build rebar-build-system)
> -                                   %standard-phases))
> -                       (outputs '("out"))
> -                       (search-paths '())
> -                       (native-search-paths '())
> -                       (system (%current-system))
> -                       (imported-modules %rebar-build-system-
> modules)
> -                       (modules '((guix build rebar-build-system)
> -                                  (guix build utils))))
> +                      #:key
> +                      guile source
> +                      (rebar-flags ''("skip_deps=true" "-vv"))
> +                      (tests? #t)
> +                      (test-target "eunit")
> +                      ;; TODO: install-name  ; default: based on
> guix package name
> +                      (install-profile "default")
> +                      (phases '(@ (guix build rebar-build-system)
> +                                  %standard-phases))
> +                      (outputs '("out"))
> +                      (search-paths '())
> +                      (native-search-paths '())
> +                      (erlang-sources '())
> +                      (system (%current-system))
> +                      (imported-modules %rebar-build-system-modules)
> +                      (modules '((guix build rebar-build-system)
> +                                 (guix build utils))))
>    "Build SOURCE with INPUTS."
>  
>    (define builder
> @@ -123,21 +233,22 @@ (define* (rebar-build name inputs
>  
>            #$(with-build-variables inputs outputs
>                #~(rebar-build #:source #+source
> -                      #:system #$system
> -                      #:name #$name
> -                      #:rebar-flags #$rebar-flags
> -                      #:tests? #$tests?
> -                      #:test-target #$test-target
> -                      ;; TODO: #:install-name #$install-name
> -                      #:install-profile #$install-profile
> -                      #:phases #$(if (pair? phases)
> -                                     (sexp->gexp phases)
> -                                     phases)
> -                      #:outputs %outputs
> -                      #:search-paths '#$(sexp->gexp
> -                                         (map search-path-
> specification->sexp
> -                                              search-paths))
> -                      #:inputs %build-inputs)))))
> +                             #:system #$system
> +                             #:name #$name
> +                             #:rebar-flags #$rebar-flags
> +                             #:tests? #$tests?
> +                             #:test-target #$test-target
> +                             ;; TODO: #:install-name #$install-name
> +                             #:install-profile #$install-profile
> +                             #:phases #$(if (pair? phases)
> +                                            (sexp->gexp phases)
> +                                            phases)
> +                             #:outputs %outputs
> +                             #:search-paths '#$(sexp->gexp
> +                                                (map search-path-
> specification->sexp
> +                                                     search-paths))
> +                             #:inputs %build-inputs
> +                             #:erlang-sources '#$erlang-sources)))))
>  
>    (mlet %store-monad ((guile (package->derivation (or guile
> (default-guile))
>                                                    system #:graft?
> #f)))
> diff --git a/guix/build/rebar-build-system.scm b/guix/build/rebar-
> build-system.scm
> index fb664228..286e4e1a 100644
> --- a/guix/build/rebar-build-system.scm
> +++ b/guix/build/rebar-build-system.scm
> @@ -28,6 +28,13 @@ (define-module (guix build rebar-build-system)
>    #:export (rebar-build
>              %standard-phases))
>  
> +;;
> +;; Utils
> +;;
> +
> +(define sep file-name-separator-string)
How about no?

Toggle quote (34 lines)
> +
>  ;;
>  ;; Builder-side code of the standard build procedure for Erlang
> packages using
>  ;; rebar3.
> @@ -37,27 +44,20 @@ (define-module (guix build rebar-build-system)
>  
>  (define %erlang-libdir "/lib/erlang/lib")
>  
> -(define* (erlang-depends #:key inputs #:allow-other-keys)
> -  (define input-directories
> -    (match inputs
> -      (((_ . dir) ...)
> -       dir)))
> -  (mkdir-p "_checkouts")
> -
> -  (for-each
> -   (lambda (input-dir)
> -     (let ((elibdir (string-append input-dir %erlang-libdir)))
> -       (when (directory-exists? elibdir)
> -         (for-each
> -          (lambda (dirname)
> -            (let ((dest (string-append elibdir "/" dirname))
> -                  (link (string-append "_checkouts/" dirname)))
> -              (when (not (file-exists? link))
> -                ;; RETHINK: Maybe better copy and make writable to
> avoid some
> -                ;; error messages e.g. when using with rebar3-git-
> vsn.
> -                (symlink dest link))))
> -          (list-directories elibdir)))))
> -   input-directories))
> +(define (configure-environment . _)
> +  (setenv "REBAR_CACHE_DIR" (getcwd)))
How about simply naming this configure, so that you can use replace
instead of add-after + delete below?

Toggle quote (8 lines)
> +(define* (erlang-depends #:key erlang-sources #:allow-other-keys)
> +  (let ((checkouts "_checkouts"))
> +    (mkdir-p checkouts)
> +    (for-each (lambda (source)
> +                (match source
> +                  ((name archive)
> +                   (let ((libdir (string-append checkouts sep
> name)))
Alternatively add a slash (/) to checkouts ;)
Toggle quote (4 lines)
> +                     (mkdir-p libdir)
> +                     (with-directory-excursion libdir
> +                       (unpack #:source archive))))))
> +              erlang-sources)))
This loses the previous erlang-depends logic, which unpackaged the
already compiled packages. I really don't think we should have erlang
be yet another rust that heats up the planet compiling leftpad over and
over again. Can we somehow have that cake?

Toggle quote (12 lines)
>  (define* (unpack #:key source #:allow-other-keys)
>    "Unpack SOURCE in the working directory, and change directory
> within the
> @@ -134,6 +134,7 @@ (define* (install #:key name outputs
>  (define %standard-phases
>    (modify-phases gnu:%standard-phases
>      (replace 'unpack unpack)
> +    (add-after 'unpack 'configure-environment configure-environment)
>      (delete 'bootstrap)
>      (delete 'configure)
>      (add-before 'build 'erlang-depends erlang-depends)

Cheers
P
P
Pierre-Henry Fröhring wrote on 13 Nov 2023 19:58
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVUtUsP7dorLPip2EWgNLEMCfL779BJckzSCniBHF0=PPg@mail.gmail.com
This loses the previous erlang-depends logic, which unpackaged the
already compiled packages. I really don't think we should have
erlang be
yet another rust that heats up the planet compiling leftpad over and
over
again. Can we somehow have that cake?

Okay, perhaps it would have been better to start working on the Mix
building system
and inform you simultaneously, instead of sending patches all at once. So,
let's
start anew.

I have taken into account all of your suggestions and have crafted this
patch
introducing the mix-build-system. Yes, there are ChangeLogs now. Currently,
the
"Machete" package is compiled and tested without repeatedly compiling
leftpad — i.e.,
considering pure Elixir packages up to transitive dependencies, it works as
expected. This is new.

As I'm learning how all this works, I'm not entirely sure that updating the
rebar
build system is absolutely necessary. I suppose we will understand more as
we add an
increasing number of Elixir packages, especially when incorporating Elixir
packages
with Erlang dependencies.

So, here's what's coming up:

1. A patch that introduces the mix-build-system variable.
2. Several patches that introduce Elixir packages, up to elixir-machete,
which is one
of the few packages that includes tests in the tarball.

I guess the next steps are as follows:

1. To determine if the approach is acceptable. Will we boil the world by
compiling
left-pad endlessly?
2. If the approach is deemed acceptable, the next step is to evaluate the
code. Is
the code riddled with delicious regexes?
3. If the first two points are verified, it might be worthwhile to continue
developing this implementation until Phoenix is successfully compiled
and tested
as expected.

For reference, I have attached a file named `mix-build-system.org'.
This file contains a description of a prototype in Bash that
illustrates the approach taken in this patch.

Cheers.
Attachment: file
P
P
Pierre-Henry Fröhring wrote on 13 Nov 2023 21:26
['PATCH v2' 01/14] build-system: Add mix-build-system.
(address . 66801@debbugs.gnu.org)
26ef9c0f4bf2ff942ba2b42e1fadeb6174bbaa6a.1699906775.git.phfrohring@deeplinks.com
* guix/build-system/mix.scm,
* guix/build/mix-build-system.scm: New modules.

Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
---
guix/build-system/mix.scm | 237 +++++++++++++++++++++++++
guix/build/mix-build-system.scm | 303 ++++++++++++++++++++++++++++++++
2 files changed, 540 insertions(+)
create mode 100644 guix/build-system/mix.scm
create mode 100644 guix/build/mix-build-system.scm

Toggle diff (523 lines)
diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
new file mode 100644
index 00000000..ae4407c9
--- /dev/null
+++ b/guix/build-system/mix.scm
@@ -0,0 +1,237 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Standard build procedure for Elixir packages using 'mix'. This is
+;; implemented as an extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define-module (guix build-system mix)
+ #:use-module (gnu packages base)
+ #:use-module (gnu packages elixir)
+ #:use-module (gnu packages elixir-xyz)
+ #:use-module (gnu packages erlang)
+ #:use-module (guix build mix-build-system)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
+ #:use-module (guix gexp)
+ #:use-module (guix monads)
+ #:use-module (guix packages)
+ #:use-module (guix search-paths)
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build-system hexpm-uri))
+
+(define (hexpm-uri name version)
+ "Return the URI where to fetch the sources of a Hex package NAME at VERSION.
+See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
+ (string-append "https://repo.hex.pm/tarballs/"
+ (string-replace-substring (strip-elixir-prefix name) "-" "_")
+ "-" version ".tar"))
+
+(define glibc-utf8-locales
+ (make-glibc-utf8-locales glibc
+ #:locales (list "en_US")
+ #:name "glibc-utf8-locales"))
+
+(define (default-elixir)
+ "Return the default Elixir package."
+ ;; Lazily resolve the binding to avoid a circular dependency.
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir)))
+
+(define imported-modules
+ `((guix build mix-build-system)
+ ,@%gnu-build-system-modules))
+
+(define modules
+ '((guix build mix-build-system)
+ (guix build utils)))
+
+;; The prefix of Elixir packages.
+(define %elixir-prefix "elixir-")
+
+;; The prefix of Erlang packages.
+(define %erlang-prefix "erlang-")
+
+(define (erlang-package? package)
+ "Tell whether PACKAGE is an Erlang package."
+ (string-prefix? %erlang-prefix (package-name package)))
+
+(define (elixir-package? package)
+ "Tell whether PACKAGE is an Elixir package."
+ (string-prefix? %elixir-prefix (package-name package)))
+
+(define (erlang-or-elixir-pkg? package)
+ "Tell whether PACKAGE is an Elixir or an Erlang package."
+ (or (erlang-package? package)
+ (elixir-package? package)))
+
+(define (erlang-or-elixir-input? input)
+ "Tell whether INPUT is an Elixir or an Erlang input."
+ (match input
+ ((_ package)
+ (erlang-or-elixir-pkg? package))))
+
+(define (input=? input1 input2)
+ "Tell whether inputs INPUT1 and INPUT2 are equal."
+ (define pkg1 (match input1 ((_ pkg) pkg)))
+ (define pkg2 (match input2 ((_ pkg) pkg)))
+ (string=? (package-name pkg1) (package-name pkg2)))
+
+;; A number of environment variables specific to the Mix build system are reflected here.
+;; They are documented here: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables.
+;; Other parameters located in mix.exs are defined here:
+;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
+(define* (mix-build name
+ inputs
+ #:key
+ source
+ elixir-X.Y ;The major and minor of Elixir.
+ (tests? #t)
+ (mix-path #f) ;See MIX_PATH.
+ (mix-exs "mix.exs") ;See MIX_EXS.
+ (build-per-environment #t) ;See :build_per_environment.
+ (phases '%standard-phases)
+ (outputs '("out"))
+ (search-paths '())
+ (system (%current-system))
+ (guile #f)
+ (imported-modules imported-modules)
+ (modules modules))
+ "Build SOURCE using Elixir, and with INPUTS."
+
+ ;; Check the documentation of :build_per_environment here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration And
+ ;; "Environments" here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
+ (define mix-environments
+ (if build-per-environment
+ `("prod" ,@(if tests? '("test") '()))
+ '("shared")))
+
+ (define builder
+ (with-imported-modules imported-modules
+ #~(begin
+
+ (use-modules #$@(sexp->gexp modules))
+
+ #$(with-build-variables inputs outputs
+ #~(mix-build #:name #$name
+ #:source #+source
+ #:system #$system
+ #:tests? #$tests?
+ #:mix-path #$mix-path
+ #:mix-exs #$mix-exs
+ #:elixir-X.Y #$elixir-X.Y
+ #:mix-environments '#$mix-environments
+ #:build-per-environment #$build-per-environment
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map
+ search-path-specification->sexp
+ search-paths))
+ #:inputs
+ %build-inputs)))))
+
+ (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
+ system
+ #:graft? #f)))
+ (gexp->derivation name
+ builder
+ #:system system
+ #:graft? #f ;consistent with 'gnu-build'
+ #:target #f
+ #:guile-for-build guile)))
+
+(define* (lower name
+ #:key
+ source
+ (inputs '())
+ (tests? #t)
+ (native-inputs '())
+ (propagated-inputs '())
+ outputs
+ system
+ target
+ (elixir (default-elixir))
+ #:allow-other-keys #:rest arguments)
+ "Return a bag for NAME."
+ (define private-keywords
+ '(#:inputs #:native-inputs #:outputs #:system #:target #:elixir))
+
+ ;; Libraries are compiled using a given version of Elixir. This fact is
+ ;; encoded by the name of a sub-directory like lib/elixir/X.Y. We compute
+ ;; the value of X.Y here which is valid for the whole build.
+ (define elixir-X.Y (version-major+minor (package-version elixir)))
+
+ ;; Elixir depends on a specific version of Erlang, this one.
+ (define erlang (lookup-package-input elixir "erlang"))
+
+ ;; For mix to compile and test a package, it needs to find all inputs,
+ ;; native-inputs and propagated-inputs (including the transitive ones) under
+ ;; _build directories like _build/prod/lib.
+ ;;
+ ;; Given inputs and native-inputs of the package, we need to compute the
+ ;; transitive closure of all Erlang and Elixir propagated inputs and add
+ ;; them to the build inputs.
+ (define all-propagated-inputs
+ ((compose
+ (cut delete-duplicates <> input=?)
+ (cut filter erlang-or-elixir-input? <>)
+ (cut append-map package-transitive-propagated-inputs <>)
+ (cut map cadr <>))
+ (append inputs native-inputs)))
+
+ (define build-inputs
+ `(,@(standard-packages)
+ ("glibc-utf8-locales" ,glibc-utf8-locales)
+ ("erlang" ,erlang)
+ ("rebar3" ,rebar3)
+ ("elixir" ,elixir)
+ ("elixir-hex" ,elixir-hex)
+ ,@all-propagated-inputs
+ ,@inputs
+ ,@native-inputs))
+
+ ;; Some inputs, such as C programs, may be architecture dependent.
+ (define host-inputs (if target inputs '()))
+
+ (bag (name name)
+ (system system)
+ (build-inputs build-inputs)
+ (host-inputs host-inputs)
+ (outputs outputs)
+ (build mix-build)
+ (arguments (append `(#:elixir-X.Y ,elixir-X.Y)
+ (strip-keyword-arguments private-keywords arguments)))))
+
+(define mix-build-system
+ (build-system (name 'mix)
+ (description "The standard Mix build system")
+ (lower lower)))
+
+;;; mix.scm ends here
diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-system.scm
new file mode 100644
index 00000000..86a5db51
--- /dev/null
+++ b/guix/build/mix-build-system.scm
@@ -0,0 +1,303 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Code:
+
+(define-module (guix build mix-build-system)
+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+ #:use-module (guix build utils)
+ #:use-module (ice-9 ftw)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build
+ strip-elixir-prefix
+ %standard-phases))
+
+(define (f-join . paths)
+ "Return a path (a string) formed from joining each component in PATHS (list of strings).
+Example: \"a\" \"b\" \"c\" → \"a/b/c\""
+ (string-join paths file-name-separator-string))
+
+(define (strip-prefix prefix name)
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+;; All Elixir package names start with this prefix. If a package name starts
+;; with this prefix, then it is an Elixir package.
+(define %elixir-prefix "elixir-")
+
+(define (path->elixir-lib path X.Y)
+ "Return the path to the directory within PATH where libraries of an Elixir
+package are installed. Here, X.Y represents the major and minor version
+numbers of Elixir used for compilation."
+ (f-join path "lib" "elixir" X.Y))
+
+(define (elixir-name? name)
+ "Determines if NAME is the name or the label associated to an Elixir
+package."
+ (string-prefix? %elixir-prefix name))
+
+(define (elixir-input? X.Y input)
+ "Determines if the given INPUT is an Elixir input."
+ (match input
+ ((label . path)
+ ;; XXX: The second condition may be enough.
+ (and (elixir-name? label)
+ (directory-exists? (path->elixir-lib path X.Y))))))
+
+(define (strip-elixir-prefix name)
+ "Strip %elixir-prefix from NAME."
+ (strip-prefix %elixir-prefix name))
+
+;; All Erlang package names start with this prefix. If a package name starts
+;; with this prefix, then it is an Erlang package.
+(define %erlang-prefix "erlang-")
+
+(define (path->erlang-lib path)
+ "Return the path of the directory where libraries of an Erlang package are
+installed in the store."
+ (f-join path "lib" "erlang" "lib"))
+
+(define (erlang-name? name)
+ "Determines if NAME is the name or the label associated to an Erlang
+package."
+ (string-prefix? %erlang-prefix name))
+
+(define (erlang-input? input)
+ "Determines if the given INPUT is an Erlang input."
+ (match input
+ ((label . path)
+ ;; XXX: one condition may be enough. Without the first one, the erlang
+ ;; input is considered an input when we just want Erlang packages.
+ (and (erlang-name? label)
+ (directory-exists? (path->erlang-lib path))))))
+
+(define (strip-erlang-prefix name)
+ "Strip %erlang-prefix from NAME."
+ (strip-prefix %erlang-prefix name))
+
+(define (erlang-or-elixir-input? X.Y input)
+ "Determines if the given INPUT is an Erlang or Elixir input."
+ (or (erlang-input? input)
+ (elixir-input? X.Y input)))
+
+(define (snakecase-name name)
+ "Return a snakecase version of NAME."
+ (string-replace-substring (string-downcase name) "-" "_"))
+
+(define (label->library-name label)
+ "Return the library name associated to an input label LABEL."
+ (define stripped-label
+ (cond
+ ((erlang-name? label)
+ (strip-erlang-prefix label))
+ ((elixir-name? label)
+ (strip-elixir-prefix label))
+ (#t (error "Invalid label: expected an Erlang or Elixir label." 'label label))))
+ (snakecase-name stripped-label))
+
+(define (pkg-name->library-name name)
+ "Return the name of the library deduced from the name of the Guix package.
+Example: elixir-a-pkg-1.0.2 → a_pkg
+See: https://www.erlang.org/doc/man/code#code-path"
+ ((compose
+ label->library-name
+ (cut string-join <> "-")
+ (cut drop-right <> 1)
+ (cut string-split <> #\-))
+ name))
+
+;; We fix as many variables as possible.
+;; See: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables
+(define MIX_HOME "MIX_HOME")
+
+(define MIX_ARCHIVES "MIX_ARCHIVES")
+(define (%mix-archives mix-home) (f-join mix-home "archives"))
+(define MIX_BUILD_ROOT "MIX_BUILD_ROOT")
+(define %mix-build-root "_build")
+(define MIX_DEPS_PATH "MIX_DEPS_PATH")
+(define %mix-deps-path "deps")
+(define MIX_PATH "MIX_PATH")
+(define MIX_REBAR3 "MIX_REBAR3")
+(define MIX_EXS "MIX_EXS")
+(define %mix-exs "mix.exs")
+;; XXX: if different architecture are needed, then use this variable.
+(define MIX_TARGET "MIX_TARGET")
+(define MIX_ENV "MIX_ENV")
+(define %mix-env-prod "prod")
+(define %mix-env-test "test")
+(define %mix-env-shared "shared")
+
+;; The name of the directory where compiled libraries by mix are stored.
+(define %mix-lib "lib")
+
+;; Useful because Elixir expects a UTF-8 locale.
+(define LC_ALL "LC_ALL")
+
+(define (mix-build-dir mix-env)
+ "Return the directory where build artifacts are to be installed according to
+en environment MIX-ENV in the current directory."
+ (f-join %mix-build-root mix-env %mix-lib))
+
+(define* (unpack #:key source mix-path #:allow-other-keys)
+ "Unpack SOURCE in the working directory, and change directory within the
+source. When SOURCE is a directory, copy it in a sub-directory of the current
+working directory."
+ (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
+ (gnu-unpack #:source source)
+ (let ((contents "contents.tar.gz"))
+ (when (file-exists? contents)
+ (invoke "tar" "xvf" contents)))))
+
+(define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
+ "Set environment variables."
+ (setenv LC_ALL "en_US.UTF-8")
+ (setenv MIX_HOME (getcwd))
+ (setenv MIX_ARCHIVES (%mix-archives (getenv MIX_HOME)))
+ (setenv MIX_BUILD_ROOT %mix-build-root)
+ (setenv MIX_DEPS_PATH %mix-deps-path)
+ (setenv MIX_PATH (or mix-path ""))
+ (setenv MIX_REBAR3 (f-join (assoc-ref inputs "rebar3") "bin" "rebar3"))
+ (setenv MIX_EXS mix-exs))
+
+(define* (install-hex #:key inputs name elixir-X.Y #:allow-other-keys)
+ "Install Hex."
+ (define hex-name "hex")
+ (define hex-path (assoc-ref inputs "elixir-hex"))
+ (define hex-lib (f-join (path->elixir-lib hex-path elixir-X.Y) hex-name))
+ (define hex-archive-path (f-join (getenv MIX_ARCHIVES) hex-name))
+ (mkdir-p hex-archive-path)
+ (symlink hex-lib (f-join hex-archive-path hex-name)))
+
+(define* (install-dependencies #:key
+ name
+ tests?
+ build-per-environment
+ (inputs '())
+ (native-inputs '())
+ elixir-X.Y
+ mix-environments
+ #:allow-other-keys
+ #:rest rest)
+ "Install dependencies.
+Given an environment mix-env, we define all-inputs(mix-env) as the set of all
+necessary Erlang and Elixir inputs and associated propagated inputs (and
+transitive propagated inputs).
+
+For example, all-inputs(prod) represents all the Erlang and Elixir inputs and
+propagated inputs necessary to compile the Mix project for the prod
+environment.
+
+If dep belongs to all-inputs(mix-env) and its library name is dep-name, then
+it is installed under (f-join (mix-build-dir mix-env) dep-name) as a symbolic
+link."
+ (define (all-inputs mix-env)
+ (define env-inputs
+ (cond
+ ((string=? mix-env %mix-env-prod)
+ inputs)
+ ((member mix-env (list %mix-env-test %mix-env-shared))
+ (append inputs native-inputs))
+ (#t (error "Unexpected Mix environment." 'mix-env mix-env))))
+ (filter (cut erlang-or-elixir-input? elixir-X.Y <>) env-inputs))
+
+ (define (install-input mix-env input)
+ (let ((dir (mix-build-dir mix-env)))
+ (mkdir-p dir)
+ (match input
+ ((label . path)
+ (let ((lib-name (label->library-name label)))
+ (symlink
+ (f-join (path->elixir-lib path elixir-X.Y) lib-name)
+ (f-join dir lib-name)))))))
+
+ (define (install-inputs mix-env)
+ (for-each (cut install-input mix-env <>)
+ (all-inputs mix-env)))
+
+ (for-each install-inputs mix-environments))
+
+(define* (build #:key mix-environments #:allow-other-keys)
+ "Builds the Mix project."
+ (define (compile mix-env)
+ (setenv MIX_ENV mix-env)
+ (invoke "mix" "compile" "--no-deps-check"))
+ (for-each compile mix-environments))
+
+(define* (check #:key (tests? #t) #:allow-other-keys)
+ "Test the Mix project."
+ (if tests?
+ (invoke "mix" "test" "--no-deps-check")
+ (format #t "tests? = ~a~%" tests?)))
+
+(define* (remove-mix-dirs . _)
+ "Remove all .mix/ directories.
+We do not want to copy them to the installation directory."
+ (define mix-dirs
+ (find-files "."
+ (file-name-predicate "\\.mix$")
+ #:directories? #t))
+ (for-each delete-file-recursively mix-dirs))
+
+(define* (install #:key
+ inputs
+ outputs
+ name
+ build-per-environment
+ elixir-X.Y
+ #:allow-other-keys)
+ "Install build artifacts in the store."
+ (define lib-name (pkg-name->library-name name))
+
+ (define
This message was truncated. Download the full message here.
L
L
Liliana Marie Prikler wrote on 13 Nov 2023 22:22
dff0d773a3d24e50760ff49d79dea1b1599d4ec5.camel@gmail.com
Am Montag, dem 13.11.2023 um 21:26 +0100 schrieb Pierre-Henry Fröhring:
Toggle quote (55 lines)
> * guix/build-system/mix.scm,
> * guix/build/mix-build-system.scm: New modules.
>
> Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
> ---
>  guix/build-system/mix.scm       | 237 +++++++++++++++++++++++++
>  guix/build/mix-build-system.scm | 303
> ++++++++++++++++++++++++++++++++
>  2 files changed, 540 insertions(+)
>  create mode 100644 guix/build-system/mix.scm
>  create mode 100644 guix/build/mix-build-system.scm
>
> diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
> new file mode 100644
> index 00000000..ae4407c9
> --- /dev/null
> +++ b/guix/build-system/mix.scm
> @@ -0,0 +1,237 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
> +;;;
> +;;; 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/>.
> +
> +;; Commentary:
> +;;
> +;; Standard build procedure for Elixir packages using 'mix'.  This
> is
> +;; implemented as an extension of 'gnu-build-system'.
> +;;
> +;; Code:
> +
> +(define-module (guix build-system mix)
> +  #:use-module (gnu packages base)
> +  #:use-module (gnu packages elixir)
> +  #:use-module (gnu packages elixir-xyz)
> +  #:use-module (gnu packages erlang)
You probably want to resolve those imports rather than use-modules
them.
Toggle quote (60 lines)
> +  #:use-module (guix build mix-build-system)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix build-system)
> +  #:use-module (guix gexp)
> +  #:use-module (guix monads)
> +  #:use-module (guix packages)
> +  #:use-module (guix search-paths)
> +  #:use-module (guix store)
> +  #:use-module (guix utils)
> +  #:use-module (ice-9 match)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (srfi srfi-26)
> +  #:export (mix-build-system hexpm-uri))
> +
> +(define (hexpm-uri name version)
> +  "Return the URI where to fetch the sources of a Hex package NAME
> at VERSION.
> +See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
> +  (string-append "https://repo.hex.pm/tarballs/"
> +                 (string-replace-substring (strip-elixir-prefix
> name) "-" "_")
> +                 "-" version ".tar"))
> +
> +(define glibc-utf8-locales
> +  (make-glibc-utf8-locales glibc
> +                           #:locales (list "en_US")
> +                           #:name "glibc-utf8-locales"))
> +
> +(define (default-elixir)
> +  "Return the default Elixir package."
> +  ;; Lazily resolve the binding to avoid a circular dependency.
> +  (let ((elixir (resolve-interface '(gnu packages elixir))))
> +    (module-ref elixir 'elixir)))
> +
> +(define imported-modules
> +  `((guix build mix-build-system)
> +    ,@%gnu-build-system-modules))
> +
> +(define modules
> +  '((guix build mix-build-system)
> +    (guix build utils)))
> +
> +;; The prefix of Elixir packages.
> +(define %elixir-prefix "elixir-")
> +
> +;; The prefix of Erlang packages.
> +(define %erlang-prefix "erlang-")
> +
> +(define (erlang-package? package)
> +  "Tell whether PACKAGE is an Erlang package."
> +  (string-prefix? %erlang-prefix (package-name package)))
> +
> +(define (elixir-package? package)
> +  "Tell whether PACKAGE is an Elixir package."
> +  (string-prefix? %elixir-prefix (package-name package)))
> +
> +(define (erlang-or-elixir-pkg? package)
> +  "Tell whether PACKAGE is an Elixir or an Erlang package."
> +  (or (erlang-package? package)
> +      (elixir-package? package)))
You can simplify these five variables into one to three (three being
quite many already depending on whether you'll actually use the smaller
ones).

Toggle quote (5 lines)
> +(define (erlang-or-elixir-input? input)
> +  "Tell whether INPUT is an Elixir or an Erlang input."
> +  (match input
> +    ((_ package)
> +     (erlang-or-elixir-pkg? package))))
Skip.

Toggle quote (5 lines)
> +(define (input=? input1 input2)
> +  "Tell whether inputs INPUT1 and INPUT2 are equal."
> +  (define pkg1 (match input1 ((_ pkg) pkg)))
> +  (define pkg2 (match input2 ((_ pkg) pkg)))
> +  (string=? (package-name pkg1) (package-name pkg2)))
Again, checking for label equivalence is a bad idea.

Toggle quote (206 lines)
> +;; A number of environment variables specific to the Mix build
> system are reflected here.
> +;; They are documented here:
> https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables.
> +;; Other parameters located in mix.exs are defined here:
> +;;
> https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
> +(define* (mix-build name
> +                    inputs
> +                    #:key
> +                    source
> +                    elixir-X.Y ;The major and minor of Elixir.
> +                    (tests? #t)
> +                    (mix-path #f) ;See MIX_PATH.
> +                    (mix-exs "mix.exs") ;See MIX_EXS.
> +                    (build-per-environment #t) ;See
> :build_per_environment.
> +                    (phases '%standard-phases)
> +                    (outputs '("out"))
> +                    (search-paths '())
> +                    (system (%current-system))
> +                    (guile #f)
> +                    (imported-modules imported-modules)
> +                    (modules modules))
> +  "Build SOURCE using Elixir, and with INPUTS."
> +
> +  ;; Check the documentation of :build_per_environment here:
> +  ;;
> https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration A
> nd
> +  ;; "Environments" here:
> +  ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
> +  (define mix-environments
> +    (if build-per-environment
> +        `("prod" ,@(if tests? '("test") '()))
> +        '("shared")))
> +
> +  (define builder
> +    (with-imported-modules imported-modules
> +      #~(begin
> +
> +          (use-modules #$@(sexp->gexp modules))
> +
> +          #$(with-build-variables inputs outputs
> +              #~(mix-build #:name #$name
> +                           #:source #+source
> +                           #:system #$system
> +                           #:tests? #$tests?
> +                           #:mix-path #$mix-path
> +                           #:mix-exs #$mix-exs
> +                           #:elixir-X.Y #$elixir-X.Y
> +                           #:mix-environments '#$mix-environments
> +                           #:build-per-environment #$build-per-
> environment
> +                           #:phases #$(if (pair? phases)
> +                                          (sexp->gexp phases)
> +                                          phases)
> +                           #:outputs %outputs
> +                           #:search-paths '#$(sexp->gexp
> +                                              (map
> +                                               search-path-
> specification->sexp
> +                                               search-paths))
> +                           #:inputs
> +                           %build-inputs)))))
> +
> +  (mlet %store-monad ((guile (package->derivation (or guile
> (default-guile))
> +                                                  system
> +                                                  #:graft? #f)))
> +    (gexp->derivation name
> +                      builder
> +                      #:system system
> +                      #:graft? #f       ;consistent with 'gnu-build'
> +                      #:target #f
> +                      #:guile-for-build guile)))
> +
> +(define* (lower name
> +                #:key
> +                source
> +                (inputs '())
> +                (tests? #t)
> +                (native-inputs '())
> +                (propagated-inputs '())
> +                outputs
> +                system
> +                target
> +                (elixir (default-elixir))
> +                #:allow-other-keys #:rest arguments)
> +  "Return a bag for NAME."
> +  (define private-keywords
> +    '(#:inputs #:native-inputs #:outputs #:system #:target
> #:elixir))
> +
> +  ;; Libraries are compiled using a given version of Elixir. This
> fact is
> +  ;; encoded by the name of a sub-directory like lib/elixir/X.Y. We
> compute
> +  ;; the value of X.Y here which is valid for the whole build.
> +  (define elixir-X.Y (version-major+minor (package-version elixir)))
> +
> +  ;; Elixir depends on a specific version of Erlang, this one.
> +  (define erlang (lookup-package-input elixir "erlang"))
> +
> +  ;; For mix to compile and test a package, it needs to find all
> inputs,
> +  ;; native-inputs and propagated-inputs (including the transitive
> ones) under
> +  ;; _build directories like _build/prod/lib.
> +  ;;
> +  ;; Given inputs and native-inputs of the package, we need to
> compute the
> +  ;; transitive closure of all Erlang and Elixir propagated inputs
> and add
> +  ;; them to the build inputs.
> +  (define all-propagated-inputs
> +    ((compose
> +      (cut delete-duplicates <> input=?)
> +      (cut filter erlang-or-elixir-input? <>)
> +      (cut append-map package-transitive-propagated-inputs <>)
> +      (cut map cadr <>))
> +     (append inputs native-inputs)))
> +
> +  (define build-inputs
> +    `(,@(standard-packages)
> +      ("glibc-utf8-locales" ,glibc-utf8-locales)
> +      ("erlang" ,erlang)
> +      ("rebar3" ,rebar3)
> +      ("elixir" ,elixir)
> +      ("elixir-hex" ,elixir-hex)
> +      ,@all-propagated-inputs
> +      ,@inputs
> +      ,@native-inputs))
> +
> +  ;; Some inputs, such as C programs, may be architecture dependent.
> +  (define host-inputs (if target inputs '()))
> +
> +  (bag (name name)
> +       (system system)
> +       (build-inputs build-inputs)
> +       (host-inputs host-inputs)
> +       (outputs outputs)
> +       (build mix-build)
> +       (arguments (append `(#:elixir-X.Y ,elixir-X.Y)
> +                          (strip-keyword-arguments private-keywords
> arguments)))))
> +
> +(define mix-build-system
> +  (build-system (name 'mix)
> +                (description "The standard Mix build system")
> +                (lower lower)))
> +
> +;;; mix.scm ends here
> diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-
> system.scm
> new file mode 100644
> index 00000000..86a5db51
> --- /dev/null
> +++ b/guix/build/mix-build-system.scm
> @@ -0,0 +1,303 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
> +;;;
> +;;; 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/>.
> +
> +;; Commentary:
> +;;
> +;; Code:
> +
> +(define-module (guix build mix-build-system)
> +  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
> +  #:use-module (guix build utils)
> +  #:use-module (ice-9 ftw)
> +  #:use-module (ice-9 match)
> +  #:use-module (ice-9 regex)
> +  #:use-module (ice-9 string-fun)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (srfi srfi-26)
> +  #:export (mix-build
> +            strip-elixir-prefix
> +            %standard-phases))
> +
> +(define (f-join . paths)
> +  "Return a path (a string) formed from joining each component in
> PATHS (list of strings).
> +Example: \"a\" \"b\" \"c\" → \"a/b/c\""
> +  (string-join paths file-name-separator-string))
It is wiser to write these out as regular string-appends.

Toggle quote (5 lines)
> +(define (strip-prefix prefix name)
> +  "Return NAME without the prefix PREFIX."
> +  (if (string-prefix? prefix name)
> +      (string-drop name (string-length prefix))
> +      name))
I'm pretty sure we have a function looking like this somewhere, but I
can't recall its name atm.

Toggle quote (4 lines)
> +;; All Elixir package names start with this prefix. If a package
> name starts
> +;; with this prefix, then it is an Elixir package.
> +(define %elixir-prefix "elixir-")
Useless magic constant.
Toggle quote (8 lines)
> +
> +(define (path->elixir-lib path X.Y)
> +  "Return the path to the directory within PATH where libraries of
> an Elixir
> +package are installed. Here, X.Y represents the major and minor
> version
> +numbers of Elixir used for compilation."
> +  (f-join path "lib" "elixir" X.Y))
Is path itself ever useful here or does it simply point to the store?
This can likely be simplified to 
(define (elixir-lib version)
(string-append "/lib/elixir/" version))

Toggle quote (5 lines)
> +(define (elixir-name? name)
> +  "Determines if NAME is the name or the label associated to an
> Elixir
> +package."
> +  (string-prefix? %elixir-prefix name))
Useless use of magic constant.
Toggle quote (8 lines)
> +
> +(define (elixir-input? X.Y input)
> +  "Determines if the given INPUT is an Elixir input."
> +  (match input
> +    ((label . path)
> +     ;; XXX: The second condition may be enough.
> +     (and (elixir-name? label)
> +          (directory-exists? (path->elixir-lib path X.Y))))))
Ahem, search-path-as-list.
Also, leaking the version is kinda bad, API-wise.

Toggle quote (35 lines)
> +(define (strip-elixir-prefix name)
> +  "Strip %elixir-prefix from NAME."
> +  (strip-prefix %elixir-prefix name))
>
> +;; All Erlang package names start with this prefix. If a package
> name starts
> +;; with this prefix, then it is an Erlang package.
> +(define %erlang-prefix "erlang-")
> +
> +(define (path->erlang-lib path)
> +  "Return the path of the directory where libraries of an Erlang
> package are
> +installed in the store."
> +  (f-join path "lib" "erlang" "lib"))
> +
> +(define (erlang-name? name)
> +  "Determines if NAME is the name or the label associated to an
> Erlang
> +package."
> +  (string-prefix? %erlang-prefix name))
> +
> +(define (erlang-input? input)
> +  "Determines if the given INPUT is an Erlang input."
> +  (match input
> +    ((label . path)
> +     ;; XXX: one condition may be enough. Without the first one, the
> erlang
> +     ;; input is considered an input when we just want Erlang
> packages.
> +     (and (erlang-name? label)
> +          (directory-exists? (path->erlang-lib path))))))
> +
> +(define (strip-erlang-prefix name)
> +  "Strip %erlang-prefix from NAME."
> +  (strip-prefix %erlang-prefix name))
Duplicated boilerplate for neither fun nor profit.

Toggle quote (4 lines)
> +(define (erlang-or-elixir-input? X.Y input)
> +  "Determines if the given INPUT is an Erlang or Elixir input."
> +  (or (erlang-input? input)
> +      (elixir-input? X.Y input)))
Leak, leak, leak.
Toggle quote (16 lines)
> +
> +(define (snakecase-name name)
> +  "Return a snakecase version of NAME."
> +  (string-replace-substring (string-downcase name) "-" "_"))
> +
> +(define (label->library-name label)
> +  "Return the library name associated to an input label LABEL."
> +  (define stripped-label
> +    (cond
> +     ((erlang-name? label)
> +      (strip-erlang-prefix label))
> +     ((elixir-name? label)
> +      (strip-elixir-prefix label))
> +     (#t (error "Invalid label: expected an Erlang or Elixir label."
> 'label label))))
> +  (snakecase-name stripped-label))
Don't rely on labels.

Toggle quote (34 lines)
> +(define (pkg-name->library-name name)
> +  "Return the name of the library deduced from the name of the Guix
> package.
> +Example: elixir-a-pkg-1.0.2 → a_pkg
> +See: https://www.erlang.org/doc/man/code#code-path"
> +  ((compose
> +    label->library-name
> +    (cut string-join <> "-")
> +    (cut drop-right <> 1)
> +    (cut string-split <> #\-))
> +   name))
> +
> +;; We fix as many variables as possible.
> +;; See:
> https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables
> +(define MIX_HOME "MIX_HOME")
> +
> +(define MIX_ARCHIVES "MIX_ARCHIVES")
> +(define (%mix-archives mix-home) (f-join mix-home "archives"))
> +(define MIX_BUILD_ROOT "MIX_BUILD_ROOT")
> +(define %mix-build-root "_build")
> +(define MIX_DEPS_PATH "MIX_DEPS_PATH")
> +(define %mix-deps-path "deps")
> +(define MIX_PATH "MIX_PATH")
> +(define MIX_REBAR3 "MIX_REBAR3")
> +(define MIX_EXS "MIX_EXS")
> +(define %mix-exs "mix.exs")
> +;; XXX: if different architecture are needed, then use this
> variable.
> +(define MIX_TARGET "MIX_TARGET")
> +(define MIX_ENV "MIX_ENV")
> +(define %mix-env-prod "prod")
> +(define %mix-env-test "test")
> +(define %mix-env-shared "shared")
Gratuitous definitions are gratuitous.

Toggle quote (74 lines)
> +;; The name of the directory where compiled libraries by mix are
> stored.
> +(define %mix-lib "lib")
> +
> +;; Useful because Elixir expects a UTF-8 locale.
> +(define LC_ALL "LC_ALL")
> +
> +(define (mix-build-dir mix-env)
> +  "Return the directory where build artifacts are to be installed
> according to
> +en environment MIX-ENV in the current directory."
> +  (f-join %mix-build-root mix-env %mix-lib))
> +
> +(define* (unpack #:key source mix-path #:allow-other-keys)
> +  "Unpack SOURCE in the working directory, and change directory
> within the
> +source.  When SOURCE is a directory, copy it in a sub-directory of
> the current
> +working directory."
> +  (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
> +    (gnu-unpack #:source source)
> +    (let ((contents "contents.tar.gz"))
> +      (when (file-exists? contents)
> +        (invoke "tar" "xvf" contents)))))
> +
> +(define* (configure #:key inputs mix-path mix-exs #:allow-other-
> keys)
> +  "Set environment variables."
> +  (setenv LC_ALL "en_US.UTF-8")
> +  (setenv MIX_HOME (getcwd))
> +  (setenv MIX_ARCHIVES (%mix-archives (getenv MIX_HOME)))
> +  (setenv MIX_BUILD_ROOT %mix-build-root)
> +  (setenv MIX_DEPS_PATH %mix-deps-path)
> +  (setenv MIX_PATH (or mix-path ""))
> +  (setenv MIX_REBAR3 (f-join (assoc-ref inputs "rebar3") "bin"
> "rebar3"))
> +  (setenv MIX_EXS mix-exs))
> +
> +(define* (install-hex #:key inputs name elixir-X.Y #:allow-other-
> keys)
> +  "Install Hex."
> +  (define hex-name "hex")
> +  (define hex-path (assoc-ref inputs "elixir-hex"))
> +  (define hex-lib (f-join (path->elixir-lib hex-path elixir-X.Y)
> hex-name))
> +  (define hex-archive-path (f-join (getenv MIX_ARCHIVES) hex-name))
> +  (mkdir-p hex-archive-path)
> +  (symlink hex-lib (f-join hex-archive-path hex-name)))
> +
> +(define* (install-dependencies #:key
> +                               name
> +                               tests?
> +                               build-per-environment
> +                               (inputs '())
> +                               (native-inputs '())
> +                               elixir-X.Y
> +                               mix-environments
> +                               #:allow-other-keys
> +                               #:rest rest)
> +  "Install dependencies.
> +Given an environment mix-env, we define all-inputs(mix-env) as the
> set of all
> +necessary Erlang and Elixir inputs and associated propagated inputs
> (and
> +transitive propagated inputs).
> +
> +For example, all-inputs(prod) represents all the Erlang and Elixir
> inputs and
> +propagated inputs necessary to compile the Mix project for the prod
> +environment.
> +
> +If dep belongs to all-inputs(mix-env) and its library name is dep-
> name, then
> +it is installed under (f-j
This message was truncated. Download the full message here.
P
P
Pierre-Henry Fröhring wrote on 14 Nov 2023 11:37
(address . 66801@debbugs.gnu.org)(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)
CAP84DVWe4R7bLtQAakVVrB234i06DcOZDerr9RvWbTxzTA-h7w@mail.gmail.com
Toggle quote (8 lines)
> > +(define-module (guix build-system mix)
> > + #:use-module (gnu packages base)
> > + #:use-module (gnu packages elixir)
> > + #:use-module (gnu packages elixir-xyz)
> > + #:use-module (gnu packages erlang)
> You probably want to resolve those imports rather than use-modules
> them.

You mean something like this?
#+begin_src scheme
(define-module (guix build-system mix)
#:use-module ((gnu packages base) #:select (glibc
make-glibc-utf8-locales))
#:use-module ((gnu packages elixir) #:select (elixir elixir-hex))
#:use-module ((gnu packages erlang) #:select (rebar3))
#+end_src

I have moved `elixir-hex' to elixir.scm to avoid a circular dependency.


Toggle quote (7 lines)
> > +(define (input=? input1 input2)
> > + "Tell whether inputs INPUT1 and INPUT2 are equal."
> > + (define pkg1 (match input1 ((_ pkg) pkg)))
> > + (define pkg2 (match input2 ((_ pkg) pkg)))
> > + (string=? (package-name pkg1) (package-name pkg2)))
> Again, checking for label equivalence is a bad idea.

OK, after reading a bit more about Guile, I understand that `equal?'
is what should be used here, right? The intent is to remove duplicated
inputs in the code below:

#+begin_src scheme
(define all-propagated-inputs
((compose
(cut delete-duplicates <> equal?) ;<-- Here
(cut filter erlang-or-elixir-input? <>)
(cut append-map package-transitive-propagated-inputs <>)
(cut map cadr <>))
(append inputs native-inputs)))
#+end_src


Toggle quote (10 lines)
> > +(define (elixir-input? X.Y input)
> > + "Determines if the given INPUT is an Elixir input."
> > + (match input
> > + ((label . path)
> > + ;; XXX: The second condition may be enough.
> > + (and (elixir-name? label)
> > + (directory-exists? (path->elixir-lib path X.Y))))))
> Ahem, search-path-as-list.
> Also, leaking the version is kinda bad, API-wise.

Does this mean that build artifacts should be installed under
`$out/lib/elixir/$libname` instead of `$out/lib/elixir/X.Y/$libname`?


Cheers
Attachment: file
L
L
Liliana Marie Prikler wrote on 14 Nov 2023 18:53
f5c259698bf3525efc0f1dc497b71292e3498878.camel@gmail.com
Am Dienstag, dem 14.11.2023 um 11:37 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (19 lines)
> > > +(define-module (guix build-system mix)
> > > +  #:use-module (gnu packages base)
> > > +  #:use-module (gnu packages elixir)
> > > +  #:use-module (gnu packages elixir-xyz)
> > > +  #:use-module (gnu packages erlang)
> > You probably want to resolve those imports rather than use-modules
> > them.
>
> You mean something like this?
> #+begin_src scheme
> (define-module (guix build-system mix)
>   #:use-module ((gnu packages base) #:select (glibc make-glibc-utf8-
> locales))
>   #:use-module ((gnu packages elixir) #:select (elixir elixir-hex))
>   #:use-module ((gnu packages erlang) #:select (rebar3))
> #+end_src
>
> I have moved `elixir-hex' to elixir.scm to avoid a circular
> dependency.
No. Look at all the other build systems. None of them use submodules
of (gnu packages), for a good reason.

Toggle quote (20 lines)
> > > +(define (input=? input1 input2)
> > > +  "Tell whether inputs INPUT1 and INPUT2 are equal."
> > > +  (define pkg1 (match input1 ((_ pkg) pkg)))
> > > +  (define pkg2 (match input2 ((_ pkg) pkg)))
> > > +  (string=? (package-name pkg1) (package-name pkg2)))
> > Again, checking for label equivalence is a bad idea.
>
> OK, after reading a bit more about Guile, I understand that `equal?'
> is what should be used here, right? The intent is to remove
> duplicated inputs in the code below:
>
> #+begin_src scheme
> (define all-propagated-inputs
>     ((compose
>       (cut delete-duplicates <> equal?) ;<-- Here
>       (cut filter erlang-or-elixir-input? <>)
>       (cut append-map package-transitive-propagated-inputs <>)
>       (cut map cadr <>))
>      (append inputs native-inputs)))
> #+end_src
Yep, that would work. Note that delete-duplicates is O(n^2), though.
We have a little bit of code where it's done in (I assume) O(n*log(n))
with vhashes.

Toggle quote (13 lines)
>
> > > +(define (elixir-input? X.Y input)
> > > +  "Determines if the given INPUT is an Elixir input."
> > > +  (match input
> > > +    ((label . path)
> > > +     ;; XXX: The second condition may be enough.
> > > +     (and (elixir-name? label)
> > > +          (directory-exists? (path->elixir-lib path X.Y))))))
> > Ahem, search-path-as-list.
> > Also, leaking the version is kinda bad, API-wise.
>
> Does this mean that build artifacts should be installed under
> `$out/lib/elixir/$libname` instead of `$out/lib/elixir/X.Y/$libname`?
Not necessarily, but you want a different way of building
$out/lib/elixir/X.Y/ that doesn't leak through the function signature.

Btw. I think that you're resolving transitive inputs twice; once on the
build system code and once by fattening the outputs. You probably only
need either of those, not both.

Cheers
P
P
Pierre-Henry Fröhring wrote on 15 Nov 2023 13:40
Fwd: ['PATCH v2' 01/14] build-system: Add mix-build-system.
(address . 66801@debbugs.gnu.org)
CAP84DVU3-2hQeOLYJP7yfFHswCsZg5z1d06xGr5phN3-JY7QgQ@mail.gmail.com
Toggle quote (1 lines)
> No. Look at all the other build systems. None of them use submodules of
(gnu
Toggle quote (2 lines)
> packages), for a good reason.

Ok, I see. It would introduce circular dependencies. By "resolve," you
mean something like: ~(resolve-interface '(gnu packages yyy))~. So, in
our case it means:
#+begin_src scheme
(define (default-glibc-utf8-locales)
(let* ((base (resolve-interface '(gnu packages base)))
(glibc (module-ref base 'glibc))
(make-glibc-utf8-locales (module-ref base
'make-glibc-utf8-locales)))
(make-glibc-utf8-locales glibc #:locales (list "en_US"))))

(define (default-elixir-hex)
(let ((elixir (resolve-interface '(gnu packages elixir))))
(module-ref elixir 'elixir-hex)))

(define (default-rebar3)
(let ((erlang (resolve-interface '(gnu packages erlang))))
(module-ref erlang 'rebar3)))
#+end_src

Then:
#+begin_src scheme
(define* (lower name
#:key
(elixir (default-elixir))
(elixir-hex (default-elixir-hex))
(glibc-utf8-locales (default-glibc-utf8-locales))
(rebar3 (default-rebar3))
#:allow-other-keys #:rest arguments)
…)
#+end_src

Is this correct?


Toggle quote (1 lines)
> Not necessarily, but you want a different way of building
$out/lib/elixir/X.Y/
Toggle quote (2 lines)
> that doesn't leak through the function signature.

Following ~python-build-system.scm~, it means something like:
#+begin_src scheme
(define (elixir-version elixir)
(let* ((version (last (string-split elixir #\-)))
(components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor ".")))

(define (install-dir inputs outputs)
"Return the path of the current output's Elixir library."
(let ((out (assoc-ref outputs "out"))
(elixir (assoc-ref inputs "elixir")))
(string-append out "/lib/elixir/" (elixir-version elixir))))
#+end_src

Is this correct?


Toggle quote (1 lines)
> Btw. I think that you're resolving transitive inputs twice; once on the
build
Toggle quote (1 lines)
> system code and once by fattening the outputs. You probably only need
either
Toggle quote (2 lines)
> of those, not both.

Ah. Propagated inputs are propagated. Who would have thought? So, this is
not necessary:
#+begin_src scheme
(define* (lower …)
(define all-propagated-inputs
((compose
(cut delete-duplicates <> equal?)
(cut filter erlang-or-elixir-input? <>)
(cut append-map package-transitive-propagated-inputs <>)
(cut map cadr <>))
(append inputs native-inputs)))

(define build-inputs
`(…
,@all-propagated-inputs
,@inputs
,@native-inputs))

(bag …
(build-inputs build-inputs)
…))
#+end_src
I've just removed ~all-propagated-inputs~ and all packages build just fine.

Is this what you meant?


Toggle quote (1 lines)
> Yep, that would work. Note that delete-duplicates is O(n^2), though. We
have
Toggle quote (1 lines)
> a little bit of code where it's done in (I assume) O(n*log(n)) with
vhashes.

If ~all-propagated-inputs~ is removed, then the discussion of this comment
is
closed.
Attachment: file
P
P
Pierre-Henry Fröhring wrote on 15 Nov 2023 10:57
Re: ['PATCH v2' 01/14] build-system: Add mix-build-system.
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVUTAYKXQgc4hAZ5hbWsmCf7GxyZJnrKw755ApWmBJknsA@mail.gmail.com
Toggle quote (1 lines)
> No. Look at all the other build systems. None of them use submodules of
(gnu
Toggle quote (2 lines)
> packages), for a good reason.

Ok, I see. It would introduce circular dependencies. By "resolve," you
mean something like: ~(resolve-interface '(gnu packages yyy))~. So, in
our case it means:
#+begin_src scheme
(define (default-glibc-utf8-locales)
(let* ((base (resolve-interface '(gnu packages base)))
(glibc (module-ref base 'glibc))
(make-glibc-utf8-locales (module-ref base
'make-glibc-utf8-locales)))
(make-glibc-utf8-locales glibc #:locales (list "en_US"))))

(define (default-elixir-hex)
(let ((elixir (resolve-interface '(gnu packages elixir))))
(module-ref elixir 'elixir-hex)))

(define (default-rebar3)
(let ((erlang (resolve-interface '(gnu packages erlang))))
(module-ref erlang 'rebar3)))
#+end_src

Then:
#+begin_src scheme
(define* (lower name
#:key
(elixir (default-elixir))
(elixir-hex (default-elixir-hex))
(glibc-utf8-locales (default-glibc-utf8-locales))
(rebar3 (default-rebar3))
#:allow-other-keys #:rest arguments)
…)
#+end_src

Is this correct?


Toggle quote (1 lines)
> Not necessarily, but you want a different way of building
$out/lib/elixir/X.Y/
Toggle quote (2 lines)
> that doesn't leak through the function signature.

Following ~python-build-system.scm~, it means something like:
#+begin_src scheme
(define (elixir-version elixir)
(let* ((version (last (string-split elixir #\-)))
(components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor ".")))

(define (install-dir inputs outputs)
"Return the path of the current output's Elixir library."
(let ((out (assoc-ref outputs "out"))
(elixir (assoc-ref inputs "elixir")))
(string-append out "/lib/elixir/" (elixir-version elixir)
"/site-packages")))
#+end_src

Is this correct?


Toggle quote (1 lines)
> Btw. I think that you're resolving transitive inputs twice; once on the
build
Toggle quote (1 lines)
> system code and once by fattening the outputs. You probably only need
either
Toggle quote (2 lines)
> of those, not both.

Ah. Propagated inputs are propagated. Who would have thought? So, this is
not necessary:
#+begin_src scheme
(define* (lower …)
(define all-propagated-inputs
((compose
(cut delete-duplicates <> equal?)
(cut filter erlang-or-elixir-input? <>)
(cut append-map package-transitive-propagated-inputs <>)
(cut map cadr <>))
(append inputs native-inputs)))

(define build-inputs
`(…
,@all-propagated-inputs
,@inputs
,@native-inputs))

(bag …
(build-inputs build-inputs)
…))
#+end_src
I've just removed ~all-propagated-inputs~ and all packages build just fine.

Is this what you meant?


Toggle quote (1 lines)
> Yep, that would work. Note that delete-duplicates is O(n^2), though. We
have
Toggle quote (1 lines)
> a little bit of code where it's done in (I assume) O(n*log(n)) with
vhashes.

If ~all-propagated-inputs~ is removed, then the discussion of this comment
is
closed.
Attachment: file
P
P
Pierre-Henry Fröhring wrote on 15 Nov 2023 10:59
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVW5RrrFDH-uZi9vfbqdt06o1D3V6298AxcJRNSvg-nW4g@mail.gmail.com
Correction: (string-append out "/lib/elixir/" (elixir-version elixir)
"/site-packages") -> (string-append out "/lib/elixir/" (elixir-version
elixir))
Attachment: file
L
L
Liliana Marie Prikler wrote on 15 Nov 2023 19:36
(name . Pierre-Henry Fröhring)(address . phfrohring@deeplinks.com)(address . 66801@debbugs.gnu.org)
bb5fc93d6861df11f02176187223922b7c6ca607.camel@gmail.com
Am Mittwoch, dem 15.11.2023 um 10:57 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (40 lines)
> > No.  Look at all the other build systems.  None of them use
> > submodules of (gnu
> > packages), for a good reason.
>
> Ok, I see. It would introduce circular dependencies. By "resolve,"
> you
> mean something like: ~(resolve-interface '(gnu packages yyy))~. So,
> in
> our case it means:
> #+begin_src scheme
> (define (default-glibc-utf8-locales)
>   (let* ((base (resolve-interface '(gnu packages base)))
>          (glibc (module-ref base 'glibc))
>          (make-glibc-utf8-locales (module-ref base 'make-glibc-utf8-
> locales)))
>     (make-glibc-utf8-locales glibc #:locales (list "en_US"))))
>
> (define (default-elixir-hex)
>   (let ((elixir (resolve-interface '(gnu packages elixir))))
>     (module-ref elixir 'elixir-hex)))
>
> (define (default-rebar3)
>   (let ((erlang (resolve-interface '(gnu packages erlang))))
>     (module-ref erlang 'rebar3)))
> #+end_src
>
> Then:
> #+begin_src scheme
> (define* (lower name
>                 #:key
>                 (elixir (default-elixir))
>                 (elixir-hex (default-elixir-hex))
>                 (glibc-utf8-locales (default-glibc-utf8-locales))
>                 (rebar3 (default-rebar3))
>                 …
>                 #:allow-other-keys #:rest arguments)
>   …)
> #+end_src
>
> Is this correct?
You shouldn't need to provide glibc-utf8-locales this way (there's
already a variable for it IIRC), but yeah.

Toggle quote (21 lines)
> > Not necessarily, but you want a different way of building
> > $out/lib/elixir/X.Y/
> > that doesn't leak through the function signature.
>
> Following ~python-build-system.scm~, it means something like:
> #+begin_src scheme
> (define (elixir-version elixir)
>   (let* ((version     (last (string-split elixir #\-)))
>          (components  (string-split version #\.))
>          (major+minor (take components 2)))
>     (string-join major+minor ".")))
>
> (define (install-dir inputs outputs)
>   "Return the path of the current output's Elixir library."
>   (let ((out (assoc-ref outputs "out"))
>         (elixir (assoc-ref inputs "elixir")))
>     (string-append out "/lib/elixir/" (elixir-version elixir) "/site-
> packages")))
> #+end_src
>
> Is this correct?
LGTM.

Toggle quote (31 lines)
> > Btw. I think that you're resolving transitive inputs twice; once on
> > the build system code and once by fattening the outputs.  You
> > probably only need either of those, not both.
>
> Ah. Propagated inputs are propagated. Who would have thought? So,
> this is not necessary:
> #+begin_src scheme
> (define* (lower …)
>   …
>   (define all-propagated-inputs
>     ((compose
>       (cut delete-duplicates <> equal?)
>       (cut filter erlang-or-elixir-input? <>)
>       (cut append-map package-transitive-propagated-inputs <>)
>       (cut map cadr <>))
>      (append inputs native-inputs)))
>
>   (define build-inputs
>     `(…
>       ,@all-propagated-inputs
>       ,@inputs
>       ,@native-inputs))
>
>   (bag …
>        (build-inputs build-inputs)
>        …))
> #+end_src
> I've just removed ~all-propagated-inputs~ and all packages build just
> fine.
>
> Is this what you meant?
Yep. I assume this makes your packages way lighter.

Note that propagated inputs have become a (not great) default for
interpreted languages such as Python or Emacs Lisp.

Toggle quote (6 lines)
> > Yep, that would work.  Note that delete-duplicates is O(n^2),
> > though.  We have a little bit of code where it's done in (I assume)
> > O(n*log(n)) with vhashes.
>
> If ~all-propagated-inputs~ is removed, then the discussion of this
> comment is closed.
Sure.
P
P
Pierre-Henry Fröhring wrote on 15 Nov 2023 23:49
(address . 66801@debbugs.gnu.org)(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)
CAP84DVXp9Z19RRVq-gZ_U+PY6vOtL8GborFLHXkLAmfXGR44ag@mail.gmail.com
So, the attached file `review.org' contains all the discussions so far on
the first patch 01/14.
The following email is the patch itself.
Thanks.
Cheers.
Attachment: file
Attachment: review.org
P
P
Pierre-Henry Fröhring wrote on 15 Nov 2023 23:51
[PATCH v3 01/14] build-system: Add mix-build-system.
(address . 66801@debbugs.gnu.org)
67c324d191a9698aed8d9887260cb0ef2bc031df.1700088189.git.phfrohring@deeplinks.com
* guix/build-system/mix.scm,
* guix/build/mix-build-system.scm: New modules.

Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
---
guix/build-system/mix.scm | 181 ++++++++++++++++++++++++++++
guix/build/mix-build-system.scm | 205 ++++++++++++++++++++++++++++++++
2 files changed, 386 insertions(+)
create mode 100644 guix/build-system/mix.scm
create mode 100644 guix/build/mix-build-system.scm

Toggle diff (402 lines)
diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
new file mode 100644
index 00000000..ae80679b
--- /dev/null
+++ b/guix/build-system/mix.scm
@@ -0,0 +1,181 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Standard build procedure for Elixir packages using 'mix'. This is
+;; implemented as an extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define-module (guix build-system mix)
+ #:use-module (guix build mix-build-system)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
+ #:use-module (guix gexp)
+ #:use-module (guix monads)
+ #:use-module (guix packages)
+ #:use-module (guix search-paths)
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build-system hexpm-uri))
+
+;; Lazily resolve the bindings to avoid circular dependencies.
+(define (default-glibc-utf8-locales)
+ (let* ((base (resolve-interface '(gnu packages base))))
+ (module-ref base 'glibc-utf8-locales)))
+
+(define (default-elixir-hex)
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir-hex)))
+
+(define (default-rebar3)
+ (let ((erlang (resolve-interface '(gnu packages erlang))))
+ (module-ref erlang 'rebar3)))
+
+(define (default-elixir)
+ "Return the default Elixir package."
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir)))
+
+(define (hexpm-uri name version)
+ "Return the URI where to fetch the sources of a Hex package NAME at VERSION.
+NAME is the name of the package which should look like: elixir-pkg-name-X.Y.Z
+See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
+ ((compose
+ (cut string-append "https://repo.hex.pm/tarballs/" <> "-" version ".tar")
+ (cut string-replace-substring <> "-" "_")
+ strip-elixir-prefix)
+ name))
+
+;; A number of environment variables specific to the Mix build system are
+;; reflected here. They are documented at
+;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables. Other
+;; parameters located in mix.exs are defined at
+;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
+(define* (mix-build name
+ inputs
+ #:key
+ source
+ (tests? #t)
+ (mix-path #f) ;See MIX_PATH.
+ (mix-exs "mix.exs") ;See MIX_EXS.
+ (build-per-environment #t) ;See :build_per_environment.
+ (phases '%standard-phases)
+ (outputs '("out"))
+ (search-paths '())
+ (system (%current-system))
+ (guile #f)
+ (imported-modules `((guix build mix-build-system)
+ ,@%gnu-build-system-modules))
+ (modules '((guix build mix-build-system)
+ (guix build utils))))
+ "Build SOURCE using Elixir, and with INPUTS."
+
+ ;; Check the documentation of :build_per_environment here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration And
+ ;; "Environments" here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
+ (define mix-environments
+ (if build-per-environment
+ `("prod" ,@(if tests? '("test") '()))
+ '("shared")))
+
+ (define builder
+ (with-imported-modules imported-modules
+ #~(begin
+
+ (use-modules #$@(sexp->gexp modules))
+
+ #$(with-build-variables inputs outputs
+ #~(mix-build #:name #$name
+ #:source #+source
+ #:system #$system
+ #:tests? #$tests?
+ #:mix-path #$mix-path
+ #:mix-exs #$mix-exs
+ #:mix-environments '#$mix-environments
+ #:build-per-environment #$build-per-environment
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map
+ search-path-specification->sexp
+ search-paths))
+ #:inputs
+ %build-inputs)))))
+
+ (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
+ system
+ #:graft? #f)))
+ (gexp->derivation name
+ builder
+ #:system system
+ #:graft? #f ;consistent with 'gnu-build'
+ #:target #f
+ #:guile-for-build guile)))
+
+(define* (lower name
+ #:key
+ (elixir (default-elixir))
+ (elixir-hex (default-elixir-hex))
+ (glibc-utf8-locales (default-glibc-utf8-locales))
+ (inputs '())
+ (native-inputs '())
+ (propagated-inputs '())
+ (rebar3 (default-rebar3))
+ (tests? #t)
+ outputs
+ source
+ system
+ target
+ #:allow-other-keys #:rest arguments)
+ "Return a bag for NAME."
+ (let ((private-keywords
+ '(#:inputs #:native-inputs
+ #:outputs #:system #:target
+ #:elixir #:elixir-hex #:glibc-utf8-locales
+ #:rebar3 #:erlang))
+ (build-inputs
+ `(,@(standard-packages)
+ ("glibc-utf8-locales" ,glibc-utf8-locales)
+ ("erlang" ,(lookup-package-input elixir "erlang"))
+ ("rebar3" ,rebar3)
+ ("elixir" ,elixir)
+ ("elixir-hex" ,elixir-hex)
+ ,@inputs
+ ,@native-inputs)))
+ (bag (name name)
+ (system system)
+ (build-inputs build-inputs)
+ (host-inputs (if target inputs '()))
+ (outputs outputs)
+ (build mix-build)
+ (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define mix-build-system
+ (build-system (name 'mix)
+ (description "The standard Mix build system")
+ (lower lower)))
+
+;;; mix.scm ends here
diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-system.scm
new file mode 100644
index 00000000..0a1fcb5c
--- /dev/null
+++ b/guix/build/mix-build-system.scm
@@ -0,0 +1,205 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Code:
+
+(define-module (guix build mix-build-system)
+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+ #:use-module (guix build utils)
+ #:use-module (ice-9 ftw)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build
+ strip-elixir-prefix
+ %standard-phases))
+
+(define (elixir-version elixir)
+ "Return an X.Y string where X and Y are respectively the major and minor version number of ELIXIR.
+Example: /gnu/store/…-elixir-1.14.0 → 1.14"
+ ((compose
+ (cut string-join <> ".")
+ (cut take <> 2)
+ (cut string-split <> #\.)
+ last)
+ (string-split elixir #\-)))
+
+(define (elixir-libdir elixir path)
+ "Return the path where all libraries for a specified ELIXIR version are installed."
+ (string-append path "/lib/elixir/" (elixir-version elixir)))
+
+(define (erlang-libdir path)
+ "Return the path of the directory where libraries of an Erlang package are
+installed in the store."
+ (string-append path "/lib/erlang/lib"))
+
+(define (install-dir inputs outputs)
+ "Return the path of the current output's Elixir library.
+Example: /gnu/store/…/lib/elixir/1.14"
+ (elixir-libdir (assoc-ref inputs "elixir")
+ (assoc-ref outputs "out")))
+
+(define (strip-prefix prefix name)
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+(define (strip-elixir-prefix name)
+ "Strip elixir- from NAME."
+ (strip-prefix "elixir-" name))
+
+(define (mix-build-dir mix-env)
+ "Return the directory where build artifacts are to be installed according to
+en environment MIX-ENV in the current directory."
+ (string-append "_build/" mix-env "/lib"))
+
+(define* (unpack #:key source mix-path #:allow-other-keys)
+ "Unpack SOURCE in the working directory, and change directory within the
+source. When SOURCE is a directory, copy it in a sub-directory of the current
+working directory."
+ (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
+ (gnu-unpack #:source source)
+ (when (file-exists? "contents.tar.gz")
+ (invoke "tar" "xvf" "contents.tar.gz"))))
+
+(define (list-directories dir)
+ "List absolute paths of directories directly under the directory DIR."
+ (map (cut string-append dir "/" <>)
+ (scandir dir (lambda (filename)
+ (and (not (member filename '("." "..")))
+ (directory-exists? (string-append dir "/" filename)))))))
+
+(define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
+ "Set environment variables.
+See: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables"
+ (setenv "LC_ALL" "en_US.UTF-8")
+ (setenv "MIX_HOME" (getcwd))
+ (setenv "MIX_ARCHIVES" "archives")
+ (setenv "MIX_BUILD_ROOT" "_build")
+ (setenv "MIX_DEPS_PATH" "deps")
+ (setenv "MIX_PATH" (or mix-path ""))
+ (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3") "/bin/rebar3"))
+ (setenv "MIX_EXS" mix-exs))
+
+(define* (install-hex #:key name inputs outputs #:allow-other-keys)
+ "Install Hex."
+ (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES") "/hex")))
+ (mkdir-p hex-archive-path)
+ (symlink (car (list-directories (elixir-libdir (assoc-ref inputs "elixir")
+ (assoc-ref inputs "elixir-hex"))))
+ (string-append hex-archive-path "/hex"))))
+
+(define* (install-dependencies #:key
+ name
+ inputs
+ outputs
+ tests?
+ build-per-environment
+ (native-inputs '())
+ mix-environments
+ #:allow-other-keys
+ #:rest rest)
+ "Install dependencies."
+ (define (install-lib lib dir)
+ (let ((lib-name (last (string-split lib #\/))))
+ (symlink lib (string-append dir "/" lib-name))))
+
+ (define (install-input mix-env input)
+ (let ((dir (mix-build-dir mix-env)))
+ (mkdir-p dir)
+ (match input
+ ((_ . path)
+ ((compose
+ (cut for-each (cut install-lib <> dir) <>)
+ (cut append-map list-directories <>)
+ (cut filter directory-exists? <>))
+ (list (elixir-libdir (assoc-ref inputs "elixir") path)
+ (erlang-libdir path)))))))
+
+ (define (install-inputs mix-env)
+ (for-each (cut install-input mix-env <>)
+ (append inputs native-inputs)))
+
+ (for-each install-inputs mix-environments))
+
+(define* (build #:key mix-environments #:allow-other-keys)
+ "Builds the Mix project."
+ (for-each (lambda (mix-env)
+ (setenv "MIX_ENV" mix-env)
+ (invoke "mix" "compile" "--no-deps-check"))
+ mix-environments))
+
+(define* (check #:key (tests? #t) #:allow-other-keys)
+ "Test the Mix project."
+ (if tests?
+ (invoke "mix" "test" "--no-deps-check")
+ (format #t "tests? = ~a~%" tests?)))
+
+(define* (remove-mix-dirs . _)
+ "Remove all .mix/ directories.
+We do not want to copy them to the installation directory."
+ (for-each delete-file-recursively
+ (find-files "." (file-name-predicate "\\.mix$") #:directories? #t)))
+
+(define (library-name pkg-name)
+ "Return the library name deduced from PKG-NAME.
+A package should be named: elixir-lib-name-X.Y.Z from which the library name
+lib_name is deduced."
+ ((compose
+ (cut string-join <> "_")
+ (cut drop-right <> 1)
+ (cut string-split <> #\-))
+ (strip-elixir-prefix pkg-name)))
+
+(define* (install #:key
+ inputs
+ outputs
+ name
+ build-per-environment
+ #:allow-other-keys)
+ "Install build artifacts in the store."
+ (let* ((lib-name (library-name name))
+ (lib-dir (string-append (install-dir inputs outputs) "/" lib-name)))
+ (mkdir-p lib-dir)
+ (copy-recursively (string-append (mix-build-dir (if build-per-environment "prod" "shared")) "/" lib-name)
+ lib-dir
+ #:follow-symlinks? #t)))
+
+(define %standard-phases
+ (modify-phases gnu:%standard-phases
+ (delete 'bootstrap)
+ (replace 'configure configure)
+ (replace 'unpack unpack)
+ (add-after 'patch-generated-file-shebangs 'install-hex install-hex)
+ (add-after 'install-hex 'install-dependencies install-dependencies)
+ (replace 'build build)
+ (replace 'check check)
+ (add-before 'install 'remove-mix-dirs remove-mix-dirs)
+ (replace 'install install)))
+
+(define* (mix-build #:key inputs (phases %standard-phases)
+ #:allow-other-keys #:rest args)
+ "Build the given Mix package, applying all of PHASES in order."
+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))
+
+;;; mix-build-system.scm ends here

base-commit: a0d337e79c87d7c38c79d0291974f490cb137a52
--
2.41.0
L
L
Liliana Marie Prikler wrote on 16 Nov 2023 03:05
ceb7647522b4578067a4fbc63815d13be1f56d09.camel@gmail.com
Am Mittwoch, dem 15.11.2023 um 23:51 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (280 lines)
> * guix/build-system/mix.scm,
> * guix/build/mix-build-system.scm: New modules.
>
> Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
> ---
>  guix/build-system/mix.scm       | 181 ++++++++++++++++++++++++++++
>  guix/build/mix-build-system.scm | 205
> ++++++++++++++++++++++++++++++++
>  2 files changed, 386 insertions(+)
>  create mode 100644 guix/build-system/mix.scm
>  create mode 100644 guix/build/mix-build-system.scm
>
> diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
> new file mode 100644
> index 00000000..ae80679b
> --- /dev/null
> +++ b/guix/build-system/mix.scm
> @@ -0,0 +1,181 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
> +;;;
> +;;; 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/>.
> +
> +;; Commentary:
> +;;
> +;; Standard build procedure for Elixir packages using 'mix'.  This
> is
> +;; implemented as an extension of 'gnu-build-system'.
> +;;
> +;; Code:
> +
> +(define-module (guix build-system mix)
> +  #:use-module (guix build mix-build-system)
> +  #:use-module (guix build-system gnu)
> +  #:use-module (guix build-system)
> +  #:use-module (guix gexp)
> +  #:use-module (guix monads)
> +  #:use-module (guix packages)
> +  #:use-module (guix search-paths)
> +  #:use-module (guix store)
> +  #:use-module (guix utils)
> +  #:use-module (ice-9 match)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (srfi srfi-26)
> +  #:export (mix-build-system hexpm-uri))
> +
> +;; Lazily resolve the bindings to avoid circular dependencies.
> +(define (default-glibc-utf8-locales)
> +  (let* ((base (resolve-interface '(gnu packages base))))
> +    (module-ref base 'glibc-utf8-locales)))
> +
> +(define (default-elixir-hex)
> +  (let ((elixir (resolve-interface '(gnu packages elixir))))
> +    (module-ref elixir 'elixir-hex)))
> +
> +(define (default-rebar3)
> +  (let ((erlang (resolve-interface '(gnu packages erlang))))
> +    (module-ref erlang 'rebar3)))
> +
> +(define (default-elixir)
> +  "Return the default Elixir package."
> +  (let ((elixir (resolve-interface '(gnu packages elixir))))
> +    (module-ref elixir 'elixir)))
> +
> +(define (hexpm-uri name version)
> +  "Return the URI where to fetch the sources of a Hex package NAME
> at VERSION.
> +NAME is the name of the package which should look like: elixir-pkg-
> name-X.Y.Z
> +See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
> +  ((compose
> +    (cut string-append "https://repo.hex.pm/tarballs/" <> "-"
> version ".tar")
> +    (cut string-replace-substring <> "-" "_")
> +    strip-elixir-prefix)
> +   name))
> +
> +;; A number of environment variables specific to the Mix build
> system are
> +;; reflected here.  They are documented at
> +;;
> https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables. 
> Other
> +;; parameters located in mix.exs are defined at
> +;;
> https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
> +(define* (mix-build name
> +                    inputs
> +                    #:key
> +                    source
> +                    (tests? #t)
> +                    (mix-path #f) ;See MIX_PATH.
> +                    (mix-exs "mix.exs") ;See MIX_EXS.
> +                    (build-per-environment #t) ;See
> :build_per_environment.
> +                    (phases '%standard-phases)
> +                    (outputs '("out"))
> +                    (search-paths '())
> +                    (system (%current-system))
> +                    (guile #f)
> +                    (imported-modules `((guix build mix-build-
> system)
> +                                        ,@%gnu-build-system-
> modules))
> +                    (modules '((guix build mix-build-system)
> +                               (guix build utils))))
> +  "Build SOURCE using Elixir, and with INPUTS."
> +
> +  ;; Check the documentation of :build_per_environment here:
> +  ;;
> https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration A
> nd
> +  ;; "Environments" here:
> +  ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
> +  (define mix-environments
> +    (if build-per-environment
> +        `("prod" ,@(if tests? '("test") '()))
> +        '("shared")))
> +
> +  (define builder
> +    (with-imported-modules imported-modules
> +      #~(begin
> +
> +          (use-modules #$@(sexp->gexp modules))
> +
> +          #$(with-build-variables inputs outputs
> +              #~(mix-build #:name #$name
> +                           #:source #+source
> +                           #:system #$system
> +                           #:tests? #$tests?
> +                           #:mix-path #$mix-path
> +                           #:mix-exs #$mix-exs
> +                           #:mix-environments '#$mix-environments
> +                           #:build-per-environment #$build-per-
> environment
> +                           #:phases #$(if (pair? phases)
> +                                          (sexp->gexp phases)
> +                                          phases)
> +                           #:outputs %outputs
> +                           #:search-paths '#$(sexp->gexp
> +                                              (map
> +                                               search-path-
> specification->sexp
> +                                               search-paths))
> +                           #:inputs
> +                           %build-inputs)))))
> +
> +  (mlet %store-monad ((guile (package->derivation (or guile
> (default-guile))
> +                                                  system
> +                                                  #:graft? #f)))
> +    (gexp->derivation name
> +                      builder
> +                      #:system system
> +                      #:graft? #f       ;consistent with 'gnu-build'
> +                      #:target #f
> +                      #:guile-for-build guile)))
> +
> +(define* (lower name
> +                #:key
> +                (elixir (default-elixir))
> +                (elixir-hex (default-elixir-hex))
> +                (glibc-utf8-locales (default-glibc-utf8-locales))
> +                (inputs '())
> +                (native-inputs '())
> +                (propagated-inputs '())
> +                (rebar3 (default-rebar3))
> +                (tests? #t)
> +                outputs
> +                source
> +                system
> +                target
> +                #:allow-other-keys #:rest arguments)
> +  "Return a bag for NAME."
> +  (let ((private-keywords
> +         '(#:inputs #:native-inputs
> +           #:outputs #:system #:target
> +           #:elixir #:elixir-hex #:glibc-utf8-locales
> +           #:rebar3 #:erlang))
> +        (build-inputs
> +         `(,@(standard-packages)
> +           ("glibc-utf8-locales" ,glibc-utf8-locales)
> +           ("erlang" ,(lookup-package-input elixir "erlang"))
> +           ("rebar3" ,rebar3)
> +           ("elixir" ,elixir)
> +           ("elixir-hex" ,elixir-hex)
> +           ,@inputs
> +           ,@native-inputs)))
> +  (bag (name name)
> +       (system system)
> +       (build-inputs build-inputs)
> +       (host-inputs (if target inputs '()))
> +       (outputs outputs)
> +       (build mix-build)
> +       (arguments (strip-keyword-arguments private-keywords
> arguments)))))
> +
> +(define mix-build-system
> +  (build-system (name 'mix)
> +                (description "The standard Mix build system")
> +                (lower lower)))
> +
> +;;; mix.scm ends here
> diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-
> system.scm
> new file mode 100644
> index 00000000..0a1fcb5c
> --- /dev/null
> +++ b/guix/build/mix-build-system.scm
> @@ -0,0 +1,205 @@
> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2023 Pierre-Henry Fröhring
> <phfrohring@deeplinks.com>
> +;;;
> +;;; 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/>.
> +
> +;; Commentary:
> +;;
> +;; Code:
> +
> +(define-module (guix build mix-build-system)
> +  #:use-module ((guix build gnu-build-system) #:prefix gnu:)
> +  #:use-module (guix build utils)
> +  #:use-module (ice-9 ftw)
> +  #:use-module (ice-9 match)
> +  #:use-module (ice-9 regex)
> +  #:use-module (ice-9 string-fun)
> +  #:use-module (srfi srfi-1)
> +  #:use-module (srfi srfi-26)
> +  #:export (mix-build
> +            strip-elixir-prefix
> +            %standard-phases))
> +
> +(define (elixir-version elixir)
> +  "Return an X.Y string where X and Y are respectively the major and
> minor version number of ELIXIR.
> +Example: /gnu/store/…-elixir-1.14.0 → 1.14"
> +  ((compose
> +    (cut string-join <> ".")
> +    (cut take <> 2)
> +    (cut string-split <> #\.)
> +    last)
> +   (string-split elixir #\-)))
I don't think we need to be overly cute here. The let-binding version
from python-build-system is less surprising to the uninitiated reader.

See also strip-store-file-name and package-name->name+version.

Toggle quote (4 lines)
> +(define (elixir-libdir elixir path)
> +  "Return the path where all libraries for a specified ELIXIR
> version are installed."
> +  (string-append path "/lib/elixir/" (elixir-version elixir)))
You probably want to swap path and elixir and perhaps also find a way
to implicitly parameterize the latter so as to make it optional.
Toggle quote (18 lines)
> +
> +(define (erlang-libdir path)
> +  "Return the path of the directory where libraries of an Erlang
> package are
> +installed in the store."
> +  (string-append path "/lib/erlang/lib"))
> +
> +(define (install-dir inputs outputs)
> +  "Return the path of the current output's Elixir library.
> +Example: /gnu/store/…/lib/elixir/1.14"
> +  (elixir-libdir (assoc-ref inputs "elixir")
> +                 (assoc-ref outputs "out")))
> +
> +(define (strip-prefix prefix name)
> +  "Return NAME without the prefix PREFIX."
> +  (if (string-prefix? prefix name)
> +      (string-drop name (string-length prefix))
> +      name))
You might want to consider 
(define* (strip-prefix name #:optional (prefix "elixir-")
…)

Toggle quote (40 lines)
> +(define (mix-build-dir mix-env)
> +  "Return the directory where build artifacts are to be installed
> according to
> +en environment MIX-ENV in the current directory."
> +  (string-append "_build/" mix-env "/lib"))
> +
> +(define* (unpack #:key source mix-path #:allow-other-keys)
> +  "Unpack SOURCE in the working directory, and change directory
> within the
> +source.  When SOURCE is a directory, copy it in a sub-directory of
> the current
> +working directory."
> +  (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
> +    (gnu-unpack #:source source)
> +    (when (file-exists? "contents.tar.gz")
> +      (invoke "tar" "xvf" "contents.tar.gz"))))
> +
> +(define (list-directories dir)
> +  "List absolute paths of directories directly under the directory
> DIR."
> +  (map (cut string-append dir "/" <>)
> +       (scandir dir (lambda (filename)
> +                      (and (not (member filename '("." "..")))
> +                           (directory-exists? (string-append dir "/"
> filename)))))))
> +
> +(define* (configure #:key inputs mix-path mix-exs #:allow-other-
> keys)
> +  "Set environment variables.
> +See:
> https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables"
> +  (setenv "LC_ALL" "en_US.UTF-8")
> +  (setenv "MIX_HOME" (getcwd))
> +  (setenv "MIX_ARCHIVES" "archives")
> +  (setenv "MIX_BUILD_ROOT" "_build")
> +  (setenv "MIX_DEPS_PATH" "deps")
> +  (setenv "MIX_PATH" (or mix-path ""))
> +  (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3")
> "/bin/rebar3"))
> +  (setenv "MIX_EXS" mix-exs))
This does not appear to be a configure phase in the traditional sense
of the wording. Instead, it should be a post 'set-paths' 'set-mix-env'
imho.

Toggle quote (10 lines)
> +(define* (install-hex #:key name inputs outputs #:allow-other-keys)
> +  "Install Hex."
> +  (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES")
> "/hex")))
> +    (mkdir-p hex-archive-path)
> +    (symlink (car (list-directories (elixir-libdir (assoc-ref inputs
> "elixir")
> +                                                   (assoc-ref inputs
> "elixir-hex"))))
> +             (string-append hex-archive-path "/hex"))))
Why do we need this? It looks like we'll be pasting the same (native?)
input all over the store, which imho would be bad.

Toggle quote (26 lines)
> +(define* (install-dependencies #:key
> +                               name
> +                               inputs
> +                               outputs
> +                               tests?
> +                               build-per-environment
> +                               (native-inputs '())
> +                               mix-environments
> +                               #:allow-other-keys
> +                               #:rest rest)
> +  "Install dependencies."
> +  (define (install-lib lib dir)
> +    (let ((lib-name (last (string-split lib #\/))))
> +      (symlink lib (string-append dir "/" lib-name))))
> +
> +  (define (install-input mix-env input)
> +    (let ((dir (mix-build-dir mix-env)))
> +      (mkdir-p dir)
> +      (match input
> +        ((_ . path)
> +         ((compose
> +           (cut for-each (cut install-lib <> dir) <>)
> +           (cut append-map list-directories <>)
> +           (cut filter directory-exists? <>))
> +          (list (elixir-libdir (assoc-ref inputs "elixir") path)
> +                (erlang-libdir path)))))))
I think you're at the wrong layer of abstraction here.

(match input 
((_ . prefix)
(begin
(install-subdirectories (elixir-libdir path))
(install-subdirectories (erlang-libdir path)))))

where (install-subdirectories PATH) is basically
(when (directory-exists? PATH)
(for-each (cute install-lib <> (mix-build-dir mix-env))
(list-directories PATH)))

Toggle quote (3 lines)
> +  (define (install-inputs mix-env)
> +    (for-each (cut install-input mix-env <>)
> +              (append inputs native-inputs)))
Installing native inputs: probably a bad idea (inhibits cross-
compilation).

Toggle quote (32 lines)
> +  (for-each install-inputs mix-environments))
> +
> +(define* (build #:key mix-environments #:allow-other-keys)
> +  "Builds the Mix project."
> +  (for-each (lambda (mix-env)
> +              (setenv "MIX_ENV" mix-env)
> +              (invoke "mix" "compile" "--no-deps-check"))
> +            mix-environments))
> +
> +(define* (check #:key (tests? #t) #:allow-other-keys)
> +  "Test the Mix project."
> +  (if tests?
> +      (invoke "mix" "test" "--no-deps-check")
> +      (format #t "tests? = ~a~%" tests?)))
> +
> +(define* (remove-mix-dirs . _)
> +  "Remove all .mix/ directories.
> +We do not want to copy them to the installation directory."
> +  (for-each delete-file-recursively
> +            (find-files "." (file-name-predicate "\\.mix$")
> #:directories? #t)))
> +
> +(define (library-name pkg-name)
> +  "Return the library name deduced from PKG-NAME.
> +A package should be named: elixir-lib-name-X.Y.Z from which the
> library name
> +lib_name is deduced."
> +  ((compose
> +    (cut string-join <> "_")
> +    (cut drop-right <> 1)
> +    (cut string-split <> #\-))
> +   (strip-elixir-prefix pkg-name)))
Consider defining (package-name-version->elixir-name) analogous to
(package-name-version->erlang-name) in rebar-build-system. Also allow
overriding it through a build system argument. The thing you currently
have will blow up with git-version.

Cheers
P
P
Pierre-Henry Fröhring wrote on 16 Nov 2023 14:01
(address . 66801@debbugs.gnu.org)(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)
CAP84DVVBMKfOL6TA0z0FowD6ne8Z+UXKgpbpYuZKmfQxmR3rrg@mail.gmail.com
Do you mind if I paste the conversation using the following org format?

* Comment
** lilyp
Toggle quote (11 lines)
> +(define (elixir-version elixir)
> + "Return an X.Y string where X and Y are respectively the major and
> minor version number of ELIXIR.
> +Example: /gnu/store/…-elixir-1.14.0 → 1.14"
> + ((compose
> + (cut string-join <> ".")
> + (cut take <> 2)
> + (cut string-split <> #\.)
> + last)
> + (string-split elixir #\-)))

I don't think we need to be overly cute here. The let-binding version
from python-build-system is less surprising to the uninitiated reader.

See also strip-store-file-name and package-name->name+version.


** phf
Maybe:
#+begin_src scheme
(define (elixir-version elixir)
"Return an X.Y string where X and Y are respectively the major and minor
version number of ELIXIR.
Example: /gnu/store/…-elixir-1.14.0 → 1.14"
(receive (_ version) (package-name->name+version (strip-store-file-name
elixir))
(let* ((components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor "."))))
#+end_src

or:
#+begin_src scheme
(define (elixir-version elixir)
"Return an X.Y string where X and Y are respectively the major and minor
version number of ELIXIR.
Example: /gnu/store/…-elixir-1.14.0 → 1.14"
(let* ((version (last (string-split elixir #\-)))
(components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor ".")))
#+end_src

or: just inline the code as it is used just once. See
[[id:76abe0e4-a0e2-4176-bdc0-9ff241e8ba42][next comment]].


* Comment
:PROPERTIES:
:ID: 76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
:END:

** lilyp
Toggle quote (5 lines)
> +(define (elixir-libdir elixir path)
> + "Return the path where all libraries for a specified ELIXIR
> version are installed."
> + (string-append path "/lib/elixir/" (elixir-version elixir)))

You probably want to swap path and elixir and perhaps also find a way
to implicitly parameterize the latter so as to make it optional.


** phf
Is this what you mean?
#+begin_src scheme
;; The Elixir version is constant as soon as it is computable from the
current
;; execution. It is a X.Y string where X and Y are respectively the major
and
;; minor version number of the Elixir used in the build.
(define elixir-version (make-parameter "X.Y"))

(define* (elixir-libdir path #:optional (version (elixir-version)))
"Return the path where all libraries for a specified ELIXIR version are
installed."
(string-append path "/lib/elixir/" version))

(define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
(elixir-version
(receive (_ version) (package-name->name+version (strip-store-file-name
(assoc-ref inputs "elixir")))
(let* ((components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor ".")))))
#+end_src


* Comment
** lilyp
Toggle quote (15 lines)
> +(define* (configure #:key inputs mix-path mix-exs #:allow-other-
> keys)
> + "Set environment variables.
> +See:
> https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables"
> + (setenv "LC_ALL" "en_US.UTF-8")
> + (setenv "MIX_HOME" (getcwd))
> + (setenv "MIX_ARCHIVES" "archives")
> + (setenv "MIX_BUILD_ROOT" "_build")
> + (setenv "MIX_DEPS_PATH" "deps")
> + (setenv "MIX_PATH" (or mix-path ""))
> + (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3")
> "/bin/rebar3"))
> + (setenv "MIX_EXS" mix-exs))

This does not appear to be a configure phase in the traditional sense
of the wording. Instead, it should be a post 'set-paths' 'set-mix-env'
imho.


** phf
After ~install-locale~ since ~(setenv "LC_ALL" "en_US.UTF-8")~ is called in
this
phase.
#+begin_src scheme
(define %standard-phases
(modify-phases gnu:%standard-phases
(delete 'configure)
(add-after 'install-locale 'set-mix-env set-mix-env)
(replace 'unpack unpack)
…))
#+end_src


* Comment
** lilyp
Toggle quote (11 lines)
> +(define* (install-hex #:key name inputs outputs #:allow-other-keys)
> + "Install Hex."
> + (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES")
> "/hex")))
> + (mkdir-p hex-archive-path)
> + (symlink (car (list-directories (elixir-libdir (assoc-ref inputs
> "elixir")
> + (assoc-ref inputs
> "elixir-hex"))))
> + (string-append hex-archive-path "/hex"))))

Why do we need this? It looks like we'll be pasting the same (native?)
input all over the store, which imho would be bad.


** phf
Without ~Hex~, you get this error:
#+begin_example
starting phase `build'
Could not find Hex, which is needed to build dependency :ex_doc
Shall I install Hex? (if running non-interactively, use "mix local.hex
--force") [Yn]
#+end_example
This message is called from ~handle_rebar_not_found~ in
~lib/mix/lib/mix/tasks/deps.compile.ex~ ; which is called from ~rebar_cmd~
because
a ~manager~ (~Hex~) could not be found. Hex must be present => install-hex
must be
executed.

I thought that this should not be a problem since Hex is needed at build
time,
and just symlinked. Maybe should it be copied instead?


* Comment
** lilyp
Toggle quote (12 lines)
> + (define (install-input mix-env input)
> + (let ((dir (mix-build-dir mix-env)))
> + (mkdir-p dir)
> + (match input
> + ((_ . path)
> + ((compose
> + (cut for-each (cut install-lib <> dir) <>)
> + (cut append-map list-directories <>)
> + (cut filter directory-exists? <>))
> + (list (elixir-libdir (assoc-ref inputs "elixir") path)
> + (erlang-libdir path)))))))

I think you're at the wrong layer of abstraction here.

(match input
((_ . prefix)
(begin
(install-subdirectories (elixir-libdir path))
(install-subdirectories (erlang-libdir path)))))

where (install-subdirectories PATH) is basically
(when (directory-exists? PATH)
(for-each (cute install-lib <> (mix-build-dir mix-env))
(list-directories PATH)))


** phf
Does this work?
#+begin_src scheme
(define (install-lib lib dir)
(let ((lib-name (last (string-split lib #\/))))
(symlink lib (string-append dir "/" lib-name))))

(define (install-subdirectories mix-env path)
(let ((build-dir (mix-build-dir mix-env)))
(mkdir-p build-dir)
(when (directory-exists? path)
(for-each (cute install-lib <> build-dir)
(list-directories path)))))

(define (install-input mix-env input)
(match input
((_ . path)
(begin
(install-subdirectories mix-env (elixir-libdir path))
(install-subdirectories mix-env (erlang-libdir path))))))
#+end_src


* Comment
** lilyp
Toggle quote (4 lines)
> + (define (install-inputs mix-env)
> + (for-each (cut install-input mix-env <>)
> + (append inputs native-inputs)))

Installing native inputs: probably a bad idea (inhibits cross-
compilation).


** phf
A slight variant that does not link things when it should not:
#+begin_src scheme
(define (install-inputs mix-env)
(for-each (cut install-input mix-env <>)
(cond
((string=? mix-env "prod") inputs)
((member mix-env '("shared" "test")) (append inputs
native-inputs))
(else (error (format #f "Unexpected Mix env: ~a~%"
mix-env))))))
#+end_src

I did not consider cross-compilation yet. The following might be wrong be
here
we go. I far as I understand, Erlang applications are largely platform
independent. Once the code is compiled to BEAM bytecode, it can run on any
platform that has the Erlang VM installed. If an Erlang library uses native
extensions, then cross-compilation might be required. For a build to succeed
in a given environment (one of "prod", "test", "shared"), the BEAM files of
all dependencies should be present on the build machine. So, all
dependencies
must be installed


* Comment
** lilyp
Toggle quote (11 lines)
> +(define (library-name pkg-name)
> + "Return the library name deduced from PKG-NAME.
> +A package should be named: elixir-lib-name-X.Y.Z from which the
> library name
> +lib_name is deduced."
> + ((compose
> + (cut string-join <> "_")
> + (cut drop-right <> 1)
> + (cut string-split <> #\-))
> + (strip-elixir-prefix pkg-name)))

Consider defining (package-name-version->elixir-name) analogous to
(package-name-version->erlang-name) in rebar-build-system. Also allow
overriding it through a build system argument. The thing you currently
have will blow up with git-version.


** phf
Faily close to the ~rebar-build-system~ version.
#+begin_src scheme
(define (package-name-version->elixir-name name+ver)
"Convert the Guix package NAME-VER to the corresponding Elixir
name-version
format. Essentially drop the prefix used in Guix and replace dashes by
underscores."
(let* ((name- (package-name->name+version name+ver)))
(string-join
(string-split
(if (string-prefix? "elixir-" name-)
(string-drop name- (string-length "elixir-"))
name-)
#\-)
"_")))
#+end_src
Attachment: file
L
L
Liliana Marie Prikler wrote on 16 Nov 2023 16:11
66cf8aa37e2c9696af3a8895059b9293669f485c.camel@gmail.com
Am Donnerstag, dem 16.11.2023 um 14:01 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (2 lines)
> Do you mind if I paste the conversation using the following org
> format?
I do mind you pasting it in HTML format :P

Toggle quote (49 lines)
> * Comment
> ** lilyp
> > +(define (elixir-version elixir)
> > +  "Return an X.Y string where X and Y are respectively the major
> > and
> > minor version number of ELIXIR.
> > +Example: /gnu/store/…-elixir-1.14.0 → 1.14"
> > +  ((compose
> > +    (cut string-join <> ".")
> > +    (cut take <> 2)
> > +    (cut string-split <> #\.)
> > +    last)
> > +   (string-split elixir #\-)))
>
> I don't think we need to be overly cute here.  The let-binding
> version from python-build-system is less surprising to the
> uninitiated reader.
>
> See also strip-store-file-name and package-name->name+version.
>
>
> ** phf
> Maybe:
> #+begin_src scheme
> (define (elixir-version elixir)
>   "Return an X.Y string where X and Y are respectively the major and
> minor version number of ELIXIR.
> Example: /gnu/store/…-elixir-1.14.0 → 1.14"
>   (receive (_ version) (package-name->name+version (strip-store-file-
> name elixir))
>     (let* ((components  (string-split version #\.))
>            (major+minor (take components 2)))
>       (string-join major+minor "."))))
> #+end_src
>
> or:
> #+begin_src scheme
> (define (elixir-version elixir)
>   "Return an X.Y string where X and Y are respectively the major and
> minor version number of ELIXIR.
> Example: /gnu/store/…-elixir-1.14.0 → 1.14"
>   (let* ((version     (last (string-split elixir #\-)))
>          (components  (string-split version #\.))
>          (major+minor (take components 2)))
>     (string-join major+minor ".")))
> #+end_src
>
> or: just inline the code as it is used just once. See [[id:76abe0e4-
> a0e2-4176-bdc0-9ff241e8ba42][next comment]].
Note that you can use SRFI-71 let and let* to bind multiple values at
once. So you can write the first one without receive.

Toggle quote (40 lines)
>
> * Comment
> :PROPERTIES:
> :ID:       76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
> :END:
>
> ** lilyp
> > +(define (elixir-libdir elixir path)
> > +  "Return the path where all libraries for a specified ELIXIR
> > version are installed."
> > +  (string-append path "/lib/elixir/" (elixir-version elixir)))
>
> You probably want to swap path and elixir and perhaps also find a way
> to implicitly parameterize the latter so as to make it optional.
>
>
> ** phf
> Is this what you mean?
> #+begin_src scheme
> ;; The Elixir version is constant as soon as it is computable from
> the current
> ;; execution. It is a X.Y string where X and Y are respectively the
> major and
> ;; minor version number of the Elixir used in the build.
> (define elixir-version (make-parameter "X.Y"))
>
> (define* (elixir-libdir path #:optional (version (elixir-version)))
>   "Return the path where all libraries for a specified ELIXIR version
> are installed."
>   (string-append path "/lib/elixir/" version))
>
> (define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
>   …
>   (elixir-version
>    (receive (_ version) (package-name->name+version (strip-store-
> file-name (assoc-ref inputs "elixir")))
>      (let* ((components  (string-split version #\.))
>             (major+minor (take components 2)))
>        (string-join major+minor ".")))))
> #+end_src
I'd use %elixir-version and perhaps make it a fluent rather than a
parameter (not quite sure whether parameters get reset when a function
goes out of scope).

Toggle quote (35 lines)
> * Comment
> ** lilyp
> > +(define* (configure #:key inputs mix-path mix-exs #:allow-other-
> > keys)
> > +  "Set environment variables.
> > +See:
> > https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables
> > "
> > +  (setenv "LC_ALL" "en_US.UTF-8")
> > +  (setenv "MIX_HOME" (getcwd))
> > +  (setenv "MIX_ARCHIVES" "archives")
> > +  (setenv "MIX_BUILD_ROOT" "_build")
> > +  (setenv "MIX_DEPS_PATH" "deps")
> > +  (setenv "MIX_PATH" (or mix-path ""))
> > +  (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3")
> > "/bin/rebar3"))
> > +  (setenv "MIX_EXS" mix-exs))
>
> This does not appear to be a configure phase in the traditional sense
> of the wording.  Instead, it should be a post 'set-paths' 'set-mix-
> env' imho.
>
>
> ** phf
> After ~install-locale~ since ~(setenv "LC_ALL" "en_US.UTF-8")~ is
> called in this phase.
> #+begin_src scheme
> (define %standard-phases
>   (modify-phases gnu:%standard-phases
>     …
>     (delete 'configure)
>     (add-after 'install-locale 'set-mix-env set-mix-env)
>     (replace 'unpack unpack)
>     …))
> #+end_src
Good point: you shouldn't be setting LC_ALL anyway, that's already done
by install-locale.

Toggle quote (36 lines)
> * Comment
> ** lilyp
> > +(define* (install-hex #:key name inputs outputs #:allow-other-
> > keys)
> > +  "Install Hex."
> > +  (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES")
> > "/hex")))
> > +    (mkdir-p hex-archive-path)
> > +    (symlink (car (list-directories (elixir-libdir (assoc-ref
> > inputs
> > "elixir")
> > +                                                   (assoc-ref
> > inputs
> > "elixir-hex"))))
> > +             (string-append hex-archive-path "/hex"))))
>
> Why do we need this?  It looks like we'll be pasting the same
> (native?) input all over the store, which imho would be bad.
>
>
> ** phf
> Without ~Hex~, you get this error:
> #+begin_example
> starting phase `build'
> Could not find Hex, which is needed to build dependency :ex_doc
> Shall I install Hex? (if running non-interactively, use "mix
> local.hex --force") [Yn]
> #+end_example
> This message is called from ~handle_rebar_not_found~ in
> ~lib/mix/lib/mix/tasks/deps.compile.ex~ ; which is called from
> ~rebar_cmd~ because
> a ~manager~ (~Hex~) could not be found. Hex must be present =>
> install-hex must be executed.
>
> I thought that this should not be a problem since Hex is needed at
> build time, and just symlinked. Maybe should it be copied instead?
Is hex not an (implicit) native-input in your build system? Anything
that keeps it from functioning is a packaging bug imho.

Toggle quote (41 lines)
> * Comment
> ** lilyp
> > +  (define (install-input mix-env input)
> > +    (let ((dir (mix-build-dir mix-env)))
> > +      (mkdir-p dir)
> > +      (match input
> > +        ((_ . path)
> > +         ((compose
> > +           (cut for-each (cut install-lib <> dir) <>)
> > +           (cut append-map list-directories <>)
> > +           (cut filter directory-exists? <>))
> > +          (list (elixir-libdir (assoc-ref inputs "elixir") path)
> > +                (erlang-libdir path)))))))
>
> I think you're at the wrong layer of abstraction here.
>
>   (match input
>     ((_ . prefix)
>      (begin
>       (install-subdirectories (elixir-libdir path))
>       (install-subdirectories (erlang-libdir path)))))
>
> where (install-subdirectories PATH) is basically
>   (when (directory-exists? PATH)
>     (for-each (cute install-lib <> (mix-build-dir mix-env))
>               (list-directories PATH)))
>
>
> ** phf
> Does this work?
> #+begin_src scheme
> (define (install-lib lib dir)
>     (let ((lib-name (last (string-split lib #\/))))
>       (symlink lib (string-append dir "/" lib-name))))
>
>   (define (install-subdirectories mix-env path)
>     (let ((build-dir (mix-build-dir mix-env)))
>       (mkdir-p build-dir)
>       (when (directory-exists? path)
>         (for-each (cute install-lib <> build-dir)
>                   (list-directories path)))))
Maybe move the mkdir-p into the when or at the start of install-lib.


Toggle quote (41 lines)
>   (define (install-input mix-env input)
>     (match input
>       ((_ . path)
>        (begin
>          (install-subdirectories mix-env (elixir-libdir path))
>          (install-subdirectories mix-env (erlang-libdir path))))))
> #+end_src
>
>
> * Comment
> ** lilyp
> > +  (define (install-inputs mix-env)
> > +    (for-each (cut install-input mix-env <>)
> > +              (append inputs native-inputs)))
>
> Installing native inputs: probably a bad idea (inhibits cross-
> compilation).
>
>
> ** phf
> A slight variant that does not link things when it should not:
> #+begin_src scheme
> (define (install-inputs mix-env)
>     (for-each (cut install-input mix-env <>)
>               (cond
>                 ((string=? mix-env "prod") inputs)
>                 ((member mix-env '("shared" "test")) (append inputs
> native-inputs))
>                 (else (error (format #f "Unexpected Mix env: ~a~%"
> mix-env))))))
> #+end_src
>
> I did not consider cross-compilation yet. The following might be
> wrong be here we go. I far as I understand, Erlang applications are
> largely platform independent. Once the code is compiled to BEAM
> bytecode, it can run on any platform that has the Erlang VM
> installed. If an Erlang library uses native extensions, then cross-
> compilation might be required. For a build to succeed
> in a given environment (one of "prod", "test", "shared"), the BEAM
> files of all dependencies should be present on the build machine. So,
> all dependencies must be installed
Not an expert on elixir, but that sounds borked. You might get around
this with propagated-inputs maybe? That being said, native-inputs
shouldn't blow up a build if missing.

Toggle quote (35 lines)
> * Comment
> ** lilyp
> > +(define (library-name pkg-name)
> > +  "Return the library name deduced from PKG-NAME.
> > +A package should be named: elixir-lib-name-X.Y.Z from which the
> > library name
> > +lib_name is deduced."
> > +  ((compose
> > +    (cut string-join <> "_")
> > +    (cut drop-right <> 1)
> > +    (cut string-split <> #\-))
> > +   (strip-elixir-prefix pkg-name)))
>
> Consider defining (package-name-version->elixir-name) analogous to
> (package-name-version->erlang-name) in rebar-build-system.  Also
> allow overriding it through a build system argument.  The thing you
> currently have will blow up with git-version.
>
>
> ** phf
> Faily close to the ~rebar-build-system~ version.
> #+begin_src scheme
> (define (package-name-version->elixir-name name+ver)
>   "Convert the Guix package NAME-VER to the corresponding Elixir
> name-version format.  Essentially drop the prefix used in Guix and
> replace dashes by underscores."
>   (let* ((name- (package-name->name+version name+ver)))
>     (string-join
>      (string-split
>       (if (string-prefix? "elixir-" name-)
>           (string-drop name- (string-length "elixir-"))
>           name-)
>       #\-)
>      "_")))
> #+end_src
Looks okay.
P
P
Pierre-Henry Fröhring wrote on 16 Nov 2023 19:12
(address . 66801@debbugs.gnu.org)(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)
CAP84DVVh_ZaCUkrrCPCEsitCdLEcCkHTp1C3RB0M1u2msXEZ_w@mail.gmail.com
I should really configure mu4e or something like that.
I'm curious to know if you have a pointer to an efficient setup for working
through emails like this.
Below the last three comments:

* WAITING Comment
:PROPERTIES:
:ID: 76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
:END:

** lilyp
Toggle quote (5 lines)
> +(define (elixir-libdir elixir path)
> + "Return the path where all libraries for a specified ELIXIR
> version are installed."
> + (string-append path "/lib/elixir/" (elixir-version elixir)))

You probably want to swap path and elixir and perhaps also find a way
to implicitly parameterize the latter so as to make it optional.


** phf
Is this what you mean?
#+begin_src scheme
;; The Elixir version is constant as soon as it is computable from the
current
;; execution. It is a X.Y string where X and Y are respectively the major
and
;; minor version number of the Elixir used in the build.
(define elixir-version (make-parameter "X.Y"))

(define* (elixir-libdir path #:optional (version (elixir-version)))
"Return the path where all libraries for a specified ELIXIR version are
installed."
(string-append path "/lib/elixir/" version))

(define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
(elixir-version
(receive (_ version) (package-name->name+version (strip-store-file-name
(assoc-ref inputs "elixir")))
(let* ((components (string-split version #\.))
(major+minor (take components 2)))
(string-join major+minor ".")))))
#+end_src


** lilyp
I'd use %elixir-version and perhaps make it a fluent rather than a parameter
(not quite sure whether parameters get reset when a function goes out of
scope).


** phf
Parameters do not get reset when a function goes out of scope:
#+begin_src scheme
(define x (make-parameter 1))
(define (set-x-to-2) (x 2))
(format #t "~a~%" (x))
(set-x-to-2)
(format #t "~a~%" (x))
#+end_src

#+begin_example
1
2
#+end_example

The [[
seems to indicate that it's an appropriate replacement for a
global variable.


* WAITING Comment
** lilyp
Is hex not an (implicit) native-input in your build system? Anything that
keeps it from functioning is a packaging bug imho.


** phf
If ~mix~ finds ~Hex~ under ~$MIX_ARCHIVES/hex/hex~, then ~mix compile~ does
not emit
the message above. I'm not sure how could this be changed. I've tried to set
~MIX_PATH~ to ~/gnu/store/…-elixir-hex-2.0.5/lib/elixir/1.14~ without
success. So,
this is the reason why ~install-hex~ phase installs Hex like it does.


* WAITING Comment
** lilyp
Toggle quote (4 lines)
> + (define (install-inputs mix-env)
> + (for-each (cut install-input mix-env <>)
> + (append inputs native-inputs)))

Installing native inputs: probably a bad idea (inhibits cross-
compilation).


** phf
A slight variant that does not link things when it should not:
#+begin_src scheme
(define (install-inputs mix-env)
(for-each (cut install-input mix-env <>)
(cond
((string=? mix-env "prod") inputs)
((member mix-env '("shared" "test")) (append inputs
native-inputs))
(else (error (format #f "Unexpected Mix env: ~a~%"
mix-env))))))
#+end_src

I did not consider cross-compilation yet. The following might be wrong be
here
we go. I far as I understand, Erlang applications are largely platform
independent. Once the code is compiled to BEAM bytecode, it can run on any
platform that has the Erlang VM installed. If an Erlang library uses native
extensions, then cross-compilation might be required. For a build to succeed
in a given environment (one of "prod", "test", "shared"), the BEAM files of
all dependencies should be present on the build machine. So, all
dependencies
must be installed


** lilyp
Not an expert on elixir, but that sounds borked.


** phf
Yes. Did not have time to look into it as of now.


** lilyp
You might get around this with propagated-inputs maybe? That being said,
native-inputs shouldn't blow up a build if missing.


** phf
If ~native-inputs~ are missing, it's fine. But wait, maybe there is a
misunderstanding here. Please, check the reasoning: in a cross-compilation
context, we have two machines A and B, and:
- native-inputs: dependencies that must be built on A for A ;
- inputs: dependencies that must be built on A for B ;
- propagated-inputs: like inputs but installed in the profile.


If installing Elixir (like Python) gathers all libraries in the profile
with a
variable like ~GUIX_ERL_LIBS~, then, it would be enough to list
dependencies (in
packages) in ~propagated-inputs~ instead of ~inputs~ and make them
available to
Elixir through ~ERL_LIBS~ (like ~GUIX_PYTHONPATH~ and ~PYTHONPATH~). As a
consequence, the ~install-dependencies~ phase would be reduced to
~ERL_LIBS=$GUIX_ERL_LIBS~.


Is this an answer to: "You might get around this with propagated-inputs
maybe?"
Attachment: file
L
L
Liliana Marie Prikler wrote on 16 Nov 2023 20:34
6aca9ebb2099f6d8ee3bbe39199bc42c364c40f0.camel@gmail.com
Am Donnerstag, dem 16.11.2023 um 19:12 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (67 lines)
> I should really configure mu4e or something like that.
> I'm curious to know if you have a pointer to an efficient setup for
> working through emails like this.
> Below the last three comments:
>
> * WAITING Comment
> :PROPERTIES:
> :ID:       76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
> :END:
>
> ** lilyp
> > +(define (elixir-libdir elixir path)
> > +  "Return the path where all libraries for a specified ELIXIR
> > version are installed."
> > +  (string-append path "/lib/elixir/" (elixir-version elixir)))
>
> You probably want to swap path and elixir and perhaps also find a way
> to implicitly parameterize the latter so as to make it optional.
>
>
> ** phf
> Is this what you mean?
> #+begin_src scheme
> ;; The Elixir version is constant as soon as it is computable from
> the current
> ;; execution. It is a X.Y string where X and Y are respectively the
> major and
> ;; minor version number of the Elixir used in the build.
> (define elixir-version (make-parameter "X.Y"))
>
> (define* (elixir-libdir path #:optional (version (elixir-version)))
>   "Return the path where all libraries for a specified ELIXIR version
> are installed."
>   (string-append path "/lib/elixir/" version))
>
> (define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
>   …
>   (elixir-version
>    (receive (_ version) (package-name->name+version (strip-store-
> file-name (assoc-ref inputs "elixir")))
>      (let* ((components  (string-split version #\.))
>             (major+minor (take components 2)))
>        (string-join major+minor ".")))))
> #+end_src
>
>
> ** lilyp
> I'd use %elixir-version.
>
>
> ** phf
> Parameters do not get reset when a function goes out of scope:
> #+begin_src scheme
> (define x (make-parameter 1))
> (define (set-x-to-2) (x 2))
> (format #t "~a~%" (x))
> (set-x-to-2)
> (format #t "~a~%" (x))
> #+end_src
>
> #+begin_example
> 1
> 2
> #+end_example
>
> The documentation seems to indicate that it's an appropriate
> replacement for a global variable.
It also uses the special parameterize thing to scope values. That
being said, if parameters work for you, then parameters are fine.

Toggle quote (13 lines)
>
> * WAITING Comment** lilyp
> Is hex not an (implicit) native-input in your build system?  Anything
> that keeps it from functioning is a packaging bug imho.
>
>
> ** phf
> If ~mix~ finds ~Hex~ under ~$MIX_ARCHIVES/hex/hex~, then ~mix
> compile~ does not emit the message above. I'm not sure how could this
> be changed. I've tried to set ~MIX_PATH~ to ~/gnu/store/…-elixir-hex-
> 2.0.5/lib/elixir/1.14~ without
> success. So, this is the reason why ~install-hex~ phase installs Hex
> like it does.
Look into mix and how it invokes hex. There's hardcoding potential,
I'm sure of it.

Toggle quote (66 lines)
> * WAITING Comment
> ** lilyp
> > +  (define (install-inputs mix-env)
> > +    (for-each (cut install-input mix-env <>)
> > +              (append inputs native-inputs)))
>
> Installing native inputs: probably a bad idea (inhibits cross-
> compilation).
>
>
> ** phf
> A slight variant that does not link things when it should not:
> #+begin_src scheme
> (define (install-inputs mix-env)
>     (for-each (cut install-input mix-env <>)
>               (cond
>                 ((string=? mix-env "prod") inputs)
>                 ((member mix-env '("shared" "test")) (append inputs
> native-inputs))
>                 (else (error (format #f "Unexpected Mix env: ~a~%"
> mix-env))))))
> #+end_src
>
> I did not consider cross-compilation yet. The following might be
> wrong be here we go. I far as I understand, Erlang applications are
> largely platform independent. Once the code is compiled to BEAM
> bytecode, it can run on any platform that has the Erlang VM
> installed. If an Erlang library uses native extensions, then cross-
> compilation might be required. For a build to succeed
> in a given environment (one of "prod", "test", "shared"), the BEAM
> files of all dependencies should be present on the build machine. So,
> all dependencies must be installed
>
>
> ** lilyp
> Not an expert on elixir, but that sounds borked.
>
>
> ** phf
> Yes. Did not have time to look into it as of now.
>
>
> ** lilyp
> You might get around this with propagated-inputs maybe?  That being
> said, native-inputs shouldn't blow up a build if missing.
>
>
> ** phf
> If ~native-inputs~ are missing, it's fine. But wait, maybe there is a
> misunderstanding here. Please, check the reasoning: in a cross-
> compilation context, we have two machines A and B, and:
> - native-inputs: dependencies that must be built on A for A ;
> - inputs: dependencies that must be built on A for B ;
> - propagated-inputs: like inputs but installed in the profile.
>
>
> If installing Elixir (like Python) gathers all libraries in the
> profile with a variable like ~GUIX_ERL_LIBS~, then, it would be
> enough to list dependencies (in packages) in ~propagated-inputs~
> instead of ~inputs~ and make them available to Elixir through
> ~ERL_LIBS~ (like ~GUIX_PYTHONPATH~ and ~PYTHONPATH~).
> As a consequence, the ~install-dependencies~ phase would be reduced
> to ~ERL_LIBS=$GUIX_ERL_LIBS~.
>
> Is this an answer to: "You might get around this with propagated-
> inputs maybe?"
If environment variables work, that is clearly to be preferred over any
other magic we've considered so far. My hunch is that rebar-build-
system was written this way because environment variables didn't work,
however. Same with Rust and Node, which are kinda yucky in this
regard.

Other than that, yes, (ab)using propagated-inputs like that is the way
to go when there's no smarter alternative available.

Cheers
P
P
Pierre-Henry Fröhring wrote on 17 Nov 2023 08:36
(name . Liliana Marie Prikler)(address . liliana.prikler@gmail.com)(address . 66801@debbugs.gnu.org)
CAP84DVVQX-vSTWHn96hdkHMaQ-E2OsW0Tx5ue3DR_3gRfj0tqw@mail.gmail.com
* WAITING Comment
** lilyp
Toggle quote (11 lines)
> +(define* (install-hex #:key name inputs outputs #:allow-other-keys)
> + "Install Hex."
> + (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES")
> "/hex")))
> + (mkdir-p hex-archive-path)
> + (symlink (car (list-directories (elixir-libdir (assoc-ref inputs
> "elixir")
> + (assoc-ref inputs
> "elixir-hex"))))
> + (string-append hex-archive-path "/hex"))))

Why do we need this? It looks like we'll be pasting the same (native?)
input all over the store, which imho would be bad.


** phf
Without ~Hex~, you get this error:
#+begin_example
starting phase `build'
Could not find Hex, which is needed to build dependency :ex_doc
Shall I install Hex? (if running non-interactively, use "mix local.hex
--force") [Yn]
#+end_example
This message is called from ~handle_rebar_not_found~ in
~lib/mix/lib/mix/tasks/deps.compile.ex~ ; which is called from
~rebar_cmd~ because
a ~manager~ (~Hex~) could not be found. Hex must be present =>
install-hex must be
executed.

I thought that this should not be a problem since Hex is needed at build time,
and just symlinked. Maybe should it be copied instead?


** lilyp
Is hex not an (implicit) native-input in your build system? Anything that
keeps it from functioning is a packaging bug imho.


** phf
If ~mix~ finds ~Hex~ under ~$MIX_ARCHIVES/hex/hex~, then ~mix compile~
does not emit
the message above. I'm not sure how could this be changed. I've tried to set
~MIX_PATH~ to ~/gnu/store/…-elixir-hex-2.0.5/lib/elixir/1.14~ without
success. So,
this is the reason why ~install-hex~ phase installs Hex like it does.


** lilyp
Look into mix and how it invokes hex. There's hardcoding potential, I'm sure
of it.


** phf
:PROPERTIES:
:ID: d9ffbbfa-3cd3-4a44-9acb-04a0627b90d7
:END:

- Observation: ~mix compile~ ⇒ "Could not find Hex, which is needed to
build dependency :ex_doc".
- We have the source
- guix build --source
- We found from where this message is emitted.
- lib/mix/lib/mix/hex.ex
- We now why the message was emitted.
- Code.ensure_loaded?(Hex) failed.

Well, adding the store path of Hex to ~ERL_LIBS~ solves the problem. The
~install-hex~ phase can be deleted in favor of manipulating ~ERL_LIBS~ as
suggested with propagated inputs
[[id:d7cd6e3d-9802-499f-a157-7698aca942d4][below]].


* WAITING Comment
:PROPERTIES:
:ID: d7cd6e3d-9802-499f-a157-7698aca942d4
:END:

** lilyp
Toggle quote (4 lines)
> + (define (install-inputs mix-env)
> + (for-each (cut install-input mix-env <>)
> + (append inputs native-inputs)))

Installing native inputs: probably a bad idea (inhibits cross-
compilation).


** phf
A slight variant that does not link things when it should not:
#+begin_src scheme
(define (install-inputs mix-env)
(for-each (cut install-input mix-env <>)
(cond
((string=? mix-env "prod") inputs)
((member mix-env '("shared" "test")) (append inputs
native-inputs))
(else (error (format #f "Unexpected Mix env: ~a~%" mix-env))))))
#+end_src

I did not consider cross-compilation yet. The following might be wrong be here
we go. As far as I understand, Erlang applications are largely platform
independent. Once the code is compiled to BEAM bytecode, it can run on any
platform that has the Erlang VM installed. If an Erlang library uses native
extensions, then cross-compilation might be required. For a build to succeed
in a given environment (one of "prod", "test", "shared"), the BEAM files of
all dependencies should be present on the build machine. So, all dependencies
must be installed


** lilyp
Not an expert on elixir, but that sounds borked.


** phf
Yes. Did not have time to look into it as of now.


** lilyp
You might get around this with propagated-inputs maybe? That being said,
native-inputs shouldn't blow up a build if missing.


** phf
If ~native-inputs~ are missing, it's fine. But wait, maybe there is a
misunderstanding here. Please, check the reasoning: in a cross-compilation
context, we have two machines A and B, and:
- native-inputs: dependencies that must be built on A for A ;
- inputs: dependencies that must be built on A for B ;
- propagated-inputs: like inputs but installed in the profile.


If installing Elixir (like Python) gathers all libraries in the profile with a
variable like ~GUIX_ERL_LIBS~, then, it would be enough to list dependencies (in
packages) in ~propagated-inputs~ instead of ~inputs~ and make them available to
Elixir through ~ERL_LIBS~ (like ~GUIX_PYTHONPATH~ and ~PYTHONPATH~). As a
consequence, the ~install-dependencies~ phase would be reduced to
~ERL_LIBS=$GUIX_ERL_LIBS~.


Is this an answer to: "You might get around this with propagated-inputs
maybe?"


** lilyp
If environment variables work, that is clearly to be preferred over any other
magic we've considered so far. My hunch is that rebar-build- system was
written this way because environment variables didn't work, however. Same
with Rust and Node, which are kinda yucky in this regard.

Other than that, yes, (ab)using propagated-inputs like that is the way to go
when there's no smarter alternative available.


** phf
As hinted [[id:d9ffbbfa-3cd3-4a44-9acb-04a0627b90d7][above]], abusing
propagated inputs works up to the ~elixir-machete~
package. Essentially, it is enough to add the code below to the
~elixir~ package:
#+begin_src scheme
(native-search-paths
(list (search-path-specification
(variable "GUIX_ERL_LIBS")
(files (list "lib/erlang/lib"
(string-append "lib/elixir/" (version-major+minor
version)))))))
#+end_src


~install-dependencies~ has been deleted altogether for a single line added to
~set-mix-env~.
#+begin_src scheme
(setenv "ERL_LIBS" (getenv "GUIX_ERL_LIBS"))
#+end_src

So, if Erlang and Elixir dependencies are added to propagated inputs, then it
seems to work as expected.
P
P
Pierre-Henry Fröhring wrote on 17 Nov 2023 09:03
[PATCH v3 01/14] build-system: Add mix-build-system.
(address . 66801@debbugs.gnu.org)
ce8c173ef0b340b6a500bacd5821064a1bffe4fc.1700208022.git.phfrohring@deeplinks.com
* guix/build-system/mix.scm,
* guix/build/mix-build-system.scm: New modules.

Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
---
gnu/packages/elixir.scm | 62 ++++++++++-
guix/build-system/mix.scm | 187 ++++++++++++++++++++++++++++++++
guix/build/mix-build-system.scm | 171 +++++++++++++++++++++++++++++
3 files changed, 417 insertions(+), 3 deletions(-)
create mode 100644 guix/build-system/mix.scm
create mode 100644 guix/build/mix-build-system.scm

Toggle diff (458 lines)
diff --git a/gnu/packages/elixir.scm b/gnu/packages/elixir.scm
index 724b4251..6f779afb 100644
--- a/gnu/packages/elixir.scm
+++ b/gnu/packages/elixir.scm
@@ -27,6 +27,7 @@ (define-module (gnu packages elixir)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (guix build-system gnu)
#:use-module (guix gexp)
+ #:use-module (guix utils)
#:use-module (guix git-download)
#:use-module (guix packages)
#:use-module (gnu packages)
@@ -96,9 +97,21 @@ (define-public elixir
(lambda* (#:key inputs #:allow-other-keys)
;; Some tests require access to a home directory.
(setenv "HOME" "/tmp")))
- (delete 'configure))))
- (inputs
- (list erlang git))
+ (delete 'configure)
+ (add-after 'install 'wrap-programs
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ (let* ((out (assoc-ref outputs "out"))
+ (programs '("elixir" "elixirc" "iex" "mix")))
+ (for-each (lambda (program)
+ (wrap-program (string-append out "/bin/" program)
+ '("ERL_LIBS" prefix ("${GUIX_ERL_LIBS}"))))
+ programs)))))))
+ (inputs (list erlang git))
+ (native-search-paths
+ (list (search-path-specification
+ (variable "GUIX_ERL_LIBS")
+ (files (list "lib/erlang/lib"
+ (string-append "lib/elixir/" (version-major+minor version)))))))
(home-page "https://elixir-lang.org/")
(synopsis "Elixir programming language")
(description "Elixir is a dynamic, functional language used to build
@@ -106,3 +119,46 @@ (define-public elixir
for running low-latency, distributed and fault-tolerant systems, while also
being successfully used in web development and the embedded software domain.")
(license license:asl2.0)))
+
+(define-public elixir-hex
+ (package
+ (name "elixir-hex")
+ (version "2.0.5")
+ (source
+ (origin
+ (method git-fetch)
+ (uri (git-reference
+ (url "https://github.com/hexpm/hex.git")
+ (commit (string-append "v" version))))
+ (file-name (git-file-name name version))
+ (sha256
+ (base32
+ "1kvczwvij58kgkhak68004ap81pl26600bczg21mymy2sypkgxmj"))))
+ ;; The mix-build-system assumes that Hex exists.
+ ;; We build Hex using the gnu-build-system.
+ ;; Other Elixir packages use the mix-build-system.
+ (build-system gnu-build-system)
+ (inputs (list elixir))
+ (arguments
+ (list
+ #:phases
+ #~(modify-phases %standard-phases
+ (delete 'bootstrap)
+ (delete 'configure)
+ (replace 'build
+ (lambda* (#:key inputs #:allow-other-keys)
+ (setenv "MIX_ENV" "prod")
+ (invoke "mix" "compile")))
+ (delete 'check)
+ (replace 'install
+ (lambda* (#:key inputs outputs #:allow-other-keys)
+ (define X.Y #$(version-major+minor (package-version elixir)))
+ (define out (string-append (assoc-ref outputs "out") "/lib/elixir/" X.Y "/hex"))
+ (mkdir-p out)
+ (copy-recursively "_build/prod/lib/hex" out))))))
+ (synopsis "Package manager for the Erlang VM")
+ (description
+ "This project provides tasks that integrate with Mix, Elixir's build
+tool.")
+ (home-page "https://hexdocs.pm/makeup_elixir/")
+ (license license:bsd-2)))
diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm
new file mode 100644
index 00000000..7ddedea9
--- /dev/null
+++ b/guix/build-system/mix.scm
@@ -0,0 +1,187 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Standard build procedure for Elixir packages using 'mix'. This is
+;; implemented as an extension of 'gnu-build-system'.
+;;
+;; Code:
+
+(define-module (guix build-system mix)
+ #:use-module (guix build mix-build-system)
+ #:use-module (guix build-system gnu)
+ #:use-module (guix build-system)
+ #:use-module (guix gexp)
+ #:use-module (guix monads)
+ #:use-module (guix packages)
+ #:use-module (guix search-paths)
+ #:use-module (guix store)
+ #:use-module (guix utils)
+ #:use-module (ice-9 match)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:export (mix-build-system hexpm-uri))
+
+;; Lazily resolve the bindings to avoid circular dependencies.
+(define (default-glibc-utf8-locales)
+ (let* ((base (resolve-interface '(gnu packages base))))
+ (module-ref base 'glibc-utf8-locales)))
+
+(define (default-elixir-hex)
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir-hex)))
+
+(define (default-rebar3)
+ (let ((erlang (resolve-interface '(gnu packages erlang))))
+ (module-ref erlang 'rebar3)))
+
+(define (default-elixir)
+ "Return the default Elixir package."
+ (let ((elixir (resolve-interface '(gnu packages elixir))))
+ (module-ref elixir 'elixir)))
+
+(define* (strip-prefix name #:optional (prefix "elixir-"))
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+(define (hexpm-uri name version)
+ "Return the URI where to fetch the sources of a Hex package NAME at VERSION.
+NAME is the name of the package which should look like: elixir-pkg-name-X.Y.Z
+See: https://github.com/hexpm/specifications/blob/main/endpoints.md"
+ ((compose
+ (cut string-append "https://repo.hex.pm/tarballs/" <> "-" version ".tar")
+ (cut string-replace-substring <> "-" "_")
+ strip-prefix)
+ name))
+
+;; A number of environment variables specific to the Mix build system are
+;; reflected here. They are documented at
+;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables. Other
+;; parameters located in mix.exs are defined at
+;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration
+(define* (mix-build name
+ inputs
+ #:key
+ source
+ (tests? #t)
+ (mix-path #f) ;See MIX_PATH.
+ (mix-exs "mix.exs") ;See MIX_EXS.
+ (build-per-environment #t) ;See :build_per_environment.
+ (phases '%standard-phases)
+ (outputs '("out"))
+ (search-paths '())
+ (system (%current-system))
+ (guile #f)
+ (imported-modules `((guix build mix-build-system)
+ ,@%gnu-build-system-modules))
+ (modules '((guix build mix-build-system)
+ (guix build utils))))
+ "Build SOURCE using Elixir, and with INPUTS."
+
+ ;; Check the documentation of :build_per_environment here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.Project.html#module-configuration And
+ ;; "Environments" here:
+ ;; https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments
+ (define mix-environments
+ (if build-per-environment
+ `("prod" ,@(if tests? '("test") '()))
+ '("shared")))
+
+ (define builder
+ (with-imported-modules imported-modules
+ #~(begin
+
+ (use-modules #$@(sexp->gexp modules))
+
+ #$(with-build-variables inputs outputs
+ #~(mix-build #:name #$name
+ #:source #+source
+ #:system #$system
+ #:tests? #$tests?
+ #:mix-path #$mix-path
+ #:mix-exs #$mix-exs
+ #:mix-environments '#$mix-environments
+ #:build-per-environment #$build-per-environment
+ #:phases #$(if (pair? phases)
+ (sexp->gexp phases)
+ phases)
+ #:outputs %outputs
+ #:search-paths '#$(sexp->gexp
+ (map
+ search-path-specification->sexp
+ search-paths))
+ #:inputs
+ %build-inputs)))))
+
+ (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
+ system
+ #:graft? #f)))
+ (gexp->derivation name
+ builder
+ #:system system
+ #:graft? #f ;consistent with 'gnu-build'
+ #:target #f
+ #:guile-for-build guile)))
+
+(define* (lower name
+ #:key
+ (elixir (default-elixir))
+ (elixir-hex (default-elixir-hex))
+ (glibc-utf8-locales (default-glibc-utf8-locales))
+ (inputs '())
+ (native-inputs '())
+ (propagated-inputs '())
+ (rebar3 (default-rebar3))
+ (tests? #t)
+ outputs
+ source
+ system
+ target
+ #:allow-other-keys #:rest arguments)
+ "Return a bag for NAME."
+ (let ((private-keywords
+ '(#:inputs #:native-inputs
+ #:outputs #:system #:target
+ #:elixir #:elixir-hex #:glibc-utf8-locales
+ #:rebar3 #:erlang))
+ (build-inputs
+ `(,@(standard-packages)
+ ("glibc-utf8-locales" ,glibc-utf8-locales)
+ ("erlang" ,(lookup-package-input elixir "erlang"))
+ ("rebar3" ,rebar3)
+ ("elixir" ,elixir)
+ ("elixir-hex" ,elixir-hex)
+ ,@inputs
+ ,@native-inputs)))
+ (bag (name name)
+ (system system)
+ (build-inputs build-inputs)
+ (host-inputs (if target inputs '()))
+ (outputs outputs)
+ (build mix-build)
+ (arguments (strip-keyword-arguments private-keywords arguments)))))
+
+(define mix-build-system
+ (build-system (name 'mix)
+ (description "The standard Mix build system")
+ (lower lower)))
+
+;;; mix.scm ends here
diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-system.scm
new file mode 100644
index 00000000..ca649582
--- /dev/null
+++ b/guix/build/mix-build-system.scm
@@ -0,0 +1,171 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Pierre-Henry Fröhring <phfrohring@deeplinks.com>
+;;;
+;;; 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/>.
+
+;; Commentary:
+;;
+;; Code:
+
+(define-module (guix build mix-build-system)
+ #:use-module ((guix build gnu-build-system) #:prefix gnu:)
+ #:use-module (guix build utils)
+ #:use-module (ice-9 ftw)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 regex)
+ #:use-module (ice-9 string-fun)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-26)
+ #:use-module (srfi srfi-71)
+ #:export (mix-build
+ %standard-phases))
+
+;; The Elixir version is constant as soon as it is computable from the current
+;; execution. It is a X.Y string where X and Y are respectively the major and
+;; minor version number of the Elixir used in the build.
+(define %elixir-version (make-parameter "X.Y"))
+
+(define* (elixir-libdir path #:optional (version (%elixir-version)))
+ "Return the path where all libraries for a specified ELIXIR version are installed."
+ (string-append path "/lib/elixir/" version))
+
+(define (erlang-libdir path)
+ "Return the path of the directory where libraries of an Erlang package are
+installed in the store."
+ (string-append path "/lib/erlang/lib"))
+
+(define* (strip-prefix name #:optional (prefix "elixir-"))
+ "Return NAME without the prefix PREFIX."
+ (if (string-prefix? prefix name)
+ (string-drop name (string-length prefix))
+ name))
+
+(define (mix-build-dir mix-env)
+ "Return the directory where build artifacts are to be installed according to
+en environment MIX-ENV in the current directory."
+ (string-append "_build/" mix-env "/lib"))
+
+(define (elixir-version inputs)
+ "Return an X.Y string where X and Y are respectively the major and minor version number of ELIXIR.
+Example: /gnu/store/…-elixir-1.14.0 → 1.14"
+ (let* ((_ version (package-name->name+version
+ (strip-store-file-name (assoc-ref inputs "elixir"))))
+ (components (string-split version #\.))
+ (major+minor (take components 2)))
+ (string-join major+minor ".")))
+
+(define* (unpack #:key source mix-path #:allow-other-keys)
+ "Unpack SOURCE in the working directory, and change directory within the
+source. When SOURCE is a directory, copy it in a sub-directory of the current
+working directory."
+ (let ((gnu-unpack (assoc-ref gnu:%standard-phases 'unpack)))
+ (gnu-unpack #:source source)
+ (when (file-exists? "contents.tar.gz")
+ (invoke "tar" "xvf" "contents.tar.gz"))))
+
+(define (list-directories dir)
+ "List absolute paths of directories directly under the directory DIR."
+ (map (cut string-append dir "/" <>)
+ (scandir dir (lambda (filename)
+ (and (not (member filename '("." "..")))
+ (directory-exists? (string-append dir "/" filename)))))))
+
+(define* (set-mix-env #:key inputs mix-path mix-exs #:allow-other-keys)
+ "Set environment variables.
+See: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables"
+ (setenv "MIX_HOME" (getcwd))
+ (setenv "MIX_ARCHIVES" "archives")
+ (setenv "MIX_BUILD_ROOT" "_build")
+ (setenv "MIX_DEPS_PATH" "deps")
+ (setenv "MIX_PATH" (or mix-path ""))
+ (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3") "/bin/rebar3"))
+ (setenv "MIX_EXS" mix-exs)
+ (%elixir-version (elixir-version inputs)))
+
+(define* (install-hex #:key name inputs outputs #:allow-other-keys)
+ "Install Hex."
+ (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES") "/hex")))
+ (mkdir-p hex-archive-path)
+ (symlink (car (list-directories (elixir-libdir (assoc-ref inputs "elixir-hex"))))
+ (string-append hex-archive-path "/hex"))))
+
+(define* (install-dependencies . _)
+ "Install dependencies."
+ (setenv "ERL_LIBS" (getenv "GUIX_ERL_LIBS")))
+
+(define* (build #:key mix-environments #:allow-other-keys)
+ "Builds the Mix project."
+ (for-each (lambda (mix-env)
+ (setenv "MIX_ENV" mix-env)
+ (invoke "mix" "compile" "--no-deps-check"))
+ mix-environments))
+
+(define* (check #:key (tests? #t) #:allow-other-keys)
+ "Test the Mix project."
+ (if tests?
+ (invoke "mix" "test" "--no-deps-check")
+ (format #t "tests? = ~a~%" tests?)))
+
+(define* (remove-mix-dirs . _)
+ "Remove all .mix/ directories.
+We do not want to copy them to the installation directory."
+ (for-each delete-file-recursively
+ (find-files "." (file-name-predicate "\\.mix$") #:directories? #t)))
+
+(define (package-name-version->elixir-name name+ver)
+ "Convert the Guix package NAME-VER to the corresponding Elixir name-version
+format. Essentially drop the prefix used in Guix and replace dashes by
+underscores."
+ (let* ((name- (package-name->name+version name+ver)))
+ (string-join
+ (string-split
+ (if (string-prefix? "elixir-" name-)
+ (string-drop name- (string-length "elixir-"))
+ name-)
+ #\-)
+ "_")))
+
+(define* (install #:key
+ inputs
+ outputs
+ name
+ build-per-environment
+ #:allow-other-keys)
+ "Install build artifacts in the store."
+ (let* ((lib-name (package-name-version->elixir-name name))
+ (lib-dir (string-append (elixir-libdir (assoc-ref outputs "out")) "/" lib-name)))
+ (mkdir-p lib-dir)
+ (copy-recursively (string-append (mix-build-dir (if build-per-environment "prod" "shared")) "/" lib-name)
+ lib-dir
+ #:follow-symlinks? #t)))
+
+(define %standard-phases
+ (modify-phases gnu:%standard-phases
+ (delete 'bootstrap)
+ (delete 'configure)
+ (add-after 'install-locale 'set-mix-env set-mix-env)
+ (replace 'unpack unpack)
+ (replace 'build build)
+ (replace 'check check)
+ (add-before 'install 'remove-mix-dirs remove-mix-dirs)
+ (replace 'install install)))
+
+(define* (mix-build #:key inputs (phases %standard-phases)
+ #:allow-other-keys #:rest args)
+ "Build the given Mix package, applying all of PHASES in order."
+ (apply gnu:gnu-build #:inputs inputs #:phases phases args))
+
+;;; mix-build-system.scm ends here

base-commit: a0d337e79c87d7c38c79d0291974f490cb137a52
--
2.41.0
L
L
Liliana Marie Prikler wrote on 17 Nov 2023 20:24
b013181c4026fa833ebf560628538f75c96f504c.camel@gmail.com
Am Freitag, dem 17.11.2023 um 09:03 +0100 schrieb Pierre-Henry
Fröhring:
Toggle quote (2 lines)
> * guix/build-system/mix.scm,
> * guix/build/mix-build-system.scm: New modules.
Avoid spanning a change across multiple files. Use
file: Change.
file2: Likewise.

Toggle quote (6 lines)
> Change-Id: I2cbf6c963a530e73420da0eb17ffaf92827451bf
> ---
>  gnu/packages/elixir.scm         |  62 ++++++++++-
>  guix/build-system/mix.scm       | 187
> ++++++++++++++++++++++++++++++++
>  guix/build/mix-build-system.scm | 171 +++++++++++++++++++++++++++++
You committed two changes at once here. Split them.

Toggle quote (41 lines)
>  3 files changed, 417 insertions(+), 3 deletions(-)
>  create mode 100644 guix/build-system/mix.scm
>  create mode 100644 guix/build/mix-build-system.scm
>
> diff --git a/gnu/packages/elixir.scm b/gnu/packages/elixir.scm
> index 724b4251..6f779afb 100644
> --- a/gnu/packages/elixir.scm
> +++ b/gnu/packages/elixir.scm
> @@ -27,6 +27,7 @@ (define-module (gnu packages elixir)
>    #:use-module ((guix licenses) #:prefix license:)
>    #:use-module (guix build-system gnu)
>    #:use-module (guix gexp)
> +  #:use-module (guix utils)
>    #:use-module (guix git-download)
>    #:use-module (guix packages)
>    #:use-module (gnu packages)
> @@ -96,9 +97,21 @@ (define-public elixir
>              (lambda* (#:key inputs #:allow-other-keys)
>                ;; Some tests require access to a home directory.
>                (setenv "HOME" "/tmp")))
> -          (delete 'configure))))
> -    (inputs
> -     (list erlang git))
> +          (delete 'configure)
> +          (add-after 'install 'wrap-programs
> +            (lambda* (#:key inputs outputs #:allow-other-keys)
> +              (let* ((out (assoc-ref outputs "out"))
> +                     (programs '("elixir" "elixirc" "iex" "mix")))
> +                (for-each (lambda (program)
> +                            (wrap-program (string-append out "/bin/"
> program)
> +                              '("ERL_LIBS" prefix
> ("${GUIX_ERL_LIBS}"))))
> +                          programs)))))))
> +    (inputs (list erlang git))
> +    (native-search-paths
> +     (list (search-path-specification
> +            (variable "GUIX_ERL_LIBS")
> +            (files (list "lib/erlang/lib"
> +                         (string-append "lib/elixir/" (version-
> major+minor version)))))))
I suppose ERL is for erlang? What do we use for elixir then?
Toggle quote (395 lines)
>      (home-page "https://elixir-lang.org/")
>      (synopsis "Elixir programming language")
>      (description "Elixir is a dynamic, functional language used to
> build
> @@ -106,3 +119,46 @@ (define-public elixir
>  for running low-latency, distributed and fault-tolerant systems,
> while also
>  being successfully used in web development and the embedded software
> domain.")
>      (license license:asl2.0)))
> +
> +(define-public elixir-hex
> +  (package
> +    (name "elixir-hex")
> +    (version "2.0.5")
> +    (source
> +     (origin
> +       (method git-fetch)
> +       (uri (git-reference
> +             (url "https://github.com/hexpm/hex.git")
> +             (commit (string-append "v" version))))
> +       (file-name (git-file-name name version))
> +       (sha256
> +        (base32
> +         "1kvczwvij58kgkhak68004ap81pl26600bczg21mymy2sypkgxmj"))))
> +    ;; The mix-build-system assumes that Hex exists.
> +    ;; We build