Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The conjure IR compiler supports standard customization #1049

Merged
merged 5 commits into from
May 18, 2022

Conversation

carterkozak
Copy link
Contributor

Custom arguments are supported using the same mechanism as
generators, but using the parser key:

conjure {
  parser {
    verbose = true
  }
}

==COMMIT_MSG==
The conjure IR compiler supports standard customization using the parser key
==COMMIT_MSG==

Possible downsides?

parser isn't syntax we use elsewhere, however compiler and "IR" are not obvious to users, so I think parser is reasonable.

Custom arguments are supported using the same mechanism as
generators, but using the `parser` key:
```groovy
conjure {
  parser {
    verbose = true
  }
}
```
@carterkozak carterkozak requested review from CRogers and fawind May 17, 2022 18:41
@changelog-app
Copy link

changelog-app bot commented May 17, 2022

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

The conjure IR compiler supports standard customization using the parser key

Check the box to generate changelog(s)

  • Generate changelog entry

@@ -88,6 +88,10 @@ public final File getOutputFile() {
@Optional
public abstract MapProperty<String, Serializable> getConjureExtensions();

@Input
@Optional
public abstract MapProperty<String, Object> getOptions();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In practice I suspect the places using GeneratorOptions as an input would benefit from MapProperty<String, Object>, but I didn't update existing consumers in this PR.

TaskProvider<GenerateConjureServiceDependenciesTask> serviceDependencyTask = project.getTasks()
.named(ConjureBasePlugin.SERVICE_DEPENDENCIES_TASK, GenerateConjureServiceDependenciesTask.class);

ConjureExtension conjureExtension =
project.getExtensions().create(ConjureExtension.EXTENSION_NAME, ConjureExtension.class);
ConjureExtension conjureExtension = conjureBasePlugin.conjureExtension();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the ConjureExtension registration to ConjureBasePlugin, and updated the interacting pieces to pass references from the plugin registration rather than digging through get/find-by-X. It seemed cleaner, but I wouldn't be surprised if it's an unspeakable sin against gradle.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, looks good to me but actually not sure why this isn't applied more often. I guess it requires a tighter coupling between plugins but that seems fine in this case. Maybe @CRogers has a stronger opinion here :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I have done both. I don't know how I feel about one versus the other. The just access the plugin method feels nicer from a general-java-coding standpoint, everything in Gradle land does the latter though.

@@ -19,7 +19,7 @@
public final class TestVersions {
private TestVersions() {}

public static final String CONJURE = "4.11.2";
public static final String CONJURE = "4.30.0";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated so that the --verbose flag is actually used rather than listed as an unmatched input -- in practice it's not necessary for the test to pass, and we're only validating plumbing. I'll revert this out if it causes anything to fail.

@@ -45,6 +46,11 @@ public final void python(@DelegatesTo(GeneratorOptions.class) Closure<GeneratorO
closure.call();
}

public final void parser(@DelegatesTo(GeneratorOptions.class) Closure<GeneratorOptions> closure) {
Copy link
Contributor

@CRogers CRogers May 18, 2022

Choose a reason for hiding this comment

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

You should use Closure arguments as raw types in extensions for the gradle integration in intellij to work properly (without making a big warning box). Also, for Closure<V>, V is the return type so it shouldn't really be the delegate type.

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably a nice thing to make an errorprone rule of actually

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh, interesting! I copied from the other methods on this object, I'll update all of 'em.

Copy link
Contributor

Choose a reason for hiding this comment

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

I only just discovered this recently too!

@@ -98,6 +116,9 @@ private static TaskProvider<CompileIrTask> createIrTasks(
compileIr.getExecutableDir().set(extractCompilerTask.flatMap(ExtractExecutableTask::getOutputDirectory));
compileIr.getOutputIrFile().set(irDir.map(dir -> dir.file(project.getName() + ".conjure.json")));
compileIr.getProductDependencies().set(project.provider(pdepsExtension::getProductDependencies));
compileIr
.getOptions()
.set(project.provider(() -> conjureExtension.getParser().getProperties()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Afaik, general best practice is to make all fields of an extension (i.e. conjureExtension) a property and that way you get the lazy wiring out of the box. But this works as well and don't think we need to refactor the extension now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That makes sense, though making the change in this PR would result in either a large refactor, or inconsistency within the ConjureExtension -- what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I would just leave it like this! Just wanted to flag but don't think its a big deal!

Copy link
Contributor

Choose a reason for hiding this comment

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

It definitely is nicer to just hook up the properties together directly, especially as Gradle can then work out the task dependencies automatically if there are files involved in outputs and inputs of different tasks. The one thing I will say is the extra providers makes the stacktrace more understandable when you have some horrible not-enough-laziness bug like I recently encountered with gradle-jdks, but I don't think that's a good enough reason to not just link them together (and you can always add these back when debugging).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've filed #1050 to track

private final GeneratorOptions pythonOptions = new GeneratorOptions();
private final Map<String, GeneratorOptions> genericOptions = new HashMap<>();

public final void typescript(@DelegatesTo(GeneratorOptions.class) Closure<GeneratorOptions> closure) {
public final <T> void typescript(@DelegatesTo(GeneratorOptions.class) Closure<T> closure) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I wonder if parameterising the value like this works in the gradle integration or it really does have to be a raw type like I've been doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I misinterpreted your comment, my fault -- fixed

@CRogers
Copy link
Contributor

CRogers commented May 18, 2022

👍

@svc-autorelease
Copy link
Collaborator

Released 5.27.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants