tools for building gleam projects with nix

buildGleam, buildGleamApplication: make overridable

foxgirl.engineering c883a600 287fa46e

verified
+152 -142
+6
CHANGELOG.md
··· 8 8 9 9 the format is based on [keep a changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [semantic versioning](https://semver.org/spec/v2.0.0.html). 10 10 11 + ## unreleased 12 + 13 + ### added 14 + 15 + - add `override` function to derivations produced by `buildGleam` and `buildGleamApplication` 16 + 11 17 ## v1.0.0 - 2025-09-25 12 18 13 19 initial release
+79 -77
nix/build-gleam-application.nix
··· 15 15 gleam-tool, 16 16 }@inputs: 17 17 18 - { 19 - pname, 20 - version, 21 - src, 18 + lib.makeOverridable ( 19 + { 20 + pname, 21 + version, 22 + src, 22 23 23 - buildInputs ? [ ], 24 - nativeBuildInputs ? [ ], 24 + buildInputs ? [ ], 25 + nativeBuildInputs ? [ ], 25 26 26 - gleamNix, 27 - erlang ? inputs.erlang, 28 - gleam ? inputs.gleam, 27 + gleamNix, 28 + erlang ? inputs.erlang, 29 + gleam ? inputs.gleam, 29 30 30 - buildGleamArgs ? { }, 31 - gleamNixOverrides ? _: _: { }, 32 - ... 33 - }@args: 31 + buildGleamArgs ? { }, 32 + gleamNixOverrides ? _: _: { }, 33 + ... 34 + }@args: 34 35 35 - let 36 - derivationList = attrs: lib.filter (v: lib.isDerivation v) (lib.attrValues attrs); 36 + let 37 + derivationList = attrs: lib.filter (v: lib.isDerivation v) (lib.attrValues attrs); 37 38 38 - compiledPackages = 39 - let 40 - scope = gleamNix { 41 - inherit 42 - lib 43 - newScope 44 - beamPackages 45 - buildGleam 46 - fetchgit 47 - ; 48 - }; 39 + compiledPackages = 40 + let 41 + scope = gleamNix { 42 + inherit 43 + lib 44 + newScope 45 + beamPackages 46 + buildGleam 47 + fetchgit 48 + ; 49 + }; 49 50 50 - withApplication = scope.overrideScope ( 51 - _: prev: { 52 - ${pname} = buildGleam ( 53 - buildGleamArgs 54 - // { 55 - name = pname; 56 - inherit version src; 57 - beamDeps = derivationList prev; 58 - inherit erlang gleam; 59 - } 60 - ); 61 - } 62 - ); 63 - in 64 - derivationList (withApplication.overrideScope gleamNixOverrides); 51 + withApplication = scope.overrideScope ( 52 + _: prev: { 53 + ${pname} = buildGleam ( 54 + buildGleamArgs 55 + // { 56 + name = pname; 57 + inherit version src; 58 + beamDeps = derivationList prev; 59 + inherit erlang gleam; 60 + } 61 + ); 62 + } 63 + ); 64 + in 65 + derivationList (withApplication.overrideScope gleamNixOverrides); 65 66 66 - filteredArgs = lib.filterAttrs ( 67 - key: _: 68 - !(builtins.elem key [ 69 - "gleamNix" 70 - "gleamNixOverrides" 71 - ]) 72 - ) args; 73 - in 67 + filteredArgs = lib.filterAttrs ( 68 + key: _: 69 + !(builtins.elem key [ 70 + "gleamNix" 71 + "gleamNixOverrides" 72 + ]) 73 + ) args; 74 + in 74 75 75 - stdenv.mkDerivation ( 76 - filteredArgs 77 - // { 78 - inherit pname version src; 76 + stdenv.mkDerivation ( 77 + filteredArgs 78 + // { 79 + inherit pname version src; 79 80 80 - nativeBuildInputs = nativeBuildInputs ++ [ 81 - gleam-tool 82 - makeWrapper 83 - ]; 84 - buildInputs = buildInputs ++ [ 85 - erlang 86 - ]; 81 + nativeBuildInputs = nativeBuildInputs ++ [ 82 + gleam-tool 83 + makeWrapper 84 + ]; 85 + buildInputs = buildInputs ++ [ 86 + erlang 87 + ]; 87 88 88 - buildPhase = '' 89 - runHook preBuild 90 - gleam-tool entrypoint ${pname} 91 - runHook postBuild 92 - ''; 89 + buildPhase = '' 90 + runHook preBuild 91 + gleam-tool entrypoint ${pname} 92 + runHook postBuild 93 + ''; 93 94 94 - installPhase = '' 95 - runHook preInstall 95 + installPhase = '' 96 + runHook preInstall 96 97 97 - mkdir -p $out/{bin,lib/entrypoint/ebin} 98 - ${lib.concatMapStringsSep "\n" ( 99 - package: "ln -s ${package}/lib/erlang/lib/* $out/lib/" 100 - ) compiledPackages} 98 + mkdir -p $out/{bin,lib/entrypoint/ebin} 99 + ${lib.concatMapStringsSep "\n" ( 100 + package: "ln -s ${package}/lib/erlang/lib/* $out/lib/" 101 + ) compiledPackages} 101 102 102 - mv gleam_entrypoint.beam $out/lib/entrypoint/ebin 103 + mv gleam_entrypoint.beam $out/lib/entrypoint/ebin 103 104 104 - makeWrapper ${erlang}/bin/erl $out/bin/${pname} --add-flags \ 105 - "-pa $out/lib/*/ebin -eval \"gleam_entrypoint:run()\" -noshell -extra" 105 + makeWrapper ${erlang}/bin/erl $out/bin/${pname} --add-flags \ 106 + "-pa $out/lib/*/ebin -eval \"gleam_entrypoint:run()\" -noshell -extra" 106 107 107 - runHook postInstall 108 - ''; 109 - } 108 + runHook postInstall 109 + ''; 110 + } 111 + ) 110 112 )
+67 -65
nix/build-gleam.nix
··· 10 10 gleam-tool, 11 11 }@inputs: 12 12 13 - { 14 - name, 15 - version, 16 - src, 13 + lib.makeOverridable ( 14 + { 15 + name, 16 + version, 17 + src, 17 18 18 - beamDeps ? [ ], 19 - nativeBuildInputs ? [ ], 20 - preFixup ? "", 19 + beamDeps ? [ ], 20 + nativeBuildInputs ? [ ], 21 + preFixup ? "", 21 22 22 - erlang ? inputs.erlang, 23 - gleam ? inputs.gleam, 24 - gleam-tool ? inputs.gleam-tool, 25 - ... 26 - }@args: 23 + erlang ? inputs.erlang, 24 + gleam ? inputs.gleam, 25 + gleam-tool ? inputs.gleam-tool, 26 + ... 27 + }@args: 27 28 28 - let 29 - filteredArgs = lib.filterAttrs ( 30 - key: _: 31 - !(builtins.elem key [ 32 - "erlang" 33 - "gleam" 34 - "gleam-tool" 35 - "name" 36 - "nativeBuildInputs" 37 - "preFixup" 38 - "src" 39 - "version" 40 - ]) 41 - ) args; 42 - in 43 - stdenv.mkDerivation ( 44 - { 45 - pname = name; 46 - inherit version src; 29 + let 30 + filteredArgs = lib.filterAttrs ( 31 + key: _: 32 + !(builtins.elem key [ 33 + "erlang" 34 + "gleam" 35 + "gleam-tool" 36 + "name" 37 + "nativeBuildInputs" 38 + "preFixup" 39 + "src" 40 + "version" 41 + ]) 42 + ) args; 43 + in 44 + stdenv.mkDerivation ( 45 + { 46 + pname = name; 47 + inherit version src; 47 48 48 - nativeBuildInputs = nativeBuildInputs ++ [ 49 - erlang 50 - gleam 51 - gleam-tool 52 - ]; 49 + nativeBuildInputs = nativeBuildInputs ++ [ 50 + erlang 51 + gleam 52 + gleam-tool 53 + ]; 53 54 54 - configurePhase = '' 55 - runHook preConfigure 55 + configurePhase = '' 56 + runHook preConfigure 56 57 57 - mkdir deps 58 - ${lib.concatMapStringsSep "\n" (package: "ln -s ${package}/lib/erlang/lib/* deps/") beamDeps} 58 + mkdir deps 59 + ${lib.concatMapStringsSep "\n" (package: "ln -s ${package}/lib/erlang/lib/* deps/") beamDeps} 59 60 60 - runHook postConfigure 61 - ''; 61 + runHook postConfigure 62 + ''; 62 63 63 - buildPhase = '' 64 - runHook preBuild 64 + buildPhase = '' 65 + runHook preBuild 65 66 66 - gleam compile-package --target erlang --package . --lib deps --out build 67 + gleam compile-package --target erlang --package . --lib deps --out build 67 68 68 - gleam-tool appspec build/ebin ${lib.concatMapStringsSep " " (dep: dep.otpApplication) beamDeps} 69 + gleam-tool appspec build/ebin ${lib.concatMapStringsSep " " (dep: dep.otpApplication) beamDeps} 69 70 70 - runHook postBuild 71 - ''; 71 + runHook postBuild 72 + ''; 72 73 73 - installPhase = '' 74 - runHook preInstall 74 + installPhase = '' 75 + runHook preInstall 75 76 76 - mkdir -p $out/lib/erlang/lib 77 - cp -r build $out/lib/erlang/lib/${name}-${version} 77 + mkdir -p $out/lib/erlang/lib 78 + cp -r build $out/lib/erlang/lib/${name}-${version} 78 79 79 - runHook postInstall 80 - ''; 80 + runHook postInstall 81 + ''; 81 82 82 - preFixup = '' 83 - ${preFixup} 83 + preFixup = '' 84 + ${preFixup} 84 85 85 - privPath=$out/lib/erlang/lib/${name}-${version}/priv 86 + privPath=$out/lib/erlang/lib/${name}-${version}/priv 86 87 87 - if [ -h $privPath ]; then 88 - realPath=$(realpath $privPath) 89 - rm $privPath 90 - cp -r $realPath $privPath 91 - fi 92 - ''; 93 - } 94 - // filteredArgs 88 + if [ -h $privPath ]; then 89 + realPath=$(realpath $privPath) 90 + rm $privPath 91 + cp -r $realPath $privPath 92 + fi 93 + ''; 94 + } 95 + // filteredArgs 96 + ) 95 97 )