Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
682ee98
Moved Java files to src folder
wfouche Oct 13, 2025
3172108
Maven 3.9.11
wfouche Oct 13, 2025
0ea5b1c
Created pom.xml with support for spotless
wfouche Oct 13, 2025
5a69b93
Added eclipse-java-formatter.xml
wfouche Oct 13, 2025
87dab71
Updated groupid/artifactId
wfouche Oct 13, 2025
eb9e280
Use eclipse-java-formatter.xml
wfouche Oct 13, 2025
d1b4a9e
Upgrade to spotless maven plugin 3.0.0
wfouche Oct 13, 2025
d372b57
Fixed pom.xml
wfouche Oct 13, 2025
2f158f2
Moved to Gradle
wfouche Oct 14, 2025
3f46848
Do not format JBang directives
wfouche Oct 14, 2025
004184d
Support for Eclipse and Google java formatters
wfouche Oct 14, 2025
cdae3ff
Fix JBang marker
wfouche Oct 14, 2025
aa477b3
Fix JBang marker
wfouche Oct 14, 2025
e42e411
Fix scripts starting with '/// jbang'
wfouche Oct 14, 2025
7cc32dc
Fixing scripts starting with '//' and contains jbang (ignore case)
wfouche Oct 14, 2025
7b883e8
Removed special JBang comment line
wfouche Oct 14, 2025
56d86d4
Removed task fixJbangMarker
wfouche Oct 14, 2025
76957ee
Refomatted source files using Jython-2017-v2.xml template.
wfouche Oct 19, 2025
8377f39
Reformatted source files using Jython-2017-v2.xml template.
wfouche Oct 19, 2025
7b97734
Merge remote-tracking branch 'origin/dev/maven-ejf' into dev/maven-ejf
wfouche Oct 19, 2025
318ccd4
README.md updates
wfouche Oct 19, 2025
e1f9091
fix: removed reference to Google Java Format
wfouche Oct 22, 2025
41f5714
fix: moved all Java files to src/main/java
wfouche Oct 22, 2025
38e4056
fix: spotless:{off,on} not needed when using the Eclipse Java Formatter
wfouche Oct 22, 2025
c8bf9f8
fix: moved the Eclipse Java formatter config file to the tools folder
wfouche Oct 22, 2025
d72998c
fix: exclude .gradle and build folders from git
wfouche Oct 22, 2025
0edb6bb
fix: update Java to run Gradle to version 17
wfouche Oct 22, 2025
ee9366d
fix: mention that Jython-2017-v2.xml can be imported into IDEs
wfouche Oct 22, 2025
6da46b7
fix: ignore target folder
wfouche Oct 22, 2025
128e1e3
fix: moved TestJythonCli.java to src/test/java
wfouche Oct 22, 2025
e868a25
fix: moved //SOURCES to after //DEPS block
wfouche Oct 22, 2025
bf2c5bd
Add Gradle task runTests
wfouche Nov 8, 2025
4b01aff
Removed java target folder for spotless
wfouche Nov 8, 2025
05068bd
Updated dependencies
wfouche Nov 8, 2025
11c4f82
Removed unused dependency
wfouche Nov 8, 2025
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 .github/workflows/cli-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
- name: Test with JBang
run: |
export PATH="$HOME/.jbang/bin:$PATH"
jbang TestJythonCli.java execute --disable-ansi-colors --select-class=TestJythonCli
jbang src/test/java/TestJythonCli.java execute --disable-ansi-colors --select-class=TestJythonCli
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
/jython-jbang-catalog.iml

/.vscode/
/.gradle/
/build/
/target/
4 changes: 2 additions & 2 deletions .sdkmanrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# Add key=value pairs of SDKs to use below

# Java
java=8.0.452-tem
java=17.0.16-tem

# JBang
jbang=0.126.1
jbang=0.132.1

13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,18 +252,13 @@ Also test the jython-cli script with Java 8:
* jbang run --java 8 jython-cli examples/turtle.py
* jbang run --java 8 jython-cli examples/simpletest.py

