Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invoking an external script with Nix interpolation #3

Open
srid opened this issue Apr 6, 2023 · 4 comments
Open

Invoking an external script with Nix interpolation #3

srid opened this issue Apr 6, 2023 · 4 comments

Comments

@srid
Copy link

srid commented Apr 6, 2023

I feel like this is a bit of a hack,
https://github.com/srid/nix-health/blob/0c4735b6403a4fd13ef170f3c21296e05cd32fe5/flake.nix#L21

        packages.default = pkgs.nuenv.mkScript {
          name = "nix-health";
          script = ''
            ${lib.getExe pkgs.nushell} ${./nix-health.nu} ${system}
          '';
        }

nix-health.nu references the system variable, so I'm passing it as a command-line argument. Also, I have to manually pull in pkgs.nushell to invoke the script. Is there a more idiomatic way of achieving this? The main goal is to put the script body in a separate file, whilst still being able to reference Nix variables in scope.

@siph
Copy link

siph commented Apr 11, 2023

This is still hacky!

You can use substituteAll to replace string instances inside of a file surrounding the replacement targets with @, eg:

foo = pkgs.substituteAll {
  name = "foo.nu";
  src = ./foo.nu;
  system = "${system}";
  nushell = "${pkgs.nushell}";
  nix-health = "${./nix-health.nu}";
}
#foo.nu
@nushell@ @nix-health@ @system@

However, I'm not sure of an elegant way to plug the resulting file into the script value.

Instead you can reuse the same syntax and just use replaceStrings directly on the file contents:

foo = pkgs.nuenv.mkScript {
  name = "foo";
  script = (builtins.replaceStrings
    [ "@system@" "@nushell@" "@nix-health@ ]
    [ "${system}" "${pkgs.nushell}" "${./nix-health.nu}" ]
    (builtins.readFile ./foo.nu)
  );
};

@lucperkins
Copy link
Member

lucperkins commented Apr 26, 2023

@srid Nushell itself is available in the scripts, so this, for example, should work:

{
  script = ''
    nu ${./nix-health.nu} ${system}
  '';
}

In terms of passing in system, @siph's approach is the only way I can think of that doesn't involve passing them as args in script.

@hallettj
Copy link

I pushed PR #27 which adds nuenv.writeShellApplication. That accepts runtimeInputs which sets environment variables in the script. Using that feature I think you could do it like this:

packages.default = pkgs.nuenv.writeShellApplication {
  name = "nix-health";
  runtimeEnv = { inherit system };
  text = builtins.readFile ./nix-health.nu;
};

Then in nix-health.nu you would access system as $env.system.

@srid
Copy link
Author

srid commented Jul 12, 2024

I pushed PR #27 which adds nuenv.writeShellApplication.

Great! I'll see if I can use that to replace this:

https://github.com/srid/nixos-flake/blob/cab6539d198792f94fbac029e5a63523604fd172/nix/nu.nix#L4-L7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants