Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 7 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,7 @@ Launches the JUnit Platform for test discovery and execution.

### Gradle

Discover projects and source sets from the build root. Project paths also address included builds, such as `:build-logic:plugin`:

```sh
jig gradle --root-project-dir . --list-project-paths

jig gradle --root-project-dir . \
--project-path :app --list-source-sets
```
Resolve arguments from Gradle projects and source sets, including composite builds. Use `--list-project-paths` and `--list-source-sets` to discover selections.

For a project `:app` with a source set `main`, resolve runtime arguments and launch your main class:

Expand All @@ -107,27 +100,11 @@ jig gradle --root-project-dir . \
java @runtime.args com.example.Main
```

For compilation, resolve compiler options separately:

```sh
jig gradle --root-project-dir . \
--project-path :app --source-set main \
--resolve-compiler-options --write-argfile compile.args

javac @compile.args @sources.args
```

Replace the project, source set and main class with those of your application. Prepare `sources.args` with the source filenames to compile, including generated sources and `module-info.java` where applicable, and use a `javac` matching the build's configured toolchain.
Use `--resolve-compiler-options` for the source set's effective compiler arguments. See [Build Tool Projects](https://github.com/Netflix/jig/wiki/Build-Tool-Projects) for compilation examples and supported options.

### Maven

Discover projects from the Maven project base directory:

```sh
jig maven --project-base-dir . --list-projects
```

Select a project by `groupId:artifactId` or the shorter `:artifactId` form, then request its `compile`, `runtime` or `test` scope. For an application project with artifact ID `app`:
Resolve arguments from a Maven project's `compile`, `runtime` or `test` scope. Use `--list-projects` to discover project selectors. For an application with artifact ID `app`:

```sh
jig maven --project-base-dir . \
Expand All @@ -140,11 +117,11 @@ java @runtime.args com.example.Main

### Cached build queries

Gradle and Maven discovery and argument resolution use the same persistent cache. Matching build inputs can reuse results across branch switches and worktrees; paths inside the project are resolved against the current project root. Arguments containing project-specific values that jig cannot relocate safely remain local to that project directory.
Discovery and resolved arguments are cached across branches and worktrees. Cache hits skip the build tool and output preparation; use `--refresh` to query the build again. Unused entries are pruned automatically. See [Build Tool Projects](https://github.com/Netflix/jig/wiki/Build-Tool-Projects#caching) for details.

A cache hit skips the build-tool invocation, including any tasks that would prepare outputs. Changes to reported build inputs invalidate the answer. Use `--refresh` to query the build again after other changes, such as environment changes or updated dynamic dependencies. Use `--verbose` to see cache hits and build invocations.
### Publishing module artifacts

Entries unused for seven days are pruned, with cleanup checked at most once daily. Files explicitly written with `--write-argfile` belong to the caller and are not pruned.
Install module artifacts locally or publish them to Maven repositories and Maven Central with `jig maven install`, `deploy` and `deploy-central`. See [Publishing Modules](https://github.com/Netflix/jig/wiki/Publishing-Modules).

### Module proxy

Expand All @@ -162,6 +139,7 @@ The [wiki](https://github.com/Netflix/jig/wiki) covers:

- [Getting Started](https://github.com/Netflix/jig/wiki/Getting-Started)
- [Tool Arguments](https://github.com/Netflix/jig/wiki/Tool-Arguments)
- [Build Tool Projects](https://github.com/Netflix/jig/wiki/Build-Tool-Projects)
- [Source Modules](https://github.com/Netflix/jig/wiki/Source-Modules)
- [Maven Modules](https://github.com/Netflix/jig/wiki/Maven-Modules)
- [Publishing Modules](https://github.com/Netflix/jig/wiki/Publishing-Modules)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,25 @@ void helpDescribesTheStandaloneContract() {
assertTrue(run("__complete", "gradle", "--ref").output().contains("--refresh\t"));
}

@Test
void helpUsesACompactOptionReferenceWithoutATextTail() {
var help = run("gradle", "--help");
String text = help.output();
assertEquals(0, help.exitCode(), help.error());
assertEquals("", help.error());
assertEquals(text, run("gradle").output());
assertTrue(text.startsWith("Usage: jig gradle --root-project-dir <DIRECTORY> [OPTIONS]\n"), text);
assertTrue(text.replaceAll("\\s+", " ").contains("--project-path, --source-set and --classpath"), text);
assertTrue(text.contains("source filenames"), text);
assertTrue(text.contains("build tasks"), text);
assertTrue(text.endsWith(" Print this help message\n"), text);
assertTrue(text.lines().count() <= 50, text);
assertTrue(text.lines().allMatch(line -> line.length() <= 88), text);
assertFalse(text.contains("Examples:"), text);
assertFalse(text.contains("Resolve options:"), text);
assertFalse(text.contains("native jig options"), text);
}

@Test
void requiresExplicitLocationsSourceSetAndClasspath() throws Exception {
Path root = Files.createDirectories(temporaryDirectory.resolve("root"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ void helpAndCompletionIncludeDiscoveryAndPreserveRepositoryOperations() {
assertTrue(run("__complete", "maven", "--ref").output().contains("--refresh\t"));
}

@Test
void helpPutsProjectQueriesFirstAndSeparatesPublishing() {
var help = run("maven", "--help");
String text = help.output();
assertEquals(0, help.status(), help.error());
assertEquals("", help.error());
var bare = run("maven");
assertEquals(0, bare.status(), bare.error());
assertEquals(text, bare.output());
assertTrue(text.startsWith("Usage: jig maven --project-base-dir <DIRECTORY> [OPTIONS]\n"), text);
assertTrue(text.indexOf("Publishing commands:") < text.indexOf("Options:"), text);
assertTrue(text.contains("--project and --scope"), text);
assertTrue(text.contains("build goals"), text);
assertTrue(text.endsWith(" Print this help message\n"), text);
assertTrue(text.lines().count() <= 45, text);
assertTrue(text.lines().allMatch(line -> line.length() <= 88), text);
assertFalse(text.contains("Examples:"), text);
assertFalse(text.contains("Resolve options:"), text);
var queryHelp = run("maven", "--project-base-dir", ".", "--help");
assertEquals(0, queryHelp.status(), queryHelp.error());
assertEquals(text.substring(text.indexOf("Options:")),
queryHelp.output().substring(queryHelp.output().indexOf("Options:")));
}

@Test
@EnabledOnOs({OS.LINUX, OS.MAC})
void discoveryAndResolutionCachesServeAnswersUntilRefresh() throws Exception {
Expand Down
29 changes: 29 additions & 0 deletions src/com.netflix.tools.jig/com/netflix/tools/jig/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,35 @@ public String optionsHelp() {
return help.toString();
}

static String optionsReference(ToolOption... options) {
var help = new StringBuilder("Options:\n");
for (ToolOption option : options) {
if (option.hidden()) {
continue;
}
help.append(" ").append(display(option)).append('\n');
for (String paragraph : option.description().split("\n")) {
help.append(" ");
int width = 8;
for (String word : paragraph.split(" ")) {
if (width > 8) {
if (width + 1 + word.length() > 80) {
help.append("\n ");
width = 8;
} else {
help.append(' ');
width++;
}
}
help.append(word);
width += word.length();
}
help.append('\n');
}
}
return help.toString();
}

public List<Completion> complete(CompletionRequest request) {
Objects.requireNonNull(request);
var arguments = new ArrayList<>(request.invocation()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@
/** Explicit build locations, project paths, and source-set argument projections for Gradle. */
final class GradleCommandLine {
static final List<String> CLASSPATHS = List.of("compile", "runtime");
private static final ToolOption ROOT = ToolOption.option("--root-project-dir", "DIRECTORY", "Gradle root project directory");
private static final ToolOption PROJECT = ToolOption.option("--project-path", "PATH", "A build-tree-qualified Gradle project path, such as :app or :build-logic:plugin");
private static final ToolOption ROOT = ToolOption.option("--root-project-dir", "DIRECTORY", "Set the Gradle root project directory (required)");
private static final ToolOption PROJECT = ToolOption.option("--project-path", "PATH", "Select a project, such as :app or :build-logic:plugin");
private static final ToolOption LIST_PROJECTS = ToolOption.flag("--list-project-paths", "List Gradle project paths, including included builds");
private static final ToolOption LIST_SOURCE_SETS = ToolOption.flag("--list-source-sets", "List source sets in the selected project");
private static final ToolOption LIST_SOURCE_SETS = ToolOption.flag("--list-source-sets", "List source sets; requires --project-path");
private static final ToolOption SOURCE_SET = ToolOption.option("--source-set", "NAME", "A source set from --list-source-sets");
private static final ToolOption CLASSPATH = ToolOption.option("--classpath", "compile|runtime", "Select the source set's classpath");
private static final ToolOption RESOLVE = ToolOption.option("--resolve-options", "OPTION[,OPTION...]", "Resolve standard options to stdout", "-r");
private static final ToolOption COMPILER = ToolOption.flag("--resolve-compiler-options", "Resolve the selected source set's effective compiler options");
private static final ToolOption WRITE = ToolOption.option("--write-argfile", "PATH", "Write resolved options to a Java argument file", "-w");
private static final ToolOption REFRESH = ToolOption.flag("--refresh", "Query Gradle again instead of using cached results");
private static final ToolOption VERBOSE = ToolOption.flag("--verbose", "Show the Gradle invocation and build diagnostics");
private static final ToolOption RESOLVE = ToolOption.option("--resolve-options", "OPTION[,OPTION...]", "Resolve Java tool options; requires --project-path, --source-set and --classpath", "-r");
private static final ToolOption COMPILER = ToolOption.flag("--resolve-compiler-options", "Resolve compiler options; requires --project-path and --source-set.\n"
+ "Uses compile; excludes source filenames and launcher options.");
private static final ToolOption WRITE = ToolOption.option("--write-argfile", "PATH", "Write resolved options to a Java argument file instead of stdout", "-w");
private static final ToolOption REFRESH = ToolOption.flag("--refresh", "Query Gradle again; cached answers skip Gradle and build tasks");
private static final ToolOption VERBOSE = ToolOption.flag("--verbose", "Show cache hits, Gradle invocations and build diagnostics");
private static final ToolOption HELP = ToolOption.flag("--help", "Print this help message", "-h");
private static final CommandLine COMMAND_LINE = CommandLine.builder()
.description("Resolve standard Java arguments from a Gradle source set")
Expand Down Expand Up @@ -69,25 +70,16 @@ static List<Completion> complete(CompletionRequest request) {
}

static String help() {
return COMMAND_LINE.help("jig gradle")
+ "\nDiscovery and resolved arguments are cached across branches and worktrees.\n"
+ "Cache hits do not invoke Gradle or prepare build outputs; use --refresh to query again.\n"
+ "Inputs reported by the build invalidate cached results; other changes require --refresh.\n"
+ "Entries unused for seven days are pruned.\n"
+ "\nUses the root project's wrapper, or gradle on PATH.\n"
+ "Project paths and source-set names are obtained from the build.\n"
+ "The TSV listing contains absolute directory, project path, source set and classpath.\n"
+ "Projects without Java source sets have empty source-set and classpath fields, not defaults.\n"
+ "Included-build discovery and selection require Gradle 4.0 or later.\n"
+ "Compile and runtime select the source set's compileClasspath and runtimeClasspath.\n"
+ "Discovery does not execute source producers; source-path resolution retains their dependencies.\n"
+ "Binary paths prepare selected outputs unless the corresponding source paths are requested.\n"
+ "Unknown projects or source sets are errors; empty source sets produce only configured arguments.\n"
+ "Compiler resolution implies compile and uses Gradle's compiler argument builder.\n"
+ "It excludes source filenames and launcher options; the caller owns the invocation.\n"
+ "\nResolve options include native jig options and class-path, processor-path,\n"
+ "source, target, encoding, system and add-reads. Unconfigured options are omitted.\n"
+ "Known standard options not supported by Gradle are omitted.\n";
return """
Usage: jig gradle --root-project-dir <DIRECTORY> [OPTIONS]

Resolve Java tool arguments using the build's wrapper, or gradle on PATH.
Choose --list-project-paths, --list-source-sets, --resolve-options or
--resolve-compiler-options.

""" + CommandLine.optionsReference(ROOT, PROJECT, SOURCE_SET, CLASSPATH,
LIST_PROJECTS, LIST_SOURCE_SETS, ProjectListing.FORMAT, RESOLVE, COMPILER,
WRITE, REFRESH, VERBOSE, HELP);
}

static Request parse(String[] arguments) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static int run(PrintWriter out, PrintWriter err, Supplier<ModuleRepositorySessio
String... arguments) {
if (arguments.length == 0 || isHelp(arguments[0])) {
printHelp(out);
return arguments.length == 0 ? 2 : 0;
return 0;
}
if (arguments[0].startsWith("-")) {
return MavenProjectCommands.run(out, err, arguments);
Expand Down Expand Up @@ -223,13 +223,7 @@ private static boolean isHelp(String argument) {
}

private static void printHelp(PrintWriter out) {
out.println("Usage: jig maven install [--module-version <version>] <artifact-directory>");
out.println(" jig maven deploy [--module-version <version>] --repository <id=uri|path> [--sign] <artifact-directory>");
out.println(" jig maven deploy-central [--module-version <version>] [--name <name>] [--manual] <artifact-directory>");
out.println();
out.println("Installs or deploys flat, module-named artifacts.");
out.println();
out.print(MavenProjectCommands.help());
out.print(MavenProjectCommands.help(true));
}

private record Request(Path artifacts, RemoteRepository repository, String name,
Expand Down
Loading
Loading