On Linux or MacOS the JythonCli.java script can be run directly for testing purposes:

* ./JythonCli.java -V
* ./JythonCli.java examples/banner.py

## Java Source File Formatting

Use the `google-java-format` to format the `JythonCli.java` and `TestJythonCli.java` programs.
Use the Gradle task `spotlessApply` to format the `JythonCli.java` and `TestJythonCli.java` programs. Task `spotlessCheck` will only check if the Java source files are correctly formatted.

```
jbang run com.google.googlejavaformat:google-java-format:1.29.0 --aosp -r *.java
```
The configuration file used by the Eclipse Java Formatter, when running the `spotless` tasks, can be imported into your preferred IDE (if supported).

* See file `tools\eclipse-java-formatter\Jython-2017-v2.xml`

## Articles about Jython and JBang

Expand Down
35 changes: 35 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Apply the standard Java plugin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gradle potentially confers some advantages in terms of editing and debugging from the IDE, which has always been a pain point when reviewing. VSCode recognises this as a Gradle project, which means the Gradle menu has just appeared, and the spotlessApply task may be run from it.

However, it is not properly set up as a Gradle Java project with the right structure and dependencies, so VSCode does not recognise the source as belonging to the project, and continues to give me red ink about the imports and won't debug the cli.

I think a little more work (and letting Gradle bully you into main and test source trees) will yield a lot.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an initial step, I've moved both Java files to src/main/java.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good first step. With that change, I find I can finally stop the IDE grumbling at me, with some additions to just this file, which I'll pass on next.

plugins {
id 'java'
// Apply the Spotless plugin (using the same version as in the Kotlin DSL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get the Gradle test target to work, add this plug-in (and config lower down).

id 'jvm-test-suite'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed in the revised implementation.

id 'com.diffplug.spotless' version '7.2.1'
}

// Standard repository configuration
repositories {
mavenCentral()
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then here, we need to specify these dependencies:

dependencies {
    implementation 'org.tomlj:tomlj:1.1.1'
    testImplementation 'org.junit.platform:junit-platform-console'
}

and to minimally configure the jvm-test-suite plug-in like this:

// Configure the jvm-test-suite plug-in
testing {
    suites {
        // The pre-defined test suite.
        test {
            useJUnitJupiter()
        }
    }
}

Copy link
Member Author

@wfouche wfouche Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following a slightly different approach by using the JBang Gradle plugin

https://plugins.gradle.org/plugin/dev.jbang

and then just running TestJythonCli.java as we run it currently. Created new task runTests for this purpose.

tasks.register("runTests", JBangTask) {
    // Specify the script file to run
    script = "src/test/java/TestJythonCli.java"

    // Optional: Pass arguments to the script
    jbangArgs = ["--java", "17"]
    args = ["execute", "--disable-ansi-colors", "--select-class=TestJythonCli"]
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is fine to have a target that runs the tests the way we do on GitHub. I confirm this target runs at the console for me.

It is not a substitute for the changes I suggested.

// === Spotless Configuration ===
spotless {
// Define the formatting rules for Java files
java {
target 'src/**/*.java'

eclipse().configFile('tools/eclipse-java-formatter/Jython-2017-v2.xml')

importOrder()
removeUnusedImports()
toggleOffOn()
}
}

// Add a standard task for running the application
tasks.register('hello') {
doLast {
println 'Spotless is now configured using Groovy DSL with Google Java Format. To format your code, run:'
println './gradlew spotlessApply'
println 'To check if files need formatting (useful for CI), run:'
println './gradlew spotlessCheck'
}
}
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
248 changes: 248 additions & 0 deletions gradlew
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
#!/bin/sh

#
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################

# Attempt to set APP_HOME

# Resolve links: $0 may be a link
app_path=$0

# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done

# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

warn () {
echo "$*"
} >&2

die () {
echo
echo "$*"
echo
exit 1
} >&2

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac



# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi

# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi

# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.

# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )

JAVACMD=$( cygpath --unix "$JAVACMD" )

# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi


# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi

# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#

eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'

exec "$JAVACMD" "$@"
Loading