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

Make the hooks more verbose #204

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion doc/filegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ This has two main advantages:

## Usage

To re-generate the files run:
The files specified in `files.*` are regenerated automatically when entering
the devshell (unless `filegen_hook` is set to false).

They can also be regenerated manually with:

```bash
nix run .#regenerate-files
Expand Down
51 changes: 40 additions & 11 deletions lib/files.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,18 @@ let nix = import "./nix-interop/nix.ncl" in
| doc m%"
The content of the file.
"%
| nix.derivation.NixString,
| nix.derivation.NullOr nix.derivation.NixString
| default
= null,
file
| doc "File from which to read the body of the script"
| nix.derivation.NullOr nix.derivation.NixString
| default
=
if content == null then
null
else
nix.builtins.to_file "generated-content" content,
materialisation_method
: [| 'Symlink, 'Copy |]
| doc m%"
Expand All @@ -39,7 +50,25 @@ let nix = import "./nix-interop/nix.ncl" in
Set of files that should be generated in the project's directory.
"%
= {},
filegen_hook.enable
| Bool
| doc m%"
Enable a hook that will automatically regenerate the files managed by
Nickel when entering the shell.
"%
| default
= true,
flake.apps.regenerate-files.program = nix-s%"%{regenerate_files files}/bin/regenerate-files"%,

shells.build.hooks =
if filegen_hook.enable then
{
filegen_hook.content = nix-s%"
%{regenerate_files files}/bin/regenerate-files
"%
}
else
{},
},

regenerate_files | Files -> nix.derivation.Derivation = fun files_to_generate =>
Expand All @@ -53,17 +82,17 @@ let nix = import "./nix-interop/nix.ncl" in
}
file_descr.materialisation_method
in
let file_in_store =
nix.builtins.to_file
(nix.utils.escape_drv_name key)
file_content
in
nix-s%"
rm -f %{target}
echo "Regenerating %{target}"
target_dir=$(dirname %{target})
test "${target_dir}" != "." && mkdir -p "${target_dir}"
%{copy_command} %{file_in_store} %{target}
if [[ ! -f "%{target}" ]] || [[ $(cat "%{target}") != $(cat "%{file_descr.file}") ]]; then
echo "Regenerating %{target}"
rm -f %{target}
target_dir=$(dirname "%{target}")
test "${target_dir}" != "." && mkdir -p "${target_dir}"
# XXX: If `source.file` is set explicitely to a relative path
# and `materialisation_method` is `'Symlink`, this will link to the
# original file, not one in the store. Not sure that's what we want.
%{copy_command} "%{file_descr.file}" "%{target}"
fi
"%
in
{
Expand Down
40 changes: 22 additions & 18 deletions lib/lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,19 @@
passAsFile = ["expectedLockfileContents"];
} (
if needNewLockfile
then
lib.warn ''
Lockfile contents are outdated. Please run "nix run .#regenerate-lockfile" to update them.
''
''
cp -r "${sources}" sources
if [ -f sources/nickel.lock.ncl ]; then
chmod +w sources sources/nickel.lock.ncl
else
chmod +w sources
fi
cp $expectedLockfileContentsPath sources/nickel.lock.ncl
cat > eval.ncl <<EOF
${nickelWithImports "sources"}
EOF
${nickel}/bin/nickel export eval.ncl > $out
''
then ''
cp -r "${sources}" sources
if [ -f sources/nickel.lock.ncl ]; then
chmod +w sources sources/nickel.lock.ncl
else
chmod +w sources
fi
cp $expectedLockfileContentsPath sources/nickel.lock.ncl
cat > eval.ncl <<EOF
${nickelWithImports "sources"}
EOF
${nickel}/bin/nickel export eval.ncl > $out
''
else ''
cat > eval.ncl <<EOF
${nickelWithImports sources}
Expand All @@ -210,9 +206,17 @@
nickelResult = callNickel {
inherit nickelFile baseDir flakeInputs lockFileContents;
};
enrichedFlakeInputs =
flakeInputs
// {
# XXX: Hack to pass the lockfile path to the Nickel world, so that
# we can point `files."nickel.lock.ncl"` to it and have it regenerated
# automatically.
"%%organist_internal".nickelLock = builtins.toFile "nickel.lock.ncl" (buildLockFileContents lockFileContents);
};
in
{rawNickel = nickelResult;}
// (importFromNickel flakeInputs system baseDir (builtins.fromJSON
// (importFromNickel enrichedFlakeInputs system baseDir (builtins.fromJSON
(builtins.unsafeDiscardStringContext (builtins.readFile nickelResult))));
in {
inherit
Expand Down
8 changes: 8 additions & 0 deletions lib/lockfile.ncl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let filegen = import "files.ncl" in
let nix = import "nix-interop/nix.ncl" in
{
Schema =
{
files."nickel.lock.ncl".file = nix.import_nix "%%organist_internal#nickelLock",
} | filegen.Schema,
}
23 changes: 0 additions & 23 deletions lib/nix-interop/builders.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,6 @@ in
}
| NickelPkg,

Shell
| doc m%"
A derivation that is to be used as a shell, e.g. with `nix develop`.
Analogous to `mkShell`.
"%
=
NixpkgsPkg
& {
hooks | doc "Bash scripts to run when entering the shell" = {},

name | default = "shell",
version | default = "dev",
packages | doc "Packages to be added to the shell, setting PATH, LD_LIBRARY_PATH and other variables as needed" = {},

env.buildCommand = nix-s%"
echo "This derivation is not supposed to be built" 1>&2 1>/dev/null
exit 1
"%,
env.shellHook = concat_strings_sep "\n" (std.record.values hooks),
structured_env.nativeBuildInputs = packages,
}
| NickelPkg,

