A simple application to manage having different versions of a tool for PNC.
A shim is an executable that sits between the command you type and the program you run. In our case, it mostly means creating a symlink to the correct version of the tool we want to use. We might replace the symlink with a tiny Bash script to be able to also setup any environment variables needed, and then call the actual tool.
Here's an example:
- Add a symlink in the
shimsfolder:mvnwill now symlink to/mnt/tools/maven/maven-3.9.9/bin/mvn - Add to your shell's
PATHtheshimsfolder:~/.locale/share/jshim/shims$ export PATH=~/.locale/share/jshim/shims:$PATH
- Running
mvnwill now use the mvn 3.9.9 binary - If later on, we want to use Mvn 3.8.8 instead: we can make the symlink
mvnpoint to/mnt/tools/maven/maven-3.8.8/bin/mvninstead
jshim handles the symlinking part, as well as downloading the tools' binary versions. It has logic for specific tools, so that all the CLI binaries for an application (like Java) are symlinked properly.
In the case of Java, that means we'll have to add or adjust the shims for the CLI commands java, javac, javadoc, jps, etc.
By default, the shim and downloaded binaries are in:
- downloaded binaries:
<jshim data path>/downloaded/<tool>/<tool>-<version> - shims:
<jshim data path>/shims/<tool>
We can specify where the shims and downloaded tool versions are by using the environment variables:
JSHIM_DATA_PATH: the path where the downloaded tools will be placedJSHIM_SHIM_PATH: the path where theshimsfolder will be placed
This is useful for the scenario where the data path is a volume shared between different pods, and the "shim path" is set to the pod's local storage. This allows each pod to customize its own tool version while benefiting from the shared volume and not having to constantly download different binary versions.
Example:
$ export JSHIM_DATA_PATH=/mnt/shared/jshim
$ export JSHIM_SHIM_PATH=/home/user/.local/share/shimsWe'll then need to add the JSHIM_SHIM_PATH to our shell's path:
$ export PATH=$JSHIM_SHIM_PATH:$PATHFurther customization is available after downloading a tool version using hooks. Hooks are Groovy scripts that can be
run after downloading the tool version to customize it. An example is to set a custom cacerts file after a Java
download, or set a custom settings.xml file for Maven.
This is done by:
- Create a
hooksfolder in the same path as the jshim.jar file - Inside the
hooksfolder, write a<tool>-postdownload.groovyfile
The following variables are injected into the Groovy script:
TOOL_NAME: the tool nameTOOL_VERSION: the tool versionTOOL_HOME: the home folder for the tool version
An example of a postdownload groovy script can be found in: examples/hooks/maven-postdownload.groovy
Some tools like java also needs to define an environment variable (JAVA_HOME for java) to work optimally.
This is done by creating a symlinked folder inside the shims folder which points to the home path of the tool version.
To export those environment variables, we need to run:
$ source ~/${JSHIM_SHIM_PATH}/source-file.shin your terminal shell. The exported environment variables point to the symlinked folder, which in turns point to the specific tool version folder.
After this, switching between java versions shouldn't require the user to run the source
command again since the home symlinked folder will be adjusted automatically. However, installing new tools will require
the user to run the source command again to capture the new home environment variables
to export.
The tool folder structure where we symlink the shims to has the structure:
<jshim data path>/downloaded/<tool>/<tool>-<version>
Compile:
$ mvn clean install
The CLI can be found in: cli/target/jshim.jar and run as:
$ java -jar cli/target/jshim.jar
The server part can be found in: server/target/jshim-server-runner.jar and run as:
$ java -jar server/target/jshim-server-runner.jar
You can then open the web-browser on http://localhost:8080 to interact with it
- Add support for mx, kotlin, yarn?
- Add checksum verification
- Add more tests