From patchwork Sat Oct 28 20:19:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pierre-Henry_Fr=C3=B6hring?= X-Patchwork-Id: 55468 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 338B127BBE9; Sat, 28 Oct 2023 22:46:11 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,SPF_HELO_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id E47ED27BBE2 for ; Sat, 28 Oct 2023 22:46:04 +0100 (BST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qwr7t-0000xk-9o; Sat, 28 Oct 2023 17:45:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qwpnM-0005jT-5e for guix-patches@gnu.org; Sat, 28 Oct 2023 16:20:32 -0400 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qwpnL-0001Eg-6Y for guix-patches@gnu.org; Sat, 28 Oct 2023 16:20:31 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qwpnq-0002Uq-GQ; Sat, 28 Oct 2023 16:21:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#66801] [PATCH] mix-build-system: draft 1 Resent-From: Pierre-Henry =?utf-8?b?RnLDtmhyaW5n?= Original-Sender: "Debbugs-submit" Resent-CC: andrew@trop.in, cox.katherine.e+guix@gmail.com, liliana.prikler@gmail.com, guix-patches@gnu.org Resent-Date: Sat, 28 Oct 2023 20:21:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 66801 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 66801@debbugs.gnu.org Cc: Pierre-Henry =?utf-8?b?RnLDtmhyaW5n?= , Andrew Tropin , Katherine Cox-Buday , Liliana Marie Prikler X-Debbugs-Original-To: guix-patches@gnu.org X-Debbugs-Original-Xcc: Andrew Tropin , Katherine Cox-Buday , Liliana Marie Prikler Received: via spool by submit@debbugs.gnu.org id=B.16985244139520 (code B ref -1); Sat, 28 Oct 2023 20:21:02 +0000 Received: (at submit) by debbugs.gnu.org; 28 Oct 2023 20:20:13 +0000 Received: from localhost ([127.0.0.1]:39618 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qwpn3-0002TU-Gz for submit@debbugs.gnu.org; Sat, 28 Oct 2023 16:20:13 -0400 Received: from lists.gnu.org ([2001:470:142::17]:52880) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qwpn1-0002TF-5C for submit@debbugs.gnu.org; Sat, 28 Oct 2023 16:20:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qwpmP-0005al-0r for guix-patches@gnu.org; Sat, 28 Oct 2023 16:19:33 -0400 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qwpmJ-0000wc-Re for guix-patches@gnu.org; Sat, 28 Oct 2023 16:19:32 -0400 Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-407c3adef8eso26151435e9.2 for ; Sat, 28 Oct 2023 13:19:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=deeplinks-com.20230601.gappssmtp.com; s=20230601; t=1698524365; x=1699129165; darn=gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=cM9NmqsxnHWBq2XRPiJdAo6gDOFNqPn5QNQpP4/R6e8=; b=sfJVgHxtXOjQhnn5EI5RKwIkXnQf1BKFJYip9IrBikeMSBWE1dztX39NrsNpW3+zoZ 5zdO3wkSqHbFrvai6VfCa0Nb994KwhTzGWzWi2hD+my1iIH2HJRTb6S9K9wAjXEzAPbm AQusNOMzAqHZROscgVtv7gcI+E4YqFSkYr5hEqpKnCR4FP1UNxiiKVr9WDxsPcfQ/EyO scAOjTRW/mPYs5opWlYqQcZ5oNO9lNRWnJGInxYWs7oFMfHZnFjmk8Gzhot86ajEUbCf AdpZToWvdjqZalPvAFIaSdSshe2KCwC2ZHUj8zeNW0fzsH4wBQT4/omiDtnZo6LAaztx MlGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698524365; x=1699129165; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=cM9NmqsxnHWBq2XRPiJdAo6gDOFNqPn5QNQpP4/R6e8=; b=fM+RSJDLqWlO5G8PcbX5KRkYlEAsUABvgAzk4DCvKRusqOcgJuP1NB11lFyAaujuc3 3g8tSrjbDVfczi7gZTLCo+RqMyCVsQHuPFdGmCJ3+YOcON+w6aKZug8990Z+3geqzmc3 xWnSzC9IMNXKCevjP1MPvAxVCy6jR2OjFkJJAVdekGgkbUNS5cLXoiT3rO6ofAu3tDzr 8b6MXweJ2i9n8MtUt5RVm7Ahb+ityQsQ0OSu0xFDXcDRA4BdDkaONjrqyySoyXSugd0V LlpMaTXCtv/8c3smPdEOWUWEQbPMI1GTavNB+Rvq4DqTadBmAkH6QmskdgbXUocZb3Fa 81uQ== X-Gm-Message-State: AOJu0YxLOJfNAy75xeYslj2/SAz46iF9pZeF9RnGegELdKtRTHYxWxeA ZEI5e5aga29qBGDMAzFXeyey7X2jOZRxVX/xLFU= X-Google-Smtp-Source: AGHT+IGAayGXUH6iNr6jSx2ytURdDc8bgtgC9gzLHS3QloXt5wFs3DEMOgb+Iv+exUZl+9At89geQA== X-Received: by 2002:a05:600c:4f15:b0:3fe:687a:abb8 with SMTP id l21-20020a05600c4f1500b003fe687aabb8mr5204758wmq.7.1698524363395; Sat, 28 Oct 2023 13:19:23 -0700 (PDT) Received: from doug.home ([2a01:cb19:85a1:c200:ee66:fd17:945:f033]) by smtp.gmail.com with ESMTPSA id y9-20020a7bcd89000000b00407efbc4361sm8278509wmj.9.2023.10.28.13.19.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 28 Oct 2023 13:19:22 -0700 (PDT) From: Pierre-Henry =?utf-8?b?RnLDtmhyaW5n?= Date: Sat, 28 Oct 2023 22:19:10 +0200 Message-ID: <68117eb2b3e0e6adcc7449d878e602c7b831ffee.1698524350.git.phfrohring@deeplinks.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=phfrohring@deeplinks.com; helo=mail-wm1-x333.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-Mailman-Approved-At: Sat, 28 Oct 2023 17:45:46 -0400 X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org X-getmail-retrieved-from-mailbox: Patches 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 base-commit: 4dfbc536689b07e56aead3dd864b8af54613d091 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 +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (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 ;;; Copyright © 2021 Oskar Köök ;;; Copyright © 2021 Cees de Groot +;;; Copyright © 2023 Pierre-Henry Fröhring ;;; ;;; This file is part of GNU Guix. ;;; @@ -24,14 +25,21 @@ ;;; along with GNU Guix. If not, see . (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 - #: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: - ;; . - (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: + ;; . + (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-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 + (description + "Elixir is a dynamic, functional language used to build scalable and maintainable applications. Elixir leverages the Erlang VM, known 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 mix-hex + (package + (name "mix-hex") + (version "2.0.5") + (source + (origin + (method url-fetch) + (uri "https://builds.hex.pm/installs/1.14.0/hex-2.0.5.ez") + (sha256 + (base32 "0j4s17zsshq9hv3qxflcqrfwh4p27d2rv7xmgdmfdfxp086mfvry")))) + (build-system copy-build-system) + (native-inputs (list unzip)) + (arguments + (list + #:phases #~(modify-phases %standard-phases + (replace 'unpack + (lambda* (#:key source #:allow-other-keys) + ;; A *.ez file is a kind of *.zip file. + ;; See: https://www.erlang.org/doc/man/code#loading-of-code-from-archive-files + (invoke "unzip" source)))) + #:install-plan #~'(("hex-2.0.5" "lib/")))) + (synopsis "Package manager for the Erlang VM") + (description + "This project currently provides tasks that integrate with Mix, Elixir's build +tool.") + (home-page "https://hexdocs.pm/makeup_elixir/") + (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 +;;; functionality or similar names. +;;; diff --git a/gnu/packages/emacs-xyz.scm b/gnu/packages/emacs-xyz.scm index 10c4b0a6..13f07f20 100644 --- a/gnu/packages/emacs-xyz.scm +++ b/gnu/packages/emacs-xyz.scm @@ -135,6 +135,7 @@ ;;; Copyright © 2023 Sergiu Ivanov ;;; Copyright © 2023 Camilo Q.S. (Distopico) ;;; Copyright © 2023 Thanos Apollo +;;; Copyright © 2023 Pierre-Henry Fröhring ;;; ;;; This file is part of GNU Guix. ;;; @@ -7578,6 +7579,25 @@ (define-public emacs-org-fragtog your cursor steps onto them, and re-enabled when the cursor leaves.") (license license:gpl3+))) +(define-public emacs-erlang + (package + (name "emacs-erlang") + (version (package-version erlang)) + (source + (package-source erlang)) + (build-system emacs-build-system) + (arguments + `(#:phases (modify-phases %standard-phases + (add-before 'expand-load-path 'change-working-directory + (lambda _ + (chdir "lib/tools/emacs") #t))))) + (home-page "https://www.erlang.org/") + (synopsis "Erlang major mode for Emacs") + (description + "This package provides an Emacs major mode for editing Erlang source +files.") + (license license:asl2.0))) + (define-public emacs-ob-erlang (let ((revision "1") (commit "a029c23902b4ad73b84f262a7fc5b98d87b63dfd")) diff --git a/gnu/packages/erlang-xyz.scm b/gnu/packages/erlang-xyz.scm new file mode 100644 index 00000000..e1f1a77e --- /dev/null +++ b/gnu/packages/erlang-xyz.scm @@ -0,0 +1,650 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Pierre-Henry Fröhring +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see . + +(define-module (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-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))) + +(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))) + +(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))) + +(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))) + +(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))) + +(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))) + +(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))) + +(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))) + +(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-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))) + +(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-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-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-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-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") + (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") + (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-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") + (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") + (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") + (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") + (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") + (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 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") + (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") + (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-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") + (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-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") + (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 +;;; functionality or similar names. +;;; diff --git a/gnu/packages/erlang.scm b/gnu/packages/erlang.scm index c53cb72c..df17558b 100644 --- a/gnu/packages/erlang.scm +++ b/gnu/packages/erlang.scm @@ -10,6 +10,7 @@ ;;; Copyright © 2022 jgart ;;; Copyright © 2023 wrobell ;;; Copyright © 2023 Tim Johann +;;; Copyright © 2023 Pierre-Henry Fröhring ;;; ;;; This file is part of GNU Guix. ;;; @@ -27,160 +28,182 @@ ;;; along with GNU Guix. If not, see . (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 ((guix licenses) + #:prefix license:) + #: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 erlang-xyz) + #:use-module (gnu packages version-control) + #:use-module (gnu packages wxwidgets) + #:use-module (gnu packages) + #:use-module (guix build utils) + #: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 (name "erlang") (version "25.3.2") - (source (origin - (method git-fetch) - ;; The tarball from http://erlang.org/download contains many - ;; pre-compiled files, so we use this snapshot of the source - ;; repository. - (uri (git-reference - (url "https://github.com/erlang/otp") - (commit (string-append "OTP-" version)))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "092lym5a181gz89nscw7kqhw1wa6qvgcpkj80q4i9p79mxmsr1nj")) - (patches (search-patches "erlang-man-path.patch")))) + (source + (origin + (method git-fetch) + ;; The tarball from http://erlang.org/download contains many + ;; pre-compiled files, so we use this snapshot of the source + ;; repository. + (uri (git-reference + (url "https://github.com/erlang/otp") + (commit (string-append "OTP-" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "092lym5a181gz89nscw7kqhw1wa6qvgcpkj80q4i9p79mxmsr1nj")) + (patches (search-patches "erlang-man-path.patch")))) (build-system gnu-build-system) - (native-inputs - `(("perl" ,perl) + (native-inputs `(("perl" ,perl) - ;; Erlang's documentation is distributed in a separate tarball. - ("erlang-manpages" - ,(origin - (method url-fetch) - (uri (string-append "http://erlang.org/download/otp_doc_man_" - (version-major+minor version) ".tar.gz")) - (sha256 - (base32 - "0vnpds5q17xc4jjj3sbsllpx68wyhgvx70714vkzyd68rbjmhmk7")))))) - (inputs - (list ncurses openssl wxwidgets)) - (propagated-inputs - (list fontconfig glu mesa)) + ;; Erlang's documentation is distributed in a separate tarball. + ("erlang-manpages" ,(origin + (method url-fetch) + (uri (string-append + "http://erlang.org/download/otp_doc_man_" + (version-major+minor version) + ".tar.gz")) + (sha256 (base32 + "0vnpds5q17xc4jjj3sbsllpx68wyhgvx70714vkzyd68rbjmhmk7")))))) + (inputs (list ncurses openssl wxwidgets)) + (propagated-inputs (list fontconfig glu mesa)) (arguments `(#:test-target "release_tests" - #:configure-flags - (list "--disable-saved-compile-time" - "--enable-dynamic-ssl-lib" - "--enable-native-libs" - "--enable-shared-zlib" - "--enable-smp-support" - "--enable-threads" - "--enable-wx" - (string-append "--with-ssl=" (assoc-ref %build-inputs "openssl"))) - #:modules ((srfi srfi-19) ; make-time, et cetera. + #:configure-flags (list "--disable-saved-compile-time" + "--enable-dynamic-ssl-lib" + "--enable-native-libs" + "--enable-shared-zlib" + "--enable-smp-support" + "--enable-threads" + "--enable-wx" + (string-append "--with-ssl=" + (assoc-ref %build-inputs + "openssl"))) + #:modules ((srfi srfi-19) + ;make-time, et cetera. (guix build utils) (guix build gnu-build-system)) - #:phases - (modify-phases %standard-phases - (delete 'bootstrap) - ;; The are several code fragments that embed timestamps into the - ;; output. Here, we alter those fragments to use the value of - ;; SOURCE_DATE_EPOCH instead. - (add-after 'unpack 'remove-timestamps - (lambda _ - (let ((source-date-epoch - (time-utc->date - (make-time time-utc 0 (string->number - (getenv "SOURCE_DATE_EPOCH")))))) - (substitute* "lib/reltool/src/reltool_target.erl" - (("Date = date\\(\\),") - (string-append "Date = " - (date->string source-date-epoch - "'{~Y,~m,~d}',")))) - (substitute* "lib/reltool/src/reltool_target.erl" - (("Time = time\\(\\),") - (string-append "Time = " - (date->string source-date-epoch - "'{~H,~M,~S}',")))) - (substitute* '("lib/reltool/src/reltool_target.erl" - "lib/sasl/src/systools_make.erl") - (("date\\(\\), time\\(\\),") - (date->string source-date-epoch - "{~Y,~m,~d}, {~H,~M,~S},"))) - (substitute* "lib/dialyzer/test/small_SUITE_data/src/gs_make.erl" - (("tuple_to_list\\(date\\(\\)\\),tuple_to_list\\(time\\(\\)\\)") - (date->string - source-date-epoch - "tuple_to_list({~Y,~m,~d}), tuple_to_list({~H,~M,~S})"))) - (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl" - (("\\{Y,Mo,D\\} = date\\(\\),") - (date->string source-date-epoch - "{Y,Mo,D} = {~Y,~m,~d},"))) - (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl" - (("\\{H,Mi,S\\} = time\\(\\),") - (date->string source-date-epoch - "{H,Mi,S} = {~H,~M,~S},")))))) - (add-after 'unpack 'patch-/bin/sh - (lambda* (#:key inputs #:allow-other-keys) - (let ((sh (search-input-file inputs "/bin/sh"))) - (substitute* "erts/etc/unix/run_erl.c" - (("sh = \"/bin/sh\";") - (string-append "sh = \"" sh "\";"))) - (substitute* "erts/emulator/sys/unix/sys_drivers.c" - (("SHELL \"/bin/sh\"") - (string-append "SHELL \"" sh "\""))) - (substitute* "erts/emulator/sys/unix/erl_child_setup.c" - (("SHELL \"/bin/sh\"") - (string-append "SHELL \"" sh "\""))) - (substitute* "lib/kernel/src/os.erl" - (("/bin/sh") sh))))) - (add-after 'patch-source-shebangs 'patch-source-env - (lambda _ - (let ((escripts - (append - (find-files "." "\\.escript") - (find-files "lib/stdlib/test/escript_SUITE_data/") - '("erts/lib_src/utils/make_atomics_api" - "erts/preloaded/src/add_abstract_code" - "lib/diameter/bin/diameterc" - "lib/reltool/examples/display_args" - "lib/reltool/examples/mnesia_core_dump_viewer" - "lib/snmp/src/compile/snmpc.src" - "make/verify_runtime_dependencies" - "make/emd2exml.in")))) - (substitute* escripts - (("/usr/bin/env") (which "env")))))) - (add-before 'configure 'set-erl-top - (lambda _ - (setenv "ERL_TOP" (getcwd)))) - (add-after 'install 'patch-erl - ;; This only works after install. - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - (substitute* (string-append out "/bin/erl") - (("basename") (which "basename")) - (("dirname") (which "dirname")))))) - (add-after 'install 'install-doc - (lambda* (#:key inputs outputs #:allow-other-keys) - (let* ((out (assoc-ref outputs "out")) - (manpages (assoc-ref inputs "erlang-manpages")) - (share (string-append out "/share/"))) - (mkdir-p share) - (with-directory-excursion share - (invoke "tar" "xvf" manpages)))))))) + #:phases (modify-phases %standard-phases + (delete 'bootstrap) + ;; The are several code fragments that embed timestamps into the + ;; output. Here, we alter those fragments to use the value of + ;; SOURCE_DATE_EPOCH instead. + (add-after 'unpack 'remove-timestamps + (lambda _ + (let ((source-date-epoch (time-utc->date (make-time + time-utc 0 + (string->number + (getenv + "SOURCE_DATE_EPOCH")))))) + (substitute* "lib/reltool/src/reltool_target.erl" + (("Date = date\\(\\),") + (string-append "Date = " + (date->string source-date-epoch + "'{~Y,~m,~d}',")))) + (substitute* "lib/reltool/src/reltool_target.erl" + (("Time = time\\(\\),") + (string-append "Time = " + (date->string source-date-epoch + "'{~H,~M,~S}',")))) + (substitute* '("lib/reltool/src/reltool_target.erl" + "lib/sasl/src/systools_make.erl") + (("date\\(\\), time\\(\\),") + (date->string source-date-epoch + "{~Y,~m,~d}, {~H,~M,~S},"))) + (substitute* "lib/dialyzer/test/small_SUITE_data/src/gs_make.erl" + (("tuple_to_list\\(date\\(\\)\\),tuple_to_list\\(time\\(\\)\\)") + (date->string source-date-epoch + "tuple_to_list({~Y,~m,~d}), tuple_to_list({~H,~M,~S})"))) + (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl" + (("\\{Y,Mo,D\\} = date\\(\\),") + (date->string source-date-epoch + "{Y,Mo,D} = {~Y,~m,~d},"))) + (substitute* "lib/snmp/src/compile/snmpc_mib_to_hrl.erl" + (("\\{H,Mi,S\\} = time\\(\\),") + (date->string source-date-epoch + "{H,Mi,S} = {~H,~M,~S},")))))) + (add-after 'unpack 'patch-/bin/sh + (lambda* (#:key inputs #:allow-other-keys) + (let ((sh (search-input-file inputs "/bin/sh"))) + (substitute* "erts/etc/unix/run_erl.c" + (("sh = \"/bin/sh\";") + (string-append "sh = \"" sh "\";"))) + (substitute* "erts/emulator/sys/unix/sys_drivers.c" + (("SHELL \"/bin/sh\"") + (string-append "SHELL \"" sh "\""))) + (substitute* "erts/emulator/sys/unix/erl_child_setup.c" + (("SHELL \"/bin/sh\"") + (string-append "SHELL \"" sh "\""))) + (substitute* "lib/kernel/src/os.erl" + (("/bin/sh") + sh))))) + (add-after 'patch-source-shebangs 'patch-source-env + (lambda _ + (let ((escripts (append (find-files "." "\\.escript") + (find-files + "lib/stdlib/test/escript_SUITE_data/") + '("erts/lib_src/utils/make_atomics_api" + "erts/preloaded/src/add_abstract_code" + "lib/diameter/bin/diameterc" + "lib/reltool/examples/display_args" + "lib/reltool/examples/mnesia_core_dump_viewer" + "lib/snmp/src/compile/snmpc.src" + "make/verify_runtime_dependencies" + "make/emd2exml.in")))) + (substitute* escripts + (("/usr/bin/env") + (which "env")))))) + (add-before 'configure 'set-erl-top + (lambda _ + (setenv "ERL_TOP" + (getcwd)))) + (add-after 'install 'patch-erl + ;; This only works after install. + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (substitute* (string-append out "/bin/erl") + (("basename") + (which "basename")) + (("dirname") + (which "dirname")))))) + (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")) + (share (string-append out "/share/"))) + (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 @@ -191,414 +214,13 @@ (define-public erlang built-in support for concurrency, distribution and fault tolerance.") ;; Erlang is distributed under the Apache License 2.0, but some components ;; have other licenses. See 'system/COPYRIGHT' in the source distribution. - (license (list license:asl2.0 license:bsd-2 license:bsd-3 license:expat - license:lgpl2.0+ license:tcl/tk license:zlib)))) - -(define-public emacs-erlang - (package - (name "emacs-erlang") - (version (package-version erlang)) - (source (package-source erlang)) - (build-system emacs-build-system) - (arguments - `(#:phases - (modify-phases %standard-phases - (add-before 'expand-load-path 'change-working-directory - (lambda _ (chdir "lib/tools/emacs") #t))))) - (home-page "https://www.erlang.org/") - (synopsis "Erlang major mode for Emacs") - (description - "This package provides an Emacs major mode for editing Erlang source -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 "bbmustache" version)) - (sha256 - (base32 "0fvvaxdpziygxl30j59g98qkh2n47xlb7w5dfpsm2bfcsnj372v8")))) - (build-system rebar-build-system) - (inputs - (list erlang-getopt 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-certifi - (package - (name "erlang-certifi") - (version "2.9.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "certifi" 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") - (version "0.3.1") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "cf" 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") - (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") - (version "2.0.4") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "covertool" 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") - (version "1.5.1") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "cth_readable" 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-edown - (package - (name "erlang-edown") - (version "0.8.4") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "edown" 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") - (version "1.6.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "erlware_commons" 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") - (version "0.5.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "eunit_formatters" 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-getopt - (package - (name "erlang-getopt") - (version "1.0.2") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "getopt" 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") - (version "0.8.4") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "hex_core" 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 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") - (version "1.7.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "jsone" 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") - (version "3.4.1") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "parse_trans" 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 erlang-proper - (package - (name "erlang-proper") - (version "1.4.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "proper" 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") - (version "3.1.0") - (source (origin - (method url-fetch) - (uri (hexpm-uri "jsx" 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") - (version "1.9.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "providers" 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-relx - (package - (name "erlang-relx") - (version "4.6.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "relx" 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") - (version "1.1.6") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "ssl_verify_fun" 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))) + (license (list license:asl2.0 + license:bsd-2 + license:bsd-3 + license:expat + license:lgpl2.0+ + license:tcl/tk + license:zlib)))) (define-public rebar3 (package @@ -616,56 +238,71 @@ (define-public rebar3 (build-system gnu-build-system) ;; TODO: remove vendored modules, install man-page, install lib(?) (arguments - `(#:phases - (modify-phases %standard-phases - (delete 'bootstrap) - (add-after 'unpack 'unpack-dependency-sources - (lambda* (#:key inputs #:allow-other-keys) - (for-each - (lambda (pkgname) - (let* ((src (string-append pkgname "-source")) - (input (assoc-ref inputs src)) - (checkouts-dir (string-append "_checkouts/" pkgname)) - (lib-dir (string-append "_build/default/lib/" pkgname))) - (mkdir-p checkouts-dir) - (invoke "tar" "-xf" input "-C" checkouts-dir) - (invoke "tar" "-xzf" - (pk (string-append checkouts-dir "/contents.tar.gz")) - "-C" checkouts-dir) - (mkdir-p lib-dir) - (copy-recursively checkouts-dir lib-dir))) - (list "bbmustache" "certifi" "cf" "cth_readable" - "eunit_formatters" "getopt" "hex_core" "erlware_commons" - "parse_trans" "relx" "ssl_verify_fun" "providers")))) - (delete 'configure) - (replace 'build - (lambda _ - (setenv "HOME" (getcwd)) - (invoke "./bootstrap"))) - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let* ((out (assoc-ref outputs "out"))) - (install-file "rebar3" (string-append out "/bin"))))) - (delete 'check)))) - (native-inputs - (list erlang)) - (inputs - `(("bbmustache-source" ,(package-source erlang-bbmustache)) - ("certifi-source" ,(package-source erlang-certifi)) - ("cf-source" ,(package-source erlang-cf)) - ("cth_readable-source" ,(package-source erlang-cth-readable)) - ("erlware_commons-source" ,(package-source erlang-erlware-commons)) - ("eunit_formatters-source" ,(package-source erlang-eunit-formatters)) - ("getopt-source" ,(package-source erlang-getopt)) - ("hex_core-source" ,(package-source erlang-hex-core)) - ("parse_trans-source" ,(package-source erlang-parse-trans)) - ("relx-source" ,(package-source erlang-relx)) - ("ssl_verify_fun-source" ,(package-source erlang-ssl-verify-fun)) - ("providers-source" ,(package-source erlang-providers)))) + `(#:phases (modify-phases %standard-phases + (delete 'bootstrap) + (add-after 'unpack 'unpack-dependency-sources + (lambda* (#:key inputs #:allow-other-keys) + (for-each (lambda (pkgname) + (let* ((src (string-append pkgname "-source")) + (input (assoc-ref inputs src)) + (checkouts-dir (string-append + "_checkouts/" pkgname)) + (lib-dir (string-append + "_build/default/lib/" + pkgname))) + (mkdir-p checkouts-dir) + (invoke "tar" "-xf" input "-C" + checkouts-dir) + (invoke "tar" "-xzf" + (pk (string-append checkouts-dir + "/contents.tar.gz")) "-C" + checkouts-dir) + (mkdir-p lib-dir) + (copy-recursively checkouts-dir lib-dir))) + (list "bbmustache" + "certifi" + "cf" + "cth_readable" + "eunit_formatters" + "getopt" + "hex_core" + "erlware_commons" + "parse_trans" + "relx" + "ssl_verify_fun" + "providers")))) + (delete 'configure) + (replace 'build + (lambda _ + (setenv "HOME" + (getcwd)) + (invoke "./bootstrap"))) + (replace 'install + (lambda* (#:key outputs #:allow-other-keys) + (let* ((out (assoc-ref outputs "out"))) + (install-file "rebar3" + (string-append out "/bin"))))) + (delete 'check)))) + (native-inputs (list erlang)) + (inputs `(("bbmustache-source" ,(package-source erlang-bbmustache)) + ("certifi-source" ,(package-source erlang-certifi)) + ("cf-source" ,(package-source erlang-cf)) + ("cth_readable-source" ,(package-source erlang-cth-readable)) + ("erlware_commons-source" ,(package-source + erlang-erlware-commons)) + ("eunit_formatters-source" ,(package-source + erlang-eunit-formatters)) + ("getopt-source" ,(package-source erlang-getopt)) + ("hex_core-source" ,(package-source erlang-hex-core)) + ("parse_trans-source" ,(package-source erlang-parse-trans)) + ("relx-source" ,(package-source erlang-relx)) + ("ssl_verify_fun-source" ,(package-source erlang-ssl-verify-fun)) + ("providers-source" ,(package-source erlang-providers)))) (home-page "https://rebar3.org/") (synopsis "Sophisticated build-tool for Erlang projects that follows OTP principles") - (description "@code{rebar3} is an Erlang build tool that makes it easy to + (description + "@code{rebar3} is an Erlang build tool that makes it easy to compile and test Erlang applications, port drivers and releases. @code{rebar3} is a self-contained Erlang script, so it's easy to distribute or @@ -676,84 +313,19 @@ (define-public rebar3 of locations (git, hg, etc).") (license license:asl2.0))) -(define-public rebar3-raw-deps - (package - (name "rebar3-raw-deps") - (version "2.0.0") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "rebar3_raw_deps" 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 rebar3-git-vsn - (package - (name "rebar3-git-vsn") - (version "1.1.1") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "rebar3_git_vsn" 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 rebar3-proper - (package - (name "rebar3-proper") - (version "0.12.1") - (source - (origin - (method url-fetch) - (uri (hexpm-uri "rebar3_proper" 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") (version "2.1.2") - (source (origin - (method git-fetch) - (uri (git-reference - (url "https://github.com/lfe/lfe") - (commit "v2.1.2"))) - (file-name (git-file-name name version)) - (sha256 - (base32 - "180hz1p2v3vb6yyzcfwircmljlnd86ln8z80lzy3mwlyrcxblvxy")))) + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/lfe/lfe") + (commit "v2.1.2"))) + (file-name (git-file-name name version)) + (sha256 + (base32 "180hz1p2v3vb6yyzcfwircmljlnd86ln8z80lzy3mwlyrcxblvxy")))) (build-system gnu-build-system) (arguments (list @@ -761,49 +333,47 @@ (define-public erlang-lfe (srfi srfi-26) (guix build gnu-build-system) (guix build utils)) - #:make-flags #~(list (string-append "PREFIX=" #$output) "CC=gcc") - #:phases - #~(modify-phases %standard-phases - (delete 'configure) - ;; The following is inspired by rebar-build-system.scm - (add-before 'check 'erlang-depends - (lambda* (#:key inputs #:allow-other-keys) - (define input-directories - (list #$(this-package-native-input "rebar3-proper") - #$(this-package-native-input "erlang-proper"))) - (mkdir-p "_checkouts") - (for-each - (lambda (input-dir) - (let ((elibdir (string-append input-dir "/lib/erlang/lib"))) - (when (directory-exists? elibdir) - (for-each - (lambda (dirname) - (let ((src (string-append elibdir "/" dirname)) - (dest (string-append "_checkouts/" dirname))) - (when (not (file-exists? dest)) - ;; Symlinking will not work, since rebar3 will try - ;; to overwrite the _build directory several times - ;; with the contents of _checkout, so we copy the - ;; directory tree to _checkout and make it - ;; writable. - (copy-recursively src dest #:follow-symlinks? #t) - (for-each (cut chmod <> #o777) - (find-files dest))))) - (scandir elibdir (lambda (file) - (and (not (member file '("." ".."))) - (file-is-directory? - (string-append elibdir - "/" - file))))))))) - input-directories))) - (replace 'check - (lambda* (#:key tests? #:allow-other-keys) - (when tests? - (begin - (setenv "REBAR_CACHE_DIR" "/tmp") - (invoke "make" "-j" (number->string (parallel-job-count)) - "tests")))))))) - (native-inputs (list rebar3 rebar3-proper erlang-proper)) + #:make-flags #~(list (string-append "PREFIX=" + #$output) "CC=gcc") + #:phases #~(modify-phases %standard-phases + (delete 'configure) + ;; The following is inspired by rebar-build-system.scm + (add-before 'check 'erlang-depends + (lambda* (#:key inputs #:allow-other-keys) + (define input-directories + (list #$(this-package-native-input "rebar3-proper") + #$(this-package-native-input "erlang-proper"))) + (mkdir-p "_checkouts") + (for-each + (lambda (input-dir) + (let ((elibdir (string-append input-dir "/lib/erlang/lib"))) + (when (directory-exists? elibdir) + (for-each + (lambda (dirname) + (let ((src (string-append elibdir "/" dirname)) + (dest (string-append "_checkouts/" dirname))) + (when (not (file-exists? dest)) + ;; Symlinking will not work, since rebar3 will try + ;; to overwrite the _build directory several times + ;; with the contents of _checkout, so we copy the + ;; directory tree to _checkout and make it + ;; writable. + (copy-recursively src dest #:follow-symlinks? #t) + (for-each (cut chmod <> 511) (find-files dest))))) + (scandir elibdir + (lambda (file) + (and (not (member file '("." ".."))) + (file-is-directory? (string-append elibdir "/" file))))))))) + input-directories))) + (replace 'check + (lambda* (#:key tests? #:allow-other-keys) + (when tests? + (begin + (setenv "REBAR_CACHE_DIR" "/tmp") + (invoke "make" "-j" + (number->string (parallel-job-count)) + "tests")))))))) + (native-inputs (list rebar3 erlang-rebar3-proper erlang-proper)) (propagated-inputs (list erlang)) (home-page "https://github.com/lfe/lfe") (synopsis "Lisp Flavoured Erlang") @@ -812,3 +382,9 @@ (define-public erlang-lfe compiler. Code produced with it is compatible with \"normal\" Erlang code. An LFE evaluator and shell is also included.") (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 +;;; functionality or similar names. +;;; diff --git a/guix/build-system/mix.scm b/guix/build-system/mix.scm new file mode 100644 index 00000000..8201b715 --- /dev/null +++ b/guix/build-system/mix.scm @@ -0,0 +1,185 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Pierre-Henry Fröhring +;;; +;;; 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 . + +;; 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 (guix build mix-build-system) + #:use-module (guix build-system gnu) + #:use-module (guix build-system) + #:use-module (guix search-paths) + #:use-module (guix monads) + #:use-module (guix packages) + #:use-module (guix store) + #:use-module (guix gexp) + #:use-module (guix utils) + #:export (mix-build-system hexpm-uri)) + +;; +;; hexpm +;; + +(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")) + +;; +;; utils +;; + +(define utils-locales + (make-glibc-utf8-locales glibc + #:locales (list "en_US") + #:name "glibc-utf8-locales")) + +(define (utils-elixir-default) + "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 utils-imported-modules + `((guix build mix-build-system) + ,@%gnu-build-system-modules)) + +(define utils-modules + '((guix build mix-build-system) + (guix build utils))) + +;; +;; mix +;; + +(define* (mix-build name + inputs + #:key source + (tests? #t) + (phases '%standard-phases) + (outputs '("out")) + (search-paths '()) + (system (%current-system)) + (guile #f) + (imported-modules utils-imported-modules) + (modules utils-modules)) + "Build SOURCE using Elixir, and with INPUTS." + + (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? + #: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* (mix-lower name + #:key source + inputs + native-inputs + outputs + system + target + (elixir (utils-elixir-default)) + #:allow-other-keys #:rest arguments) + "Return a bag for NAME." + + ;; The value associated to these keywords are used in the bag below and are + ;; not to be used in the arguments. + (define private-keywords + '(#:inputs #:native-inputs #:outputs #:system #:target #:elixir)) + + ;; All that is necessary to complete the build. + (define build-inputs + ;; If these packages are not present, then Elixir emits these errors: + ;; dirname: command not found + ;; basename: command not found + `(,@(standard-packages) + + ;; If no UTF-8 is present, then Elixir emits this warning: + ;; + ;; warning: the VM is running with native name encoding of latin1 + ;; which may cause Elixir to malfunction as it expects utf8. Please + ;; ensure your locale is set to UTF-8 (which can be verified by + ;; running "locale" in your shell) + ("glibc-utf8-locales" ,utils-locales) + + ("elixir" ,elixir) + + ;; If Hex is not present, mix cannot build packages. + ("mix-hex" ,mix-hex) + + ,@native-inputs + + ,@inputs)) + + (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 (strip-keyword-arguments private-keywords arguments)))) + +(define mix-build-system + (build-system (name 'mix) + (description "The standard Mix build system") + (lower mix-lower))) + +;;; mix.scm ends here diff --git a/guix/build-system/rebar.scm b/guix/build-system/rebar.scm index de1294ec..e1258a78 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 ;;; Copyright © 2020 Hartmut Goebel +;;; Copyright © 2023 Pierre-Henry Fröhring ;;; ;;; This file is part of GNU Guix. ;;; @@ -21,99 +22,171 @@ (define-module (guix build-system rebar) #:use-module (guix store) #:use-module (guix utils) #:use-module (guix gexp) + #:use-module (ice-9 regex) #:use-module (guix packages) #:use-module (guix monads) #:use-module (guix search-paths) + #:use-module (ice-9 match) #: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 (srfi srfi-1) + #:export (hexpm-uri hexpm-package-url %rebar-build-system-modules + rebar-build rebar-build-system)) ;;; -;;; Definitions for the hex.pm repository, +;;; pkg-name ;;; -;; URL and paths from -;; https://github.com/hexpm/specifications/blob/master/endpoints.md -(define %hexpm-repo-url +(define pkg-name-prefix + "erlang-") + +;; Pattern that an Erlang Guix package is expected to match. +(define pkg-name-prefix-re + (format #f "^~a(.*)" pkg-name-prefix)) + +(define (pkg-name->match name) + "Return the match object from NAME if NAME starts with pkg-name-prefix." + (string-match pkg-name-prefix-re name)) + +(define (pkg-name? name) + "Test if NAME is the name of an Erlang Guix package. + +Example: erlang-ssl-verify-fun is the name of an Erlang Guix package." + (or (pkg-name->match name) #f)) + +(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* (pkg-name->library-directory-name name + #:key (version "")) + "Return the name of the library directory associated to NAME. + +Example: if an Erlang Guix package name is \"erlang-ssl-verify-fun\" and its +version is 1.2.3, then the associated library directory name is: +\"ssl_verify_fun-1.2.3\". + +See: + - \"Library directory\" description: https://www.erlang.org/doc/man/code#code-path +" + (string-append (string-replace-substring (pkg-name->suffix name) "-" "_") + (if (string= version "") "" + (string-append "-" version)))) + +;;; +;;; hexpm +;;; + +;; See: https://github.com/hexpm/specifications/blob/master/endpoints.md +(define hexpm (make-parameter "https://repo.hex.pm")) -(define hexpm-package-url - (string-append (%hexpm-repo-url) "/tarballs/")) +(define hexpm-tarballs + (string-append (hexpm) "/tarballs/")) -(define (hexpm-uri name version) +(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. + +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 (warn-about name) + (format #t "AssertionWarning 4dcbff27 + Assertion: re matches name. + re = ~a + name = ~a +" pkg-name-prefix-re name) name) + + (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))) ;; -;; Standard build procedure for Erlang packages using Rebar. +;; utils ;; -(define %rebar-build-system-modules - ;; Build-side modules imported by default. - `((guix build rebar-build-system) - ,@%gnu-build-system-modules)) - -(define (default-rebar3) - "Return the default Rebar3 package." +(define (utils-rebar-default) ;; Lazily resolve the binding to avoid a circular dependency. (let ((erlang-mod (resolve-interface '(gnu packages erlang)))) - (module-ref erlang-mod 'rebar3))) + (module-ref erlang-mod + 'rebar3))) -(define (default-erlang) - "Return the default Erlang package." +(define (utils-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)))) + (module-ref erlang-mod + 'erlang))) + +(define utils-imported-modules + `((guix build rebar-build-system) + ,@%gnu-build-system-modules)) + +;; +;; source +;; +;; If s is a Source, then s has the form (list ) where: +;; is a string representing the name of a library directory. +;; is an origin (see: guix/packages.scm) which represents the +;; source code associated to this library. +;; + +(define source->name + car) +(define source->origin + cadr) + +;; +;; input +;; +;; If i is an Input, then i has the form (list ) where: +;; is a string representing the name of a package. +;; is a package with the associated name. + +(define input->name + car) +(define input->package + cadr) + +(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))))) + +;; +;; rebar +;; + +(define* (rebar-build name + inputs + #:key guile + source + ;; XXX: these are useless. + (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 utils-imported-modules) + (modules '((guix build rebar-build-system) + (guix build utils))) + (sources-erlang '())) "Build SOURCE with INPUTS." (define builder @@ -122,35 +195,94 @@ (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* (rebar-lower name + #:key (erlang (utils-erlang-default)) + inputs + native-inputs + outputs + (rebar (utils-rebar-default)) + source + system + target + #:allow-other-keys #:rest arguments) + "Return a bag for NAME from the given arguments." + + (let* ((erlang-packages ;List of Erlang packages. + (filter (lambda (input) + (pkg-name? (input->name input))) + (append inputs native-inputs))) + + (erlang-sources (map (lambda (input) + (input->source input)) 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 rebar-lower))) + +;;; +;;; Exports +;;; + +(define hexpm-uri + hexpm->uri) + +(define hexpm-package-url + hexpm-tarballs) + +(define %rebar-build-system-modules + utils-imported-modules) diff --git a/guix/build/mix-build-system.scm b/guix/build/mix-build-system.scm new file mode 100644 index 00000000..1d17ae49 --- /dev/null +++ b/guix/build/mix-build-system.scm @@ -0,0 +1,373 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2023 Pierre-Henry Fröhring +;;; +;;; 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 . + +;; Commentary: +;; +;; Builder-side code of the standard Mix package build procedure. +;; +;; The standard procedure is presented here: +;; https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html#project-compilation +;; +;; It boils down to: +;; 1) MIX_ENV=prod mix compile +;; 2) mix test +;; +;; Most of the code here comes from the necessity to convince mix to compile +;; without accessing the network. Here is the procedure adapted for Guix: +;; if: +;; 1) `' is an archive of a package downloaded from hex.pm. +;; See: https://github.com/hexpm/specifications/blob/main/package_tarball.md +;; 2) `' is the name of the Hex library, e.g. hex-2.0.5. +;; `' is the path in the store of Hex. +;; See: `(gnu packages elixir)' +;; +;; then the steps to build a package pkg are: +;; 1) tar +;; 2) tar contents.tar.gz +;; 3) export MIX_ENV=prod +;; 4) export MIX_HOME=.mix +;; 5) export MIX_ARCHIVES="$(MIX_HOME)"/archives +;; 6) mkdir -p "$(MIX_ARCHIVES)" +;; 7) ln -snd /lib/ "$(MIX_ARCHIVES)"// +;; 8) is either `prod' or `shared' depending on mix.exs +;; see: `build_per_environment' in mix documentation. +;; 9) For all Elixir or Erlang package p in inputs, we have the name +;; of the associated library (e.g. hex-2.0.5). We must: +;; install p under _build//lib/ +;; install p source _build//lib/ +;; 10) mix compile --no-deps-check +;; 11) mix test --no-deps-check +;; 12) install build artifacts under #$out/lib/elixir/X.Y/ +;; where X and Y are the major and minor version numbers of Elixir. +;; +;; Code: + +(define-module (guix build mix-build-system) + #:use-module (guix build utils) + #:use-module ((guix build gnu-build-system) + #:prefix gnu:) + #:use-module (ice-9 regex) + #:use-module (ice-9 ftw) + #:use-module (srfi srfi-1) + #:export (mix-build strip-elixir-prefix %standard-phases)) + +;; +;; version +;; + +;; XXX: copied from (guix utils) since not available from the build side. +;; XXX: There may be a way to avoid this duplicated code? +(define (version-prefix version-string num-parts) + "Truncate version-string to the first num-parts components of the version. +For example, (version-prefix \"2.1.47.4.23\" 3) returns \"2.1.47\"" + (string-join (take (string-split version-string #\.) num-parts) ".")) + +;; XXX: copied from (guix utils) since not available from the build side. +;; XXX: There may be a way to avoid this duplicated code? +(define (version-major+minor version-string) + "Return \".\", where major and minor are the major and +minor version numbers from version-string." + (version-prefix version-string 2)) + +;; +;; pkg +;; + +;; The prefix of Elixir packages as a regular expression. +(define pkg-elixir-prefix + "^elixir-") + +;; The prefix of Erlang packages as a regular expression. +(define pkg-erlang-prefix + "^erlang-") + +(define (pkg-name->library-name name) + "Return the name of the Mix project deduced from the name of the Guix package. + +For example: elixir-a-pkg-1.0.2 → a_pkg" + + (let* ((re (format #f "~a(.*)" pkg-elixir-prefix)) + (re-match (string-match re name)) + (name-version (if re-match + (regexp-substitute #f re-match 1) + (error (format #f "AssertionError d722a480 + Assertion: re matches name. + re = ~a + name = ~a" re + name))))) + + ;; A snake_case name. + (string-join (drop-right (string-split name-version #\-) 1) "_"))) + +(define (pkg->dir-install elixir-store pkg-store pkg-name) + "Return the path under the path PKG-STORE where to install the package named PKG-NAME given the path of the Elixir used to build ELIXIR-STORE. + +Example: + - if: + - elixir-store = /gnu/store/…elixir-1.14.0 + - pkg-store = /gnu/store/…kv-1.0.0 + - pkg-name = elixir-kv + - then: + - (pkg->dir-install elixir-store pkg-store pkg-name) = /gnu/store/…kv-1.0.0/lib/elixir/1.14/kv" + (let ((X.Y (path->elixir-X.Y elixir-store)) + (lib-name (pkg-name->library-name pkg-name))) + (string-append (path->elixir-lib pkg-store X.Y) "/" lib-name))) + +;; +;; mix +;; + +;; See: https://hexdocs.pm/mix/1.15.7/Mix.html#module-environments +(define mix-MIX_HOME + "MIX_HOME") +(define mix-MIX_ENV + "MIX_ENV") +(define mix-MIX_ENV-prod + "prod") + +(define (mix-target-dir) + "Return the directory where build artifacts are to be installed according to +MIX_ENV in the current directory." + + (format #f "_build/~a/lib" + (getenv mix-MIX_ENV))) + +;; +;; path +;; + +(define (path->elixir-lib path X.Y) + "Return the path of the directory where libraries of an Elixir package are installed in the store." + (string-append path "/lib/elixir/" X.Y)) + +(define (path->erlang-lib 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 (path->elixir-X.Y elixir) + "Given a path in the store where elixir has been installed, return its +version as X.Y where X and Y are its major and minor versions." + (let ((version (last (string-split elixir #\-)))) + (version-major+minor version))) + +;; +;; phase +;; + +(define* (phase-unpack #:key source #:allow-other-keys) + "Unpack SOURCE." + (invoke "tar" "xvf" source) + (invoke "tar" "xvf" "contents.tar.gz")) + +(define* (phase-configure-mix-env #:key (mix-env mix-MIX_ENV-prod) + #:allow-other-keys) + "Set default MIX_ENV." + + (let ((values (list mix-MIX_ENV-prod "shared"))) + (when (not (member mix-env values string=?)) + (error (format #f "AssertionError 45f9a67d + Assertion: mix-env is one of values. + values = ~a +" values))) + (setenv mix-MIX_ENV mix-env))) + +(define* (phase-install-hex #:key inputs name #:allow-other-keys) + "Install Hex." + + (let* ((hex-lib (string-append (assoc-ref inputs "mix-hex") "/lib")) + (hex-name (last (scandir hex-lib))) + (MIX_ARCHIVES "MIX_ARCHIVES") + (hex-archive-path "")) + + (setenv mix-MIX_HOME ".mix") + (setenv MIX_ARCHIVES + (string-append (getenv mix-MIX_HOME) "/archives")) + (set! hex-archive-path + (string-append (getenv MIX_ARCHIVES) "/" hex-name)) + (mkdir-p hex-archive-path) + (symlink (string-append hex-lib "/" hex-name) + (string-append hex-archive-path "/" hex-name)))) + +;; Below are definitions useful to understand the following code. +;; +;; - « p : StorePath » means that « p is a String that represents a path of a +;; package in the store ». +;; +;; - « i : Input » means that i has the form (key . path) where key : String that +;; represent the name of a package and path : StorePath. +;; +;; - « al : AList » means that « al is an Association List ». +;; +;; - « al : AList Input » means that « al is an Association List of Input ». +;; +;; - « p : Pkg » means that p has the form (type . path) where type is either +;; 'erlang or 'elixir and path : StorePath. +;; +;; - « l : Lib » means that p has the form (lib-name . lib-path) where +;; lib-name is the name of an Erlang or Elixir library and lib-path is its path. +(define* (phase-install-dependencies #:key inputs #:allow-other-keys) + "Install dependencies." + + (let ((target-dir (mix-target-dir)) + (X.Y (path->elixir-X.Y (assoc-ref inputs "elixir")))) + + ;; Where to install the dependencies. + (mkdir-p target-dir) + + (define (install-lib lib) + "Install a Lib LIB under target-dir." + ;; XXX: use match + (let ((lib-name (car lib)) + (lib-path (cdr lib))) + (let ((target (string-append target-dir "/" lib-name))) + (symlink lib-path target)))) + + (define (install-libs libraries) + "Install the set of the list of Lib LIBRARIES under target-dir." + (for-each (lambda (lib) + (install-lib lib)) libraries)) + + (define (pkg->libraries pkg) + "Return the list of Lib libraries associated to a Pkg." + ;; XXX: use match + (let* ((pkg-type (car pkg)) + (pkg-path (cdr pkg)) + (lib-folder (cond + ((eq? pkg-type + 'elixir) + (path->elixir-lib pkg-path X.Y)) + ((eq? pkg-type + 'erlang) + (path->erlang-lib pkg-path))))) + (map (lambda (lib-name) + (cons lib-name + (string-append lib-folder "/" lib-name))) + (drop (scandir lib-folder) 2)))) + + (define (install-pkg-libraries pkg) + "Install all libraries of a given Pkg PKG under target-dir." + (install-libs (pkg->libraries pkg))) + + (define (input->pkg input) + "Return a Pkg if Input INPUT is an Erlang or Elixir Input else #f." + (let ((type? (cond + ((string-match pkg-erlang-prefix + (car input)) + 'erlang) + ((string-match pkg-elixir-prefix + (car input)) + 'elixir) + (#t #f)))) + (if type? + (cons type? + (cdr input)) #f))) + + (define (inputs->pkgs inputs) + "Return the a list of Pkg, one for each Erlang or Elixir Input in INPUTS." + (filter pair? + (map input->pkg inputs))) + + (for-each (lambda (pkg) + (install-pkg-libraries pkg)) + (inputs->pkgs inputs)))) + +(define* (phase-build . args_ignored) + "Builds the Mix project according to MIX_ENV." + (invoke "mix" "compile" "--no-deps-check")) + +(define* (phase-check #:key (tests? #t) name #:allow-other-keys) + "Test the Mix project." + (if tests? + (begin + (let ((mix-env (getenv mix-MIX_ENV))) + (setenv mix-MIX_ENV "test") + (invoke "mix" "test" "--no-deps-check") + (setenv mix-MIX_ENV mix-env))) + (format #t "Tests have been skipped since test? parameter value was: ~a. +" + tests?))) + +(define* (phase-remove-mix-dirs . ignored_args) + "Remove all .mix/ directories." + (let ((mix-dirs (find-files "." + (file-name-predicate (format #f "\\~a$" + (getenv + mix-MIX_HOME))) + #:directories? #t))) + (for-each (lambda (mix-dir) + (delete-file-recursively mix-dir)) mix-dirs))) + +(define* (phase-install #:key inputs outputs name #:allow-other-keys) + "Install build artifacts in the store." + (let ((dir-build (string-append (mix-target-dir) "/" + (pkg-name->library-name name))) + (dir-install (pkg->dir-install (assoc-ref inputs "elixir") + (assoc-ref outputs "out") name))) + (mkdir-p dir-install) + (copy-recursively dir-build dir-install + #:follow-symlinks? #t))) + +(define mix-%standard-phases + (modify-phases gnu:%standard-phases + (delete 'bootstrap) + (delete 'configure) + (replace 'unpack + phase-unpack) + (add-after 'unpack 'condifure-mix-env + phase-configure-mix-env) + (add-after 'patch-generated-file-shebangs 'install-hex + phase-install-hex) + (add-after 'install-hex 'install-dependencies + phase-install-dependencies) + (replace 'build + phase-build) + (replace 'check + phase-check) + (add-before 'install 'remove-mix-dirs + phase-remove-mix-dirs) + (replace 'install + phase-install))) + +(define* (mix-build #:key inputs + (phases mix-%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)) + +;; +;; This section gather exports. +;; + +(define (strip-elixir-prefix name) + (let* ((re (format #f "~a(.*)" pkg-elixir-prefix)) + (re-match (string-match re name))) + + (if re-match + (regexp-substitute #f re-match 1) + (error (format #f "AssertionError d722a480 + Assertion: re matches name. + re = ~a + name = ~a" re name))))) + +(define %standard-phases + mix-%standard-phases) + +;;; mix-build-system.scm ends here diff --git a/guix/build/rebar-build-system.scm b/guix/build/rebar-build-system.scm index fb664228..80813225 100644 --- a/guix/build/rebar-build-system.scm +++ b/guix/build/rebar-build-system.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2016, 2018 Ricardo Wurmus ;;; Copyright © 2019 Björn Höfling ;;; Copyright © 2020, 2022 Hartmut Goebel +;;; Copyright © 2023 Pierre-Henry Fröhring ;;; ;;; This file is part of GNU Guix. ;;; @@ -19,129 +20,222 @@ ;;; along with GNU Guix. If not, see . (define-module (guix build rebar-build-system) - #:use-module ((guix build gnu-build-system) #:prefix gnu:) - #:use-module ((guix build utils) #:hide (delete)) + #:use-module ((guix build gnu-build-system) + #:prefix gnu:) + #: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 -(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* (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) - (apply invoke `("rebar3" "compile" ,@rebar-flags))) - -(define* (check #:key target (rebar-flags '()) (tests? (not target)) - (test-target "eunit") - #:allow-other-keys) - (if tests? - (apply invoke `("rebar3" ,test-target ,@rebar-flags)) - (format #t "test suite not run~%"))) +;; +;; utils +;; -(define (erlang-package? name) - "Check if NAME correspond to the name of an Erlang package." - (string-prefix? "erlang-" name)) - -(define (package-name-version->erlang-name name+ver) - "Convert the Guix package NAME-VER to the corresponding Erlang 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 (erlang-package? name-) ; checks for "erlang-" prefix - (string-drop name- (string-length "erlang-")) - name-) - #\-) - "_"))) - -(define (list-directories directory) +(define (utils-list-directories directory) "Return file names of the sub-directory of DIRECTORY." (scandir directory (lambda (file) - (and (not (member file '("." ".."))) + (and (not (member file + '("." ".."))) (file-is-directory? (string-append directory "/" file)))))) -(define* (install #:key name outputs - (install-name (package-name-version->erlang-name name)) - (install-profile "default") ; build profile outputs to install - #:allow-other-keys) - (let* ((out (assoc-ref outputs "out")) - (pkg-dir (string-append out %erlang-libdir "/" install-name))) - (let ((bin-dir (string-append "_build/" install-profile "/bin")) - (lib-dir (string-append "_build/" install-profile "/lib"))) - ;; install _build/PROFILE/bin - (when (file-exists? bin-dir) - (copy-recursively bin-dir out #:follow-symlinks? #t)) - ;; install _build/PROFILE/lib/*/{ebin,include,priv} - (for-each - (lambda (*) - (for-each - (lambda (dirname) - (let ((src-dir (string-append lib-dir "/" * "/" dirname)) - (dst-dir (string-append pkg-dir "/" dirname))) - (when (file-exists? src-dir) - (copy-recursively src-dir dst-dir #:follow-symlinks? #t)) - (false-if-exception - (delete-file (string-append dst-dir "/.gitignore"))))) - '("ebin" "include" "priv"))) - (list-directories lib-dir)) - (false-if-exception - (delete-file (string-append pkg-dir "/priv/Run-eunit-loop.expect")))))) - -(define %standard-phases +;; +;; source +;; + +(define source->name + car) +(define source->tar + cadr) + +;; +;; tar +;; + +(define* (tar-unpack tar) + (invoke "tar" "xvf" tar) + (invoke "tar" "xvf" "contents.tar.gz") + + ;; Prevent an error message at install phase. + ;; . + ;; rebar3 compile produces a symlinks like so in _build/: + ;; priv -> ../../../../priv + ;; priv -> ../../../../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"))) + +;;; +;;; pkg-name +;;; + +(define pkg-name-prefix + "erlang-") + +(define pkg-name-prefix-re + (format #f "^~a(.*)" pkg-name-prefix)) + +(define (pkg-name? name) + (string-match (format #f "^~a" pkg-name-prefix) name)) + +(define (pkg-name->name name) + (regexp-substitute #f + (string-match pkg-name-prefix-re name) 1)) + +(define* (pkg-name->lib-name name) + "erlang-a-b-1.0.2 -> a_b-1.0.2" + + (let ((elements (string-split (pkg-name->name name) #\-))) + (string-append (string-join (drop-right elements 1) "_") "-" + (last elements)))) + +(define* (pkg-name->build-dir name + #:key (profile "default")) + (string-append (format #f "_build/~a/lib/" profile) + (car (string-split (pkg-name->lib-name name) #\-)))) + +(define (lib-name-no-version lib-name) + (car (string-split lib-name #\-))) + +;; +;; phase +;; + +(define* (phase-unpack #:key source #:allow-other-keys) + (tar-unpack source)) + +(define (phase-configure-HOME . ignored_args) + "In some cases, it is needed for the environment variable HOME to be defined +as a directory with write permission. + +Examples of errors: + - Could not write to \"/homeless-shelter/.cache/rebar3/hex\". Please ensure the path is writeable. +" + + (let ((HOME "HOME") + (tmp "/tmp")) + (setenv HOME tmp) + (format #t "~a=~a\n" HOME tmp))) + +(define* (phase-configure-dependencies #:key name + version + inputs + sources-erlang + (install-profile "default") + #:allow-other-keys) + + ;; If source in sources-erlang, then install it under _checkouts/. + ;; see: https://rebar3.org/docs/configuration/dependencies/#checkout-dependencies + (let ((_checkouts "_checkouts")) + (mkdir-p _checkouts) + (for-each (lambda (source) + (match source + ((name tar) + (let ((src (string-append _checkouts "/" name))) + (mkdir-p src) + (with-directory-excursion src + (tar-unpack tar)))) + (_ #f))) sources-erlang)) + + ;; If input in inputs is an Erlang package, then install it under _build/. + (let ((_build (format #f "_build/~a/checkouts" install-profile))) + (mkdir-p _build) + (match inputs + (((_ . dirs) ..1) + (for-each (lambda (dir) + (let ((elib (string-append dir "/lib/erlang/lib"))) + (when (directory-exists? elib) + (for-each (lambda (dirname) + (let ((src (string-append elib "/" dirname)) + (dest (string-append _build "/" + (lib-name-no-version + dirname)))) + (copy-recursively src dest + #:log #f) + (mkdir-p (string-append dest "/priv")))) + (utils-list-directories elib))))) dirs)) + (_ #f)))) + +(define* (phase-build #:key name + (rebar-flags '()) #:allow-other-keys) + (apply invoke + `("rebar3" "compile" + ,@rebar-flags))) + +(define* (phase-check #:key target + (rebar-flags '()) + (tests? (not target)) + (test-target "eunit") + #:allow-other-keys) + (if tests? + (apply invoke + `("rebar3" ,test-target + ,@rebar-flags)) + (format #t "test suite not run~%"))) + +(define* (phase-install #:key name outputs + (install-profile "default") #:allow-other-keys) + (let* ((build-dir (pkg-name->build-dir name + #:profile install-profile)) + (out-build-dir (string-append (assoc-ref outputs "out") + "/lib/erlang/lib/" + (pkg-name->lib-name name)))) + + (mkdir-p out-build-dir) + (copy-recursively build-dir out-build-dir + #:follow-symlinks? #t))) + +;; +;; rebar +;; + +(define rebar-%standard-phases (modify-phases gnu:%standard-phases - (replace 'unpack unpack) + (replace 'unpack + phase-unpack) + (add-after 'unpack 'configure-HOME + phase-configure-HOME) (delete 'bootstrap) (delete 'configure) - (add-before 'build 'erlang-depends erlang-depends) - (replace 'build build) - (replace 'check check) - (replace 'install install))) + (add-before 'build 'configure-dependencies + phase-configure-dependencies) + (replace 'build + phase-build) + (replace 'check + phase-check) + (replace 'install + phase-install))) -(define* (rebar-build #:key inputs (phases %standard-phases) +(define* (rebar-build #:key inputs + (phases rebar-%standard-phases) #:allow-other-keys #:rest args) "Build the given Erlang package, applying all of PHASES in order." - (apply gnu:gnu-build #:inputs inputs #:phases phases args)) + (apply gnu:gnu-build + #:inputs inputs + #:phases phases + args)) + +;; +;; Exported bindings. +;; + +(define %standard-phases rebar-%standard-phases) + + +;;; rebar-build-system.scm ends here