Skip to content

Commit

Permalink
add CLI compile and run tests for standard help and standard version
Browse files Browse the repository at this point in the history
  • Loading branch information
sigpwned committed Jan 12, 2025
1 parent c0d063f commit 2efd7e2
Show file tree
Hide file tree
Showing 7 changed files with 385 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,9 @@ private void processComponent(TypeElement component) {
.flatMap(am -> CommandHelp.fromAnnotationMirror(am).stream()).findFirst().orElse(null);
final CommandMetadata commandMetadata = Optional.ofNullable(commandHelp)
.map(h -> new CommandMetadata(h.getName(), h.getVersion(), h.getDescription().orElse(null),
h.isProvideStandardHelp(), h.isProvideStandardVersion()))
.orElseGet(
() -> new CommandMetadata("command", CliCommandHelp.DEFAULT_VERSION, null, true, true));

System.out.println(new DaggerComponentAnalyzer(getProcessingEnv()).analyzeComponent(component)
.getInjectionSites());
h.isProvideStandardHelp(), h.isProvideStandardVersion(), h.isTesting()))
.orElseGet(() -> new CommandMetadata("command", CliCommandHelp.DEFAULT_VERSION, null, true,
true, false));

final List<DaggerInjectionSite> qualifiedInjectionSites =
new DaggerComponentAnalyzer(getProcessingEnv()).analyzeComponent(component)
Expand Down Expand Up @@ -973,6 +970,20 @@ private String generateModuleSource(String packageName, String moduleClassName,
out.println("public class " + moduleClassName + " {");
out.println();

if (commandMetadata.isTesting()) {
// If testing is enabled, generate an exception class to use instead of exiting. It's hard
// to test your library if your tests just exit the program running the tests!
out.println(" @SuppressWarnings(\"serial\")");
out.println(" public static class ExitException extends RuntimeException {");
out.println(" private final int status;");
out.println(" public ExitException(int status) {");
out.println(" this.status = status;");
out.println(" }");
out.println(" public int getStatus() { return status; }");
out.println(" }");
out.println();
}

// Generate instance fields for each positional parameter representation
out.println(" // Positional parameters");
for (PositionalParameterKey ppk : positionalRepresentationsByParameter.keySet()) {
Expand Down Expand Up @@ -1127,14 +1138,24 @@ private String generateModuleSource(String packageName, String moduleClassName,

if (commandMetadata.isProvideStandardVersion()) {
out.println(" if(standardVersionRequested) {");
out.println(" System.err.println(standardVersionMessage());");
if (commandMetadata.isTesting()) {
// We print to System.out so we capture the help as program output for testing
out.println(" System.out.println(standardVersionMessage());");
} else {
out.println(" System.err.println(standardVersionMessage());");
}
out.println(" }");
out.println();
}

if (commandMetadata.isProvideStandardHelp()) {
out.println(" if(standardHelpRequested) {");
out.println(" System.err.println(standardHelpMessage());");
if (commandMetadata.isTesting()) {
// We print to System.out so we capture the help as program output for testing
out.println(" System.out.println(standardHelpMessage());");
} else {
out.println(" System.err.println(standardHelpMessage());");
}
out.println(" }");
out.println();
}
Expand All @@ -1146,18 +1167,29 @@ private String generateModuleSource(String packageName, String moduleClassName,
if (commandMetadata.isProvideStandardVersion())
conditions.add("standardVersionRequested");
out.println(" if(" + String.join(" || ", conditions) + ") {");
out.println(" System.exit(0);");
out.println(" throw new AssertionError(\"exited\");");
if (commandMetadata.isTesting()) {
out.println(" throw new ExitException(0);");
} else {
out.println(" System.exit(0);");
out.println(" throw new AssertionError(\"exited\");");
}
out.println(" }");
}

out.println(" }");
out.println(" catch (JustArgs.IllegalSyntaxException e) {");
if (commandMetadata.isProvideStandardHelp()) {
out.println(" // Standard help is active. Print the help message and exit.");
out.println(" System.err.println(standardHelpMessage());");
out.println(" System.exit(1);");
out.println(" throw new AssertionError(\"exited\");");
if (commandMetadata.isTesting()) {
out.println(" System.out.println(e.getMessage());");
out.println(" System.out.println(standardHelpMessage());");
out.println(" throw new ExitException(1);");
} else {
out.println(" System.err.println(e.getMessage());");
out.println(" System.err.println(standardHelpMessage());");
out.println(" System.exit(1);");
out.println(" throw new AssertionError(\"exited\");");
}
} else {
out.println(" // Standard help is not active. Map and propagate the exception.");
out.println(" throw new CliSyntaxException(e.getMessage());");
Expand All @@ -1166,9 +1198,16 @@ private String generateModuleSource(String packageName, String moduleClassName,
out.println(" catch(CliSyntaxException e) {");
if (commandMetadata.isProvideStandardHelp()) {
out.println(" // Standard help is active. Print the help message and exit.");
out.println(" System.err.println(standardHelpMessage());");
out.println(" System.exit(1);");
out.println(" throw new AssertionError(\"exited\");");
if (commandMetadata.isTesting()) {
out.println(" System.out.println(e.getMessage());");
out.println(" System.out.println(standardHelpMessage());");
out.println(" throw new ExitException(1);");
} else {
out.println(" System.err.println(e.getMessage());");
out.println(" System.err.println(standardHelpMessage());");
out.println(" System.exit(1);");
out.println(" throw new AssertionError(\"exited\");");
}
} else {
out.println(" // Standard help is not active. Propagate the exception.");
out.println(" throw e;");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ public static Optional<CommandHelp> fromAnnotationMirror(AnnotationMirror annota
final String name = extractName(annotation);
final String version = extractVersion(annotation);
final String description = extractDescription(annotation);
final Boolean provideStandardHelp = extractProvideStandardHelp(annotation);
final Boolean provideStandardVersion = extractProvideStandardVersion(annotation);
final boolean provideStandardHelp = extractProvideStandardHelp(annotation);
final boolean provideStandardVersion = extractProvideStandardVersion(annotation);
final boolean testing = extractTesting(annotation);

return Optional.of(new CommandHelp(name, version, description, provideStandardHelp,
provideStandardVersion));
provideStandardVersion, testing));
}

private final String name;
Expand All @@ -55,13 +56,16 @@ public static Optional<CommandHelp> fromAnnotationMirror(AnnotationMirror annota

private final boolean provideStandardVersion;

public CommandHelp(String name, String version, String description,
Boolean provideStandardHelp, Boolean provideStandardVersion) {
private final boolean testing;

public CommandHelp(String name, String version, String description, boolean provideStandardHelp,
boolean provideStandardVersion, boolean testing) {
this.name = requireNonNull(name);
this.version = requireNonNull(version);
this.description = description;
this.provideStandardHelp = provideStandardHelp;
this.provideStandardVersion = provideStandardVersion;
this.testing = testing;
}

public String getName() {
Expand All @@ -84,16 +88,21 @@ public boolean isProvideStandardVersion() {
return provideStandardVersion;
}

public boolean isTesting() {
return testing;
}

@Override
public String toString() {
return "CommandHelp [name=" + name + ", version=" + version + ", description="
+ description + ", provideStandardHelp=" + provideStandardHelp + ", provideStandardVersion="
+ provideStandardVersion + "]";
return "CommandHelp [name=" + name + ", version=" + version + ", description=" + description
+ ", provideStandardHelp=" + provideStandardHelp + ", provideStandardVersion="
+ provideStandardVersion + ", testing=" + testing + "]";
}

@Override
public int hashCode() {
return Objects.hash(description, name, provideStandardHelp, provideStandardVersion, version);
return Objects.hash(description, name, provideStandardHelp, provideStandardVersion, testing,
version);
}

@Override
Expand All @@ -107,7 +116,7 @@ public boolean equals(Object obj) {
CommandHelp other = (CommandHelp) obj;
return Objects.equals(description, other.description) && Objects.equals(name, other.name)
&& provideStandardHelp == other.provideStandardHelp
&& provideStandardVersion == other.provideStandardVersion
&& provideStandardVersion == other.provideStandardVersion && testing == other.testing
&& Objects.equals(version, other.version);
}

Expand Down Expand Up @@ -137,7 +146,7 @@ public String visitString(String s, Void p) {
}, null)).findFirst().orElse("0.0.0");
}

private static Boolean extractProvideStandardHelp(AnnotationMirror annotation) {
private static boolean extractProvideStandardHelp(AnnotationMirror annotation) {
return annotation.getElementValues().entrySet().stream()
.filter(e -> e.getKey().getSimpleName().contentEquals("provideStandardHelp"))
.map(e -> e.getValue())
Expand All @@ -150,7 +159,7 @@ public Boolean visitBoolean(boolean b, Void p) {
}, null)).findFirst().orElse(true);
}

private static Boolean extractProvideStandardVersion(AnnotationMirror annotation) {
private static boolean extractProvideStandardVersion(AnnotationMirror annotation) {
return annotation.getElementValues().entrySet().stream()
.filter(e -> e.getKey().getSimpleName().contentEquals("provideStandardVersion"))
.map(e -> e.getValue())
Expand All @@ -172,4 +181,15 @@ public String visitString(String s, Void p) {
}
}, null)).filter(not(String::isEmpty)).findFirst().orElse(null);
}

private static boolean extractTesting(AnnotationMirror annotation) {
return annotation.getElementValues().entrySet().stream()
.filter(e -> e.getKey().getSimpleName().contentEquals("testing")).map(e -> e.getValue())
.map(v -> v.accept(new SimpleAnnotationValueVisitor8<Boolean, Void>() {
@Override
public Boolean visitBoolean(boolean b, Void p) {
return b;
}
}, null)).findFirst().orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ public class CommandMetadata {

private final boolean provideStandardVersion;

private final boolean testing;

public CommandMetadata(String name, String version, String description,
Boolean provideStandardHelp, Boolean provideStandardVersion) {
boolean provideStandardHelp, boolean provideStandardVersion, boolean testing) {
this.name = requireNonNull(name);
this.version = requireNonNull(version);
this.description = description;
this.provideStandardHelp = provideStandardHelp;
this.provideStandardVersion = provideStandardVersion;
this.testing = testing;
}

public String getName() {
Expand All @@ -63,16 +66,14 @@ public boolean isProvideStandardVersion() {
return provideStandardVersion;
}

@Override
public String toString() {
return "CommandHelp [name=" + name + ", version=" + version + ", description=" + description
+ ", provideStandardHelp=" + provideStandardHelp + ", provideStandardVersion="
+ provideStandardVersion + "]";
public boolean isTesting() {
return testing;
}

@Override
public int hashCode() {
return Objects.hash(description, name, provideStandardHelp, provideStandardVersion, version);
return Objects.hash(description, name, provideStandardHelp, provideStandardVersion, testing,
version);
}

@Override
Expand All @@ -86,7 +87,14 @@ public boolean equals(Object obj) {
CommandMetadata other = (CommandMetadata) obj;
return Objects.equals(description, other.description) && Objects.equals(name, other.name)
&& provideStandardHelp == other.provideStandardHelp
&& provideStandardVersion == other.provideStandardVersion
&& provideStandardVersion == other.provideStandardVersion && testing == other.testing
&& Objects.equals(version, other.version);
}

@Override
public String toString() {
return "CommandMetadata [name=" + name + ", version=" + version + ", description=" + description
+ ", provideStandardHelp=" + provideStandardHelp + ", provideStandardVersion="
+ provideStandardVersion + ", testing=" + testing + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
import com.google.testing.compile.JavaFileObjects;
import rapier.core.RapierTestBase;

public class CliProcessorTest extends RapierTestBase {
/**
* Test code generation for modules
*/
public class CliProcessorModuleGenerationTest extends RapierTestBase {
@Test
public void givenComponentWithPositionalOptionFlagParametersAndStandardHelpAndStandardVersion_whenCompile_thenExpectedtModuleIsGenerated()
throws IOException {
Expand Down
Loading

0 comments on commit 2efd7e2

Please sign in to comment.