Skip to content

Commit

Permalink
Add package lockedClojure that will run clojure and clj in lock…
Browse files Browse the repository at this point in the history
…ed environments - mainly for shells

- $HOME stays writeable
- Update example to show usage, and how it is different from `shellEnv`
- Document more in `example/README.md`
  • Loading branch information
danieroux committed Apr 10, 2024
1 parent 7fe6de4 commit e4cc6e6
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
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
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

0 comments on commit e4cc6e6

Please sign in to comment.