Gleam-inspired typed configuration language (POC)
0

Configure Feed

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

glint / flake.nix
9.3 kB 291 lines
1{ 2 description = "Glint a Gleam-inspired typed configuration language (POC)"; 3 4 inputs = { 5 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 systems.url = "github:nix-systems/default"; 7 8 # Wasm-capable Gleam (Zed extension export). Override locally with: 9 # nix build --override-input gleam path:../gleam 10 gleam = { 11 url = "git+https://tangled.org/nandi.uk/gleam?ref=wasm"; 12 inputs.nixpkgs.follows = "nixpkgs"; 13 }; 14 }; 15 16 outputs = 17 { 18 self, 19 nixpkgs, 20 systems, 21 gleam, 22 ... 23 }: 24 let 25 forEachSystem = nixpkgs.lib.genAttrs (import systems); 26 in 27 { 28 packages = forEachSystem ( 29 system: 30 let 31 pkgs = nixpkgs.legacyPackages.${system}; 32 inherit (pkgs) lib; 33 34 gleamToml = lib.importTOML ./gleam.toml; 35 manifestToml = lib.importTOML ./manifest.toml; 36 37 hexPackages = builtins.filter (p: p.source == "hex") manifestToml.packages; 38 39 packagesTOML = lib.concatStringsSep "\n" ( 40 [ "[packages]" ] ++ map (p: "${p.name} = \"${p.version}\"") hexPackages 41 ); 42 43 # Wasm-capable gleam from the flake input. 44 gleamBin = gleam.packages.${system}.gleam; 45 46 # Self-contained store package: Erlang shipment + fixed-path wrapper. 47 glint = pkgs.stdenv.mkDerivation { 48 pname = "glint"; 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 != "result-zed" 62 && base != "erl_crash.dump" 63 && base != "editors" 64 && !(lib.hasSuffix ".escript" base); 65 }; 66 67 nativeBuildInputs = [ 68 pkgs.gleam 69 pkgs.beamPackages.erlang 70 pkgs.rebar3 71 pkgs.beamPackages.hex 72 pkgs.rsync 73 ]; 74 75 configurePhase = '' 76 runHook preConfigure 77 78 mkdir -p build/packages 79 cat <<EOF > build/packages/packages.toml 80 ${packagesTOML} 81 EOF 82 83 # Vendor Hex deps so the pure Nix build never hits the network. 84 ${lib.concatMapStringsSep "\n" (p: '' 85 rsync --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r -r ${ 86 pkgs.fetchHex { 87 pkg = p.name; 88 version = p.version; 89 sha256 = p.outer_checksum; 90 } 91 }/* build/packages/${p.name}/ 92 '') hexPackages} 93 94 runHook postConfigure 95 ''; 96 97 buildPhase = '' 98 runHook preBuild 99 export REBAR_CACHE_DIR="$TMP/.rebar-cache" 100 gleam export erlang-shipment 101 runHook postBuild 102 ''; 103 104 installPhase = '' 105 runHook preInstall 106 107 mkdir -p $out/{bin,lib/glint} 108 rsync --exclude=entrypoint.sh --exclude=entrypoint.ps1 \ 109 -r build/erlang-shipment/* $out/lib/glint/ 110 111 # Bake -pa paths at install time (each ebin needs its own -pa). 112 ebin_args=() 113 for d in $out/lib/glint/*/ebin; do 114 ebin_args+=(-pa "$d") 115 done 116 117 { 118 echo "#!${pkgs.runtimeShell}" 119 echo "set -eu" 120 echo "exec ${pkgs.beamPackages.erlang}/bin/erl ''${ebin_args[*]} -eval \"glint@@main:run(glint)\" -noshell -extra \"\$@\"" 121 } > $out/bin/glint 122 chmod +x $out/bin/glint 123 124 runHook postInstall 125 ''; 126 127 meta = { 128 description = gleamToml.description; 129 mainProgram = "glint"; 130 license = lib.licenses.asl20; 131 }; 132 }; 133 134 # Prebuilt Glint Zed extension (Gleam guest). Point Install Dev 135 # Extension at a *writable copy* of this dir, or use `nix run .#install-zed-extension`. 136 zed-extension = pkgs.stdenv.mkDerivation { 137 pname = "glint-zed-extension"; 138 version = gleamToml.version; 139 140 src = lib.cleanSourceWith { 141 src = ./editors/zed; 142 filter = 143 path: type: 144 let 145 base = baseNameOf path; 146 in 147 lib.cleanSourceFilter path type 148 && base != "target" 149 && base != "build" 150 && base != "grammars" 151 && !(lib.hasSuffix ".wasm" base) 152 && base != "Cargo.lock"; 153 }; 154 155 nativeBuildInputs = [ 156 gleamBin 157 ]; 158 159 buildPhase = '' 160 runHook preBuild 161 export HOME=$TMPDIR 162 # `gleam export zed-extension` writes extension.wasm in the package root. 163 gleam export zed-extension 164 runHook postBuild 165 ''; 166 167 installPhase = '' 168 runHook preInstall 169 mkdir -p $out 170 cp extension.wasm $out/ 171 cp -r languages $out/ 172 173 # No [lib] section: Install Dev Extension must not run cargo. 174 # Prebuilt extension.wasm is the Gleam guest. 175 cat > $out/extension.toml <<'EOF' 176 id = "glint" 177 name = "Glint" 178 version = "0.1.0" 179 schema_version = 1 180 authors = ["nandi"] 181 description = "Glint language support highlighting and glint LSP (Gleam Wasm guest)" 182 repository = "https://tangled.org/nandi.uk/glint" 183 184 [language_servers.glint] 185 name = "Glint LSP" 186 languages = ["Glint"] 187 188 [language_servers.glint.language_ids] 189 Glint = "glint" 190 191 [grammars.gleam] 192 repository = "https://github.com/gleam-lang/tree-sitter-gleam" 193 rev = "6ea757f7eb8d391dbf24dbb9461990757946dd5e" 194 EOF 195 196 cat > $out/README.txt <<EOF 197 Glint Zed extension (Gleam Wasm guest) 198 Built with: ${gleamBin} 199 200 Install: 201 nix run .#install-zed-extension -- ~/glint-zed-dev 202 # then Zed Extensions Install Dev Extension ~/glint-zed-dev 203 EOF 204 runHook postInstall 205 ''; 206 207 meta = { 208 description = "Prebuilt Glint Zed extension (extension.wasm from Gleam)"; 209 license = lib.licenses.asl20; 210 }; 211 }; 212 in 213 { 214 default = glint; 215 inherit glint; 216 inherit gleamBin; 217 gleam = gleamBin; 218 inherit zed-extension; 219 } 220 ); 221 222 apps = forEachSystem ( 223 system: 224 let 225 pkgs = nixpkgs.legacyPackages.${system}; 226 zed = self.packages.${system}.zed-extension; 227 installScript = pkgs.writeShellApplication { 228 name = "install-zed-extension"; 229 text = '' 230 set -euo pipefail 231 dest="''${1:-$HOME/glint-zed-dev}" 232 echo "Installing Glint Zed extension $dest" 233 mkdir -p "$dest" 234 # Store path is immutable; copy so Zed can re-scan / write if needed. 235 cp -a ${zed}/. "$dest/" 236 chmod -R u+w "$dest" 237 echo "Done. In Zed: Extensions Install Dev Extension $dest" 238 echo " (prebuilt extension.wasm; no cargo rebuild required if Zed accepts the tree)" 239 ''; 240 }; 241 in 242 { 243 default = { 244 type = "app"; 245 program = "${self.packages.${system}.glint}/bin/glint"; 246 }; 247 install-zed-extension = { 248 type = "app"; 249 program = "${installScript}/bin/install-zed-extension"; 250 }; 251 } 252 ); 253 254 devShells = forEachSystem ( 255 system: 256 let 257 pkgs = nixpkgs.legacyPackages.${system}; 258 gleamBin = self.packages.${system}.gleam; 259 in 260 { 261 default = pkgs.mkShell { 262 packages = with pkgs; [ 263 # Stock gleam for normal package work, plus wasm-capable gleam as GLEAM. 264 gleam 265 gleamBin 266 beamPackages.erlang 267 rebar3 268 nodejs 269 rustc 270 cargo 271 ]; 272 GLEAM = "${gleamBin}/bin/gleam"; 273 shellHook = '' 274 echo "glint dev shell" 275 echo " GLEAM=$GLEAM (wasm-capable, for editors/zed cargo driver)" 276 echo " gleam run -- check examples/hello.glint" 277 echo " nix build .#zed-extension" 278 echo " nix run .#install-zed-extension" 279 ''; 280 }; 281 } 282 ); 283 284 checks = forEachSystem (system: { 285 package = self.packages.${system}.glint; 286 # zed-extension is heavier (builds gleam); enable when CI can afford it. 287 }); 288 289 formatter = forEachSystem (system: nixpkgs.legacyPackages.${system}.nixfmt-rfc-style); 290 }; 291}