A structured-data shell in Gleam, inspired by Nushell
0

Configure Feed

Select the types of activity you want to include in your feed.

gleshell / flake.nix
5.5 kB 175 lines
1{ 2 description = "gleshell structured-data shell in Gleam, inspired by Nushell"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 systems.url = "github:nix-systems/default"; 7 devenv.url = "github:cachix/devenv"; 8 devenv.inputs.nixpkgs.follows = "nixpkgs"; 9 }; 10 11 nixConfig = { 12 extra-substituters = [ "https://devenv.cachix.org" ]; 13 extra-trusted-public-keys = [ 14 "devenv.cachix.org-1:ppRjvZf4JrQqfA3n7eHkSxX4z1M0RKZ77N8D66zCFAI=" 15 ]; 16 }; 17 18 outputs = 19 { 20 self, 21 nixpkgs, 22 devenv, 23 systems, 24 ... 25 }@inputs: 26 let 27 forEachSystem = nixpkgs.lib.genAttrs (import systems); 28 in 29 { 30 packages = forEachSystem ( 31 system: 32 let 33 pkgs = nixpkgs.legacyPackages.${system}; 34 inherit (pkgs) lib; 35 36 gleamToml = lib.importTOML ./gleam.toml; 37 manifestToml = lib.importTOML ./manifest.toml; 38 39 hexPackages = builtins.filter (p: p.source == "hex") manifestToml.packages; 40 41 packagesTOML = lib.concatStringsSep "\n" ( 42 [ "[packages]" ] ++ map (p: "${p.name} = \"${p.version}\"") hexPackages 43 ); 44 45 # Self-contained store package: compiles to Erlang shipment, wraps with 46 # store-path Erlang. No source checkout / GLESHELL_ROOT required at runtime. 47 gleshell = pkgs.stdenv.mkDerivation { 48 pname = "gleshell"; 49 version = gleamToml.version; 50 51 src = lib.cleanSourceWith { 52 src = ./.; 53 filter = 54 path: type: 55 let 56 base = baseNameOf path; 57 in 58 lib.cleanSourceFilter path type 59 && base != "build" 60 && base != "result" 61 && base != ".devenv" 62 && base != ".direnv" 63 && base != "erl_crash.dump" 64 # Root escript is a regular file; keep the src/gleshell/ directory. 65 && !(type == "regular" && base == "gleshell") 66 && !(lib.hasSuffix ".escript" base); 67 }; 68 69 nativeBuildInputs = [ 70 pkgs.gleam 71 pkgs.beamPackages.erlang 72 pkgs.rebar3 73 pkgs.beamPackages.hex 74 pkgs.rsync 75 ]; 76 77 configurePhase = '' 78 runHook preConfigure 79 80 mkdir -p build/packages 81 cat <<EOF > build/packages/packages.toml 82 ${packagesTOML} 83 EOF 84 85 # Vendor Hex deps so the pure Nix build never hits the network. 86 ${lib.concatMapStringsSep "\n" (p: '' 87 rsync --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r -r ${ 88 pkgs.fetchHex { 89 pkg = p.name; 90 version = p.version; 91 sha256 = p.outer_checksum; 92 } 93 }/* build/packages/${p.name}/ 94 '') hexPackages} 95 96 runHook postConfigure 97 ''; 98 99 buildPhase = '' 100 runHook preBuild 101 export REBAR_CACHE_DIR="$TMP/.rebar-cache" 102 gleam export erlang-shipment 103 runHook postBuild 104 ''; 105 106 installPhase = '' 107 runHook preInstall 108 109 mkdir -p $out/{bin,lib/gleshell} 110 rsync --exclude=entrypoint.sh --exclude=entrypoint.ps1 \ 111 -r build/erlang-shipment/* $out/lib/gleshell/ 112 113 # Bake -pa paths at install time (each ebin needs its own -pa). 114 ebin_args=() 115 for d in $out/lib/gleshell/*/ebin; do 116 ebin_args+=(-pa "$d") 117 done 118 119 # Runtime wrapper: fixed store paths, works from any cwd. 120 # +Bc: Ctrl+C cancels the line; do not open the Erlang BREAK menu. 121 { 122 echo "#!${pkgs.runtimeShell}" 123 echo "set -eu" 124 echo 'export ERL_AFLAGS="+Bc ''${ERL_AFLAGS:-}"' 125 echo "exec ${pkgs.beamPackages.erlang}/bin/erl ''${ebin_args[*]} -eval \"gleshell@@main:run(gleshell)\" -noshell -extra \"\$@\"" 126 } > $out/bin/gle 127 chmod +x $out/bin/gle 128 ln -s gle $out/bin/gleshell 129 130 runHook postInstall 131 ''; 132 133 meta = { 134 description = gleamToml.description; 135 mainProgram = "gle"; 136 license = lib.licenses.asl20; 137 }; 138 }; 139 140 # Prompt icons (``, ``, …). Install so the REPL glyph set renders: 141 # nix profile install .#nerd-fonts 142 # On NixOS/home-manager prefer fonts.packages instead. 143 nerd-fonts = pkgs.nerd-fonts.symbols-only; 144 in 145 { 146 default = gleshell; 147 inherit gleshell nerd-fonts; 148 } 149 ); 150 151 apps = forEachSystem (system: { 152 default = { 153 type = "app"; 154 program = "${self.packages.${system}.gleshell}/bin/gle"; 155 }; 156 }); 157 158 devShells = forEachSystem ( 159 system: 160 let 161 pkgs = nixpkgs.legacyPackages.${system}; 162 in 163 { 164 # --no-pure-eval (or direnv) is required so devenv can resolve 165 # devenv.root from $PWD; pure eval would point ./. at the store. 166 default = devenv.lib.mkShell { 167 inherit inputs pkgs; 168 modules = [ ./devenv.nix ]; 169 }; 170 } 171 ); 172 173 formatter = forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style); 174 }; 175}