This file provides guidance to AI coding assistants when working with code in this repository.
jgo is a Python tool for launching Java applications directly from Maven coordinates without manual installation. It resolves dependencies using Maven, caches them locally in ~/.jgo, and executes Java code using the java and mvn command-line tools.
The tool serves two purposes:
- A CLI tool (
jgo) for running Java applications from the command line - A Python library for programmatically launching Java applications from Python code
# Run all tests
make test
# or
bin/test.sh
# Run specific test file
bin/test.sh tests/test_run.py
# Run specific test
bin/test.sh tests/test_run.py::test_name# Run linters and auto-format code
make lint
# or
bin/lint.shThis project uses:
validate-pyprojectfor validating pyproject.tomlrufffor linting and formattingmypyfor static type analysis checks
# Build distribution archives
make dist
# or
bin/dist.sh# Remove build artifacts
make clean
# or
bin/clean.shSee docs/architecture.md.
Dependency Resolution Flow:
- Parse the endpoint string (e.g.,
org.python:jython-standaloneorg:a:v@MainClass) or load an entrypoint fromjgo.tomlif present - Expand shortcuts from
~/.config/jgo.confand resolve configuration via 4-tier precedence: CLI flags >jgo.toml>~/.config/jgo.conf> smart defaults - Determine workspace path:
- Project mode (jgo.toml present):
.jgo/in the project root - Ad-hoc mode:
~/.cache/jgo/envs/<groupId>/<artifactId>/<hash>/where the 16-char hash is derived from coordinates + flags
- Project mode (jgo.toml present):
- On cache miss or forced refresh: resolve dependencies via Maven (downloading JARs to
~/.m2/repository/), then link/copy JARs into the workspace - Classify each JAR as modular (EXPLICIT/AUTOMATIC) or non-modular (PLAIN), using a baseline
jartool fetched viacjdk(Java 11) for consistency; cache classification results in~/.cache/jgo/info/... - Separate JARs into
jars/(classpath) andmodules/(module-path) subdirectories in the workspace - Scan JAR bytecode to detect the minimum required Java version, rounded up to the nearest LTS (8, 11, 17, 21, …); record this in
jgo.lock.tomlalongside resolved coordinates and SHA-256 checksums - Locate an appropriate JVM: in AUTO mode (default), use
cjdkto download/cache a matching JDK if no suitable system Java is found; in SYSTEM mode, use Java fromJAVA_HOME/PATH - Launch Java, passing non-modular JARs via
-cpand modular JARs via--module-path(when Java 9+ is available)
Endpoint String Format:
- Endpoints use
+to concatenate multiple artifacts (adds all to classpath) - Main class specification: use
@separator after coordinates (e.g.,coord1+coord2@MainClass) - Auto-completion: Simple class names without dots are auto-completed (e.g.,
ScriptREPL→org.scijava.script.ScriptREPL) - Fully qualified names (with dots) are used as-is (e.g.,
org.example.Main) - Old format (
coord:@MainClassorcoord:MainClass) is deprecated but still supported
Configuration:
~/.config/jgo.conf: INI file with[settings],[repositories], and[shortcuts]sectionsJGO_CACHE_DIRenvironment variable overrides cache directoryM2_REPOenvironment variable overrides Maven repository location
Dependency Management Mode (enabled by default):
- By default, jgo adds endpoints to POM's
<dependencyManagement>section using import scope - This ensures transitive dependency versions match those of the endpoint itself
- Use
--no-managedflag to disable this behavior (rare) - See
docs/dependency-management.mdfor details on Maven dependency management - The
-m/--managedflags still work for backward compatibility but are now the default
- Unit tests in
tests/test_*.pyusepytestviauv. - Integration tests in
tests/cli/*.tusepryskviauv. - The
bin/test.shscript runs both kinds of tests, and can be given arguments to limit what runs.
The "thicket" is a complex generated hierarchy of Maven POMs used to test jgo's Maven model building:
Location: tests/fixtures/thicket/
generator.py: Generates complex POM hierarchies with configurable random seed__init__.py: Exportsgenerate_thicket()function
What it tests:
- Multi-level parent POM inheritance (up to 4 levels)
- BOM imports and transitive BOM imports (up to 3 per POM)
- Property-based versioning and interpolation
- Complex dependency management merging
How it works:
- POMs are automatically generated during test runs via a pytest session-scoped fixture in
tests/conftest.py - Uses a fixed random seed (42) for reproducible test results
- No manual setup required - just run
bin/test.sh - POMs are generated in a temporary directory and cleaned up automatically
Regenerating with different seeds:
# From project root
python -m tests.fixtures.thicket.generator 123 /tmp/thicket-testThis ensures tests are fully integrated with the test suite and require no manual intervention.