ShellApplication
| doc m%"
A derivation that writes contents of `content.file` to `bin/$name` in the output and makes it executable.
Expand Down
6 changes: 3 additions & 3 deletions lib/nix-interop/shells.ncl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
let builders = import "builders.ncl" in
let nix_builtins = import "builtins.ncl" in

let concat_strings_sep = fun sep values =>
Expand All @@ -9,6 +8,7 @@ let concat_strings_sep = fun sep values =>
in

{
Base = import "./shells/base.ncl",
Bash = import "./shells/bash.ncl",
Rust = import "./shells/rust.ncl",

Expand Down Expand Up @@ -95,9 +95,9 @@ in
build.packages.opam = nix_builtins.import_nix "nixpkgs#opam",
dev.packages.ocaml-lsp = nix_builtins.import_nix "nixpkgs#ocamlPackages.ocaml-lsp",

dev.hooks.enter_opam_env = m%"
dev.hooks.enter_opam_env.content = m%"
echo "==> Reloading the OPAM environment."
echo "==> Set 'shells.dev.hooks.enter_opam_env' to false to disable."
echo "==> Set 'shells.dev.hooks.enter_opam_env' to `""` to disable."
eval $(opam env)
"%,
},
Expand Down
82 changes: 82 additions & 0 deletions lib/nix-interop/shells/base.ncl
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
let builders = import "../builders.ncl" in
let derivation = import "../derivation.ncl" in

let Hook = {
name
| doc m%"
The name of the hook.
If null, defaults to the attribute name.
"%
| String
| optional,
enabled
| doc m%"
Whether to run the hook
"%
| Bool
| default
= true,
verbose
| doc m%"
Whether to announce when the hook runs
"%
| Bool
| default
= true,
content
| doc m%"
The bash snippet to run
"%
| derivation.NixString,
}
in
let concat_strings_sep = fun sep values =>
if std.array.length values == 0 then
""
else
std.array.reduce_left (fun acc value => nix-s%"%{acc}%{sep}%{value}"%) values
in

let hook_to_string | Hook -> derivation.NixString = fun hook =>
if hook.enabled then
let header =
if hook.verbose then
nix-s%"
echo -e '\033[34;1m==> Running hook %{hook.name}\033[0m'
"%
else
nix-s%""%
in

nix-s%"
%{header}
%{hook.content}
"%
else
nix-s%""%
in
let NormaliseNames = fun label items =>
items
|> std.record.map (fun item_name item => item & { name | default = item_name })
in

builders.NixpkgsPkg
& {
hooks
| doc "Bash scripts to run when entering the shell"
| { _ : Hook }
| NormaliseNames
= {},

name | default = "shell",
version | default = "dev",
packages | doc "Packages to be added to the shell, setting PATH, LD_LIBRARY_PATH and other variables as needed" = {},

env.buildCommand = nix-s%"
echo "This derivation is not supposed to be built" 1>&2 1>/dev/null
exit 1
"%,
env.shellHook = concat_strings_sep "\n" (std.record.values hooks |> std.array.map hook_to_string),
structured_env.nativeBuildInputs = packages,
}
| builders.NickelPkg
3 changes: 2 additions & 1 deletion lib/nix-interop/shells/bash.ncl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
let builders = import "../builders.ncl" in
let base = import "./base.ncl" in
let nix_builtins = import "../builtins.ncl" in
{
build =
builders.Shell
base
& {
packages = {
bash = nix_builtins.import_nix "nixpkgs#bash",
Expand Down
2 changes: 2 additions & 0 deletions lib/schema.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
let nix = import "./nix-interop/nix.ncl" in
let filegen = import "files.ncl" in
let lockfile = import "lockfile.ncl" in
{
OrganistShells = {
dev
Expand Down Expand Up @@ -64,4 +65,5 @@ let filegen = import "files.ncl" in
= {},
}
& filegen.Schema
& lockfile.Schema
}
8 changes: 3 additions & 5 deletions run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,15 @@ test_one_template () (
fi

echo "Running without nickel.lock.ncl" 1>&2
rm nickel.lock.ncl
rm -f nickel.lock.ncl
nix develop --accept-flake-config --print-build-logs --command bash <<<"$TEST_SCRIPT"

echo "Run with proper nickel.lock.ncl" 1>&2
nix run .\#regenerate-lockfile
PROPER_LOCKFILE_CONTENTS="$(cat nickel.lock.ncl)"
nix develop --accept-flake-config --print-build-logs --command bash <<<"$TEST_SCRIPT"

echo "Testing without flakes" 1>&2
# restore lockfile
rm -f nickel.lock.ncl
cat > nickel.lock.ncl <<<"$STORED_LOCKFILE_CONTENTS"
# pretend it's not flake anymore
rm flake.*
Expand All @@ -89,7 +88,7 @@ EOF
nix develop --impure -f shell.nix -I nixpkgs="$NIXPKGS_PATH" --command bash <<<"$TEST_SCRIPT"

echo "Running without nickel.lock.ncl" 1>&2
rm nickel.lock.ncl
rm -f nickel.lock.ncl
nix develop --impure -f shell.nix -I nixpkgs="$NIXPKGS_PATH" --command bash <<<"$TEST_SCRIPT"

echo "Run with proper nickel.lock.ncl" 1>&2
Expand Down Expand Up @@ -120,7 +119,6 @@ test_example () (
cp -r "$examplePath" ./example
pushd ./example
prepare_shell
nix run .\#regenerate-files --print-build-logs
nix develop --print-build-logs --command bash test.sh
popd
popd
Expand Down
Loading