Skip to content

Commit

Permalink
Merge pull request #46 from caarlos0/nonjava-projects
Browse files Browse the repository at this point in the history
Non java projects with pom.xml files / slowness
  • Loading branch information
caarlos0 committed Feb 26, 2016
2 parents e2e6838 + 75d0285 commit f7f678b
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 42 deletions.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

> The _"Java Version Manager"_
Automatically change `JAVA_HOME` based on current directory `.java-version`
file.
Automatically change `JAVA_HOME` and `PATH` based on current directory
`.java-version` or `pom.xml` files.

The philosophy behind this project is to simplify and automate the `JAVA_HOME`
changing, much like `rbenv` and `rvm` do for Ruby.
Expand All @@ -24,11 +24,13 @@ $ echo "source ~/.jvm/jvm.sh" >> ~/.bashrc
$ echo "source ~/.jvm/jvm.sh" >> ~/.zshrc
```

Then, just `cd` to a java project folder. `jvm` will try to extract the version
using a regular expression. If that fails, `jvm` will then call
`mvn help:evaluate` asking for the source compiler version, and then, set it to
`.java-version`. If the `.java-version` file already exists, it will just use
what's in there.
Then, just `cd` to a java project folder. `jvm` will look for a `.java-version`
and use whatever version is inside it. If the file don't exist, but a
`pom.xml` do, `jvm` will try to extract the version from the `pom.xml` file
using a regular expression.

`jvm` can also recursively search for `.java-version` and `pom.xml` files, so,
`cd`-ing to project's subfolder should maintain its version set.

You can always change the current folder java version by doing:

Expand Down Expand Up @@ -65,3 +67,11 @@ $ antibody bundle caarlos0/jvm
```

And it should all work out of the box.

# Honorable mentions

- [@aureliojargas](https://github.com/aureliojargas) for helping review `jvm.sh`
and for rewrite my test suite with
[clitest](https://github.com/aureliojargas/clitest);
- [@velo](https://github.com/velo) for helping me test (on Windows), reporting
bugs and giving some useful suggestions.
80 changes: 49 additions & 31 deletions jvm.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/bin/sh
# RegExp used to find the java version in a pom file.
JVM_REGEX="<(java.version|maven.compiler.source|source)>1\.[4-9]</.*>"

# finds the java home for the given version
__jvm_javahome() {
version="$1"
# shellcheck disable=SC2039
local version="$1"

# custom jdk strategy
test -f ~/.jvmconfig &&
Expand All @@ -22,9 +26,10 @@ __jvm_javahome() {

# find the appropriate JAVA_HOME for the given java version and fix PATH.
__jvm_set() {
# shellcheck disable=SC2039
local version previous new
version="$1"
previous="$JAVA_HOME"

new="$(__jvm_javahome "$version")"

# PATH cleanup
Expand All @@ -37,60 +42,72 @@ __jvm_set() {
export PATH="${JAVA_HOME}/bin:$PATH"
}

# evaluates the 'maven.compiler.source' expression, returning the found java
# version
__jvm_pomversion_evaluate() {
MAVEN_OPTS="" mvn help:evaluate \
-Dexpression='maven.compiler.source' |
grep -e '^1\.[4-9]$' |
cut -f2 -d'.'
}

# tried to find the java version using regex.
__jvm_pomversion_regex() {
regex="<(java.version|maven.compiler.source|source)>1\.[4-9]</.*>"
version="$(grep -Eo "$regex" pom.xml)"
test -z "$version" && return 1
echo "$version" |
__jvm_pomversion() {
# shellcheck disable=SC2039
local tag pom
pom="$1/pom.xml"
test ! -s "$pom" && return 1
tag="$(grep -Eo "$JVM_REGEX" "$pom")"
test -z "$tag" && return 1
echo "$tag" |
cut -f2 -d'>' |
cut -f2 -d'.' |
cut -f1 -d'<'
}

# tries multiple strategies to find the java version, and then sets it in a
# .java-version
__jvm_pomversion() {
version="$(__jvm_pomversion_regex || __jvm_pomversion_evaluate)"
test -n "$version" && echo "$version" > .java-version
}

# tries to get the version from the local .java-version
__jvm_local_version() {
test -f .java-version || return 1
cat .java-version
# shellcheck disable=SC2039
local file="$1/.java-version"
test -s "$file" || return 1
cat "$file"
}

# tries to get the version from the user .java-version
__jvm_user_version() {
test -f ~/.java-version || return 1
test -s ~/.java-version || return 1
cat ~/.java-version
}

# finds out which java version should be used.
__jvm_version() {
test ! -f .java-version -a -f pom.xml && __jvm_pomversion
__jvm_local_version || __jvm_user_version
# shellcheck disable=SC2039
local version parent proj
proj="$1"
test -z "$proj" && proj="."

# try to load from .java-version
version="$(__jvm_local_version "$proj")"

# try to extract from pom.xml
test -z "$version" && version="$(__jvm_pomversion "$proj")"

# go up looking for pom.xmls and .java-versions
parent="$proj/.."
test -z "$version" &&
test -f "$parent/pom.xml" -o -f "$parent/.java-version" &&
version="$(__jvm_version "$parent")"

# if still no version found, use the user defined version
test -z "$version" && version="$(__jvm_user_version)"

echo "$version"
}

# called when a dir changes. Find which java version to use and sets it to PATH.
# called when current pwd changes. Find which java version to use and sets
# it to PATH.
__jvm_main() {
# shellcheck disable=SC2039
local version
version="$(__jvm_version)"
test -n "$version" && __jvm_set "$version"
}

# edit custom java version configurations
__jvm_config() {
file="$HOME/.jvmconfig"
# shellcheck disable=SC2039
local file="$HOME/.jvmconfig"
test ! -f "$file" && echo "custom-jdk=/path/to/custom/jdk" > "$file"
$EDITOR "$file"
}
Expand Down Expand Up @@ -120,7 +137,8 @@ EOF
# utilitary function to user interaction with the jvm configs
# (and further scripting).
jvm() {
command=""
# shellcheck disable=SC2039
local command
if [ "$#" != 0 ]; then
command="$1"; shift
fi
Expand Down
1 change: 0 additions & 1 deletion tests/empty/pom.xml → tests/java8/empty/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<groupId>com.jvm</groupId>
<artifactId>jdk8</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../java8</relativePath>
</parent>
<groupId>com.jvm</groupId>
<artifactId>empty</artifactId>
Expand Down
8 changes: 8 additions & 0 deletions tests/nonjava/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jvm</groupId>
<artifactId>nonjava</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
23 changes: 20 additions & 3 deletions tests/test.clitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $ TESTS="tests"
$ find . -name '.java-version' -delete
$ source jvm.sh
$ export MAVEN_OPTS=""
$ echo "8=$(__jvm_javahome 7)" > ~/.jvmconfig
$
```

Expand Down Expand Up @@ -81,7 +82,7 @@ therefore, this will run `mvn help:evaluate` and find out that the parent
is using Java 8.

```console
$ cd "$ROOT/$TESTS/empty"
$ cd "$ROOT/$TESTS/java8/empty"
$ jvm reload
$ jvm version
8
Expand All @@ -95,21 +96,37 @@ pointing out Java 6 to use Java 7 home.

```console
$ cd "$ROOT/$TESTS/grep"
$ rm .java-version
$ echo "6=$(__jvm_javahome 7)" > ~/.jvmconfig
$ echo "6=$(__jvm_javahome 7)" >> ~/.jvmconfig
$ jvm local 6
$ jvm reload
$ jvm version
6
$
```

# nonjava

Test that a folder with a `pom.xml`, but which is not being used to compile
java projects, will get an empty `.java-version` to avoid running `mvn`
evaluate every time.

```console
$ jvm global 7
$ cd "$ROOT/$TESTS/nonjava"
$ jvm reload
$ jvm version
7
$
```

# Cleanup

Remove unneeded files after all tests ran.

```console
$ cd "$ROOT"
$ find . -name '.java-version' -delete
$ echo "6=$(__jvm_javahome 7)" > ~/.jvmconfig
$ jvm global 8 2> /dev/null
$
```

0 comments on commit f7f678b

Please sign in to comment.