diff --git a/flake.nix b/flake.nix index 95d693f5..f4c5c711 100644 --- a/flake.nix +++ b/flake.nix @@ -73,33 +73,11 @@ } // computedOutputs // flake-utils.lib.eachDefaultSystem ( - system: let - lib = pkgs.callPackage ./lib/lib.nix { + system: { + lib = nixpkgs.legacyPackages.${system}.callPackage ./lib/lib.nix { organistSrc = self; nickel = inputs.nickel.packages."${system}".nickel-lang-cli; }; - pkgs = nixpkgs.legacyPackages.${system}; - in { - inherit lib; - - apps = - computedOutputs.apps.${system} - // { - run-test = let - testScript = pkgs.writeShellApplication { - name = "test-templates"; - runtimeInputs = [ - inputs.nickel.packages."${system}".nickel-lang-cli - pkgs.parallel - pkgs.gnused - ]; - text = builtins.readFile ./run-test.sh; - }; - in { - type = "app"; - program = pkgs.lib.getExe testScript; - }; - }; } ); } diff --git a/lib/builders.ncl b/lib/builders.ncl index ed2f231f..1a40a864 100644 --- a/lib/builders.ncl +++ b/lib/builders.ncl @@ -8,6 +8,15 @@ let concat_strings_sep = fun sep values => else std.array.reduce_left (fun acc value => nix-s%"%{acc}%{sep}%{value}"%) values in + +let MutExclusiveWith = fun other name other_name label value => + if value == null && other == null then + std.fail_with "You must specify either %{name} or %{other_name} field" + else if value != null && other != null then + std.fail_with "You can set only one of %{name} or %{other_name} fields" + else + value +in { NickelPkg # we should only need two '%%', but a current Nickel bug (#XXX) bug makes the example being @@ -84,4 +93,51 @@ in structured_env.buildInputs = packages, } | (NickelPkg & { packages | { _ : Derivation } }), + + ShellApplication + | doc m%" + "% + = + NixpkgsPkg + & { + name, + version | default = "0.0.0", + content.text | NixString | optional, + content.file | NixString | default = lib.to_file name content.text, + runtime_inputs | { _ : Derivation } = {}, + shell_binary | NixString | default = lib.import_nix "nixpkgs#runtimeShell", + + env.buildInputs.coreutils = lib.import_nix "nixpkgs#coreutils", + env.buildCommand = nix-s%" + mkdir -p "${outputs[out]}/bin" + target="${outputs[out]}/bin/${name}" + (cat <<<"$scriptHeader"; cat "%{content.file}") > "$target" + chmod +x "$target" + "%{lib.import_nix "nixpkgs#stdenv.shellDryRun"}" "$target" + "%{lib.import_nix "nixpkgs#shellcheck"}/bin/shellcheck" "$target" + "%, + nix_drv = + let path_line = + if std.record.is_empty runtime_inputs then + "" + else + let paths = + runtime_inputs + |> std.record.values + |> std.array.map (fun s => nix-s%"%{s}/bin"%) + |> concat_strings_sep ":" + in + nix-s%"export PATH="%{paths}:$PATH""% + in + { + script_header = nix-s%" + #!%{shell_binary} + set -o errexit + set -o nounset + set -o pipefail + %{path_line} + "% + }, + } + | NickelPkg, } diff --git a/project.ncl b/project.ncl index 1dd4d62d..389dfa6f 100644 --- a/project.ncl +++ b/project.ncl @@ -16,6 +16,22 @@ let import_nix = organist.lib.import_nix in }, }, + flake.apps.run-test = + let testScript | organist.builders.ShellApplication = { + name = "run-test.sh", + file = "./run-test.sh", + runtime_inputs = { + nickel = organist.lib.import_nix "nickel#nickel-lang-cli", + parallel = import_nix "nixpkgs#parallel", + gnused = import_nix "nixpkgs#gnused", + }, + } + in + { + type = "app", + program | organist.contracts.NixString = nix-s%"%{testScript}/bin/run-test.sh"% + }, + flake.checks | { _ | {