From 318d10e60875ef69132651668a249de75730d2ba Mon Sep 17 00:00:00 2001 From: sterni Date: Thu, 9 Sep 2021 18:26:03 +0200 Subject: chore(nint): move from //users/sterni to //nix Since //web/bubblegum depends on nint, we need to move it to a non user directory to conform with the policy established via cl/3434. Note that this likely doesn't mean greater stability (which isn't really implied in depot anyways), since I still would like to use a more elaborate calling convention to allow for additional useful features. Change-Id: I616f905d8df13e3363674aab69a797b0d39fdd79 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3506 Tested-by: BuildkiteCI Reviewed-by: tazjin --- nix/nint/README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 nix/nint/README.md (limited to 'nix/nint/README.md') diff --git a/nix/nint/README.md b/nix/nint/README.md new file mode 100644 index 0000000000..ddd8045f73 --- /dev/null +++ b/nix/nint/README.md @@ -0,0 +1,85 @@ +# nint — Nix INTerpreter + +`nint` is a shebang compatible interpreter for nix. It is currently +implemented as a fairly trivial wrapper around `nix-instantiate --eval`. +It allows to run nix expressions as command line tools if they conform +to the following calling convention: + +* Every nix script needs to evaluate to a function which takes an + attribute set as its single argument. Ideally a set pattern with + an ellipsis should be used. By default `nint` passes the following + arguments: + + * `currentDir`: the current working directory as a nix path + * `argv`: a list of arguments to the invokation including the + program name at `builtins.head argv`. + * Extra arguments can be manually passed as described below. + +* The return value should always be a string (throwing is also okay) + which is printed to stdout by `nint`. + +## Usage + +``` +nint [ --arg ARG VALUE … ] script.nix [ ARGS … ] +``` + +Instead of `--arg`, `--argstr` can also be used. They both work +like the flags of the same name for `nix-instantiate` and may +be specified any number of times as long as they are passed +*before* the nix expression to run. + +Below is a shebang which also passes `depot` as an argument +(note the usage of `env -S` to get around the shebang limitation +to two arguments). + +```nix +#!/usr/bin/env -S nint --arg depot /path/to/depot +``` + +## Limitations + +* No side effects except for writing to `stdout`. + +* Output is not streaming, i. e. even if the output is incrementally + calculated, nothing will be printed until the full output is available. + With plain nix strings we can't do better anyways. + +* Limited error handling for the script, no way to set the exit code etc. + +Some of these limitations may be possible to address in the future by using +an alternative nix interpreter and a more elaborate calling convention. + +## Example + +Below is a (very simple) implementation of a `ls(1)`-like program in nix: + +```nix +#!/usr/bin/env nint +{ currentDir, argv, ... }: + +let + lib = import ; + + dirs = + let + args = builtins.tail argv; + in + if args == [] + then [ currentDir ] + else args; + + makeAbsolute = p: + if builtins.isPath p + then p + else if builtins.match "^/.*" p != null + then p + else "${toString currentDir}/${p}"; +in + + lib.concatStringsSep "\n" + (lib.flatten + (builtins.map + (d: (builtins.attrNames (builtins.readDir (makeAbsolute d)))) + dirs)) + "\n" +``` -- cgit 1.4.1