Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You can generate a flake example with:
mkdir play-with-clojure-nix-locker && cd play-with-clojure-nix-locker && nix flake init -t github:bevuta/clojure-nix-locker
```

The [example README](example/README.md) has some next steps.
The [example README](example/README.md) has some next steps and further documentation.

## Why another tool?

Expand Down
3 changes: 3 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ in {
chmod -R +w .

# Ensures that clojure creates all the caches in our empty separate home directory
# We cannot use CLJ_JVM_OPTS here, because we want to override where `clojure`
# resolves _itself_ from as well as the classpath that it builds
# https://clojure.org/reference/clojure_cli#env_vars
export JAVA_TOOL_OPTIONS="-Duser.home=$tmp/home"

${command}
Expand Down
30 changes: 29 additions & 1 deletion example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,32 @@ Run uberjar:
nix develop
```

It will print out the current locked classpath.
It will print out the current locked classpath.

# Two ways to get a locked classpath

## Sourcing `shellEnv`

During a `buildPhase` you can source the locked `shellEnv` like this:

```sh
source ${my-clojure-nix-locker.shellEnv}
```

This overrides `$JAVA_TOOL_OPTIONS` and `$HOME` to the locked classpath. Great for building, not great for devShells.

## Using `lockedClojure`

`lockedClojure` wraps `pkgs.clojure`, overriding `$JAVA_TOOL_OPTIONS` and `$HOME` only on `clojure` or `clj` invocation. Great for devShells.

If `pkgs.clojure` is anywhere in the set of inputs for a devShell, it may override the `lockedClojure`. Check with:

```sh
clojure -Spath
```

You should see a classpath with references to `/nix/store`.

# Overriding other programs that are aware of classpaths

`wrapPrograms` is available to wrap other programs into the locked classpath. `wrapClojure` is also available if you want to wrap a custom `pkgs.clojure`.
25 changes: 19 additions & 6 deletions example/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
];

buildPhase = ''
# Overrides $HOME as well. Great for building, not great for devShells
source ${my-clojure-nix-locker.shellEnv}

# Now compile as in https://clojure.org/guides/tools_build#_compiled_uberjar_application_build
Expand All @@ -58,30 +59,42 @@
# Trace all Bash executions
set -o xtrace

source ${my-clojure-nix-locker.shellEnv}

echo "Current locked classpath:"
${pkgs.clojure}/bin/clojure -Spath

# This will work, but, $HOME will be read-only which is probably not what you want in a devShell
#source ${my-clojure-nix-locker.shellEnv}
#${pkgs.clojure}/bin/clojure -Spath

# Using the provided lockedClojure will do what you want
# And if pkgs.clojure is referenced anywhere, it may override it
${my-clojure-nix-locker.lockedClojure}/bin/clojure -Spath

set +o xtrace

echo
echo "Note that \$HOME is overridden and read-only: $HOME"
echo "Note that \$HOME will be overriden if you sourced my-clojure-nix-locker.shellEnv: $HOME"
echo "If you used my-clojure-nix-locker.lockedClojure, it will be left alone and only the clojure and clj commands are overridden and locked"
echo
echo "This command should be locked in this shell:"
echo "clojure -Spath"
echo
'';
inputsFrom = [
packages.uberjar
# Will pull in pkgs.clojure, and we want my-clojure-nix-locker.lockedClojure
#packages.uberjar
];
buildInputs = with pkgs; [
openjdk
cacert # for maven and tools.gitlibs
clojure
clj-kondo
coreutils
# This provides the standalone `clojure-nix-locker` script in the shell
# You can use it, or `nix run .#locker`
# Both does the same
my-clojure-nix-locker.locker
# Use the locked clojure
# A pkgs.clojure reference could override it
my-clojure-nix-locker.lockedClojure
];
};
});
Expand Down
7 changes: 7 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
locker = locked.commandLocker command;
homeDirectory = locked.homeDirectory;
shellEnv = locked.shellEnv;
# Function to wrap your own overridden pkgs.clojure into a locked environment, a special case
wrapClojure = locked.wrapClojure;
# Provide an already locked clojure
# You want to ensure that pkgs.clojure are not reference anywhere else
lockedClojure = locked.wrapClojure pkgs.clojure;
# Function to wrap other Java classpath aware programs with the locked environment
wrapPrograms = locked.wrapPrograms;
};
};

Expand Down