From: alex Date: Mon, 1 Dec 2025 16:21:38 +0000 (-0800) Subject: packages: add elixir X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=e4694c801bcde17cfceffdbea7d4f806530bda36;p=channel packages: add elixir --- diff --git a/infiniteadaptability/packages/elixir.scm b/infiniteadaptability/packages/elixir.scm new file mode 100644 index 0000000..5dd0639 --- /dev/null +++ b/infiniteadaptability/packages/elixir.scm @@ -0,0 +1,137 @@ +(define-module (infiniteadaptability packages elixir) + #:use-module (guix gexp) + #:use-module (guix git-download) + #:use-module (guix packages) + #:use-module (gnu packages) + #:use-module (gnu packages elixir) + #:use-module (infiniteadaptability packages erlang)) + +(define-public elixir-1.19.2 + (package + (inherit elixir) + (name "elixir") + (version "1.19.2") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/elixir-lang/elixir") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "0556xjkh5229afl22av2g8gkq5ak0gfipm90ybgnq2d2brd714xh")))) + (arguments + (list + #:test-target "test" + #:parallel-tests? #f ;see + #:make-flags #~(list (string-append "PREFIX=" #$output)) + #:phases + #~(let* ((compiler-path "lib/elixir/src/elixir_erl_compiler.erl") + (compiler-path-orig (string-append compiler-path ".orig"))) + (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"))) + ;; We should not brake the formatting, so we need patch the + ;; following more accurately. + (substitute* "lib/mix/test/mix/tasks/cmd_test.exs" + (("File\\.mkdir_p!\\(\"priv\"\\)" all) + (string-append all "\n sh = \"" + (search-input-file inputs "/bin/sh") "\"")) + (("#!/bin/sh") "#!#{sh}")))) + (add-after 'replace-paths 'pre-install-source + (lambda* (#:key outputs #:allow-other-keys) + (copy-recursively + "lib" + (string-append (assoc-ref outputs "src") "/source/lib")))) + (add-after 'pre-install-source 'patch-elixir-compiler + ;; Temporarily patch the compiler to place correct source + ;; locations into module info instead of build directory. + (lambda* (#:key outputs #:allow-other-keys) + (copy-recursively compiler-path compiler-path-orig) + (let ((source (string-append "/tmp/guix-build-" #$name "-" + #$version ".drv-0")) + (destination (assoc-ref outputs "src"))) + (substitute* compiler-path + (("source, Source") + (string-append "source, string:replace(Source, \"" + source "\", \"" destination "\")")))))) + (add-before 'build 'set-deterministic + (lambda _ + ;; Set deterministic compiler option. + (setenv "ERL_COMPILER_OPTIONS" "deterministic"))) + (add-after 'build 'restore-and-recompile + ;; Unpatch the compiler and recompile it. + (lambda _ + (copy-recursively compiler-path-orig compiler-path) + (delete-file compiler-path-orig) + (invoke "erlc" "-I" "lib/elixir/include" + "-o" "lib/elixir/ebin" compiler-path))) + (add-after 'restore-and-recompile '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 _ + ;; 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 can be sourced as an elixir script by other elixir + ;; program, for example `iex -S mix`, so we should not wrap + ;; mix into shell script. + (substitute* (string-append out "/bin/mix") + (("Mix.CLI.main\\(\\)") + (format #f "\ +~~w[GUIX_ELIXIR_LIBS ERL_LIBS] +|> Enum.map(&System.get_env/1) +|> Enum.reject(&is_nil/1) +|> Enum.join(\":\") +|> case do \"\" -> :ok; erl_libs -> System.put_env(\"ERL_LIBS\", erl_libs) end +System.put_env(\"MIX_REBAR3\", System.get_env(\"MIX_REBAR3\", \"~a\")) +Mix.CLI.main()" + (search-input-file inputs "/bin/rebar3")))) + (for-each + (lambda (program) + (wrap-program (string-append out "/bin/" program) + '("ERL_LIBS" prefix ("${GUIX_ELIXIR_LIBS}")))) + programs)))))))) + (inputs (modify-inputs (package-inputs elixir) + (replace "erlang" erlang-28.1.1) + (replace "rebar3" rebar))))) + +elixir-1.19.2