Slackbot
10/24/2022, 3:25 PMNiels Doucet
10/24/2022, 3:25 PMdiffExtension {
oldSchema { // SchemaResource
schemaUrl // Property<String>
username // Property<String>
password // Property<String>
requiresExtraction // Property<Boolean>
schemaFile // Property<String>
schema // RegularFileProperty
}
newSchema { // SchemaResource
schemaUrl // Property<String>
username // Property<String>
password // Property<String>
requiresExtraction // Property<Boolean>
schemaFile // Property<String>
schema // RegularFileProperty
}
outputDir // DirectoryProperty
}
you either define the schema
property, or all the others, depending on where the file should be coming from. This is rather confusing in my opinion, so I would like it to look something like this instead:
diffExtension {
oldSchema { // RemoteSchemaResource --> somehow have a way to say to gradle that this is remote in this case
schemaUrl // Property<String>
username // Property<String>
password // Property<String>
requiresExtraction // Property<Boolean>
schemaFile // Property<String>
}
newSchema { // LocalSchemaResource --> somehow have a way to say to gradle that this is local in this case
schema // RegularFileProperty
}
outputDir // DirectoryProperty
}
Note that oldSchema
and newSchema
could take on the RemoteSchemaResource
or LocalSchemaResource
interchangeably.Vampire
10/24/2022, 3:33 PMdiffExtension {
oldSchema.set(RemoteSchemaResource {
...
}
newSchema.set(LocalSchemaResource {
...
}
outputDir // DirectoryProperty
}
Vampire
10/24/2022, 3:33 PMdiffExtension {
oldSchema = RemoteSchemaResource {
...
}
newSchema = LocalSchemaResource {
...
}
outputDir // DirectoryProperty
}
Vampire
10/24/2022, 3:34 PMdiffExtension {
oldSchema = remote {
...
}
newSchema = local {
...
}
outputDir // DirectoryProperty
}
Vampire
10/24/2022, 3:35 PMremote
and local
have a parameter Action<RemoteSchemaResource>
and Action<LocalSchemaResource>
respectively and their body will create an instance, run the action against it and then return it.Vampire
10/24/2022, 3:37 PMdiffExtension {
oldSchema remote {
...
}
newSchema local {
...
}
outputDir // DirectoryProperty
}
Niels Doucet
10/24/2022, 4:52 PMAction<RemoteSchemaResource>
way that you proposed. I'm just struggling to translate that to my extension object, which currently looks like this:
public interface DiffExtension {
@Nested
SchemaResource getOldSchema();
default void oldSchema(Action<? super SchemaResource> action) {
action.execute(getOldSchema());
}
@Nested
SchemaResource getNewSchema();
default void newSchema(Action<? super SchemaResource> action) {
action.execute(getNewSchema());
}
DirectoryProperty getOutputDir();
}
what would the implementation of those configure Action methods be? Or do I define those on the SchemaResource
Object itself instead of on the Extension?Vampire
10/24/2022, 4:56 PMpublic interface DiffExtension {
@Nested
Property<SchemaResource> getOldSchema();
@Nested
Property<SchemaResource> getNewSchema();
default SchemaResource remote(Action<? super RemoteSchemaResource> action) {
RemoteSchemaResource result = new RemoteSchemaResource();
action.execute(result);
return result;
}
default SchemaResource local(Action<? super LocalSchemaResource> action) {
LocalSchemaResource result = new LocalSchemaResource();
action.execute(result);
return result;
}
DirectoryProperty getOutputDir();
}
Niels Doucet
10/24/2022, 4:57 PMephemient
10/25/2022, 7:01 AM// buildSrc/src/main/java/Schema.java
public interface Schema extends Named {
}
// buildSrc/src/main/java/LocalSchema.java
public interface LocalSchema extends Schema {
RegularFileProperty getSchema();
}
// buildSrc/src/main/java/RemoteSchema.java
public interface RemoteSchema extends Schema {
Property<URI> getSchemaUri();
}
// buildSrc/src/main/java/DiffPlugin.java
public class DiffPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
ExtensiblePolymorphicDomainObjectContainer<Schema> diffExtension = project.getObjects().polymorphicDomainObjectContainer(Schema.class);
diffExtension.registerBinding(LocalSchema.class, LocalSchema.class);
diffExtension.registerBinding(RemoteSchema.class, RemoteSchema.class);
project.getExtensions().add(PolymorphicDomainObjectContainer.class, "diffExtension", diffExtension);
}
}
// build.gradle
diffExtension {
oldSchema(RemoteSchema) {
schemaUrl = uri('<https://example.com/schema>')
}
newSchema(LocalSchema) {
schema = file('example.schema')
}
}
ephemient
10/25/2022, 7:10 AMDomainObjectContainer
but only oldSchema
and newSchema
then you could still create methods like
// buildSrc/src/main/java/DiffExtension.java
public interface DiffExtension {
Property<Schema> getOldSchema();
Property<Schema> getNewSchema();
<T extends Schema> T oldSchema(Class<T> type, Action<? super T> configuration);
<T extends Schema> T newSchema(Class<T> type, Action<? super T> configuration);
}
// buildSrc/src/main/java/DefaultDiffExtension.java
public abstract class DefaultDiffExtension implements DiffExtension {
private final ObjectFactory objects;
public DefaultDiffExtension(ObjectFactory objects) {
this.objects = objects;
}
@Override
public <T extends Schema> T oldSchema(Class<T> type, Action<? super T> configuration) {
T schema = objects.newInstance(type);
getOldSchema().set(schema);
configuration.execute(schema);
return schema;
}
@Override
public <T extends Schema> T newSchema(Class<T> type, Action<? super T> configuration) {
T schema = objects.newInstance(type);
getNewSchema().set(schema);
configuration.execute(schema);
return schema;
}
}
// buildSrc/src/main/java/DiffPlugin.java
public class DiffPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getExtensions().create(DiffExtension.class, "diffExtension", DefaultDiffExtension.class);
}
}
to make it work in a similar wayVampire
10/25/2022, 8:08 AMdiffExtension {
oldSchema(RemoteSchemaSource::class) {
...
}
newSchema(LocalSchemaSource::class) {
...
}
outputDir // DirectoryProperty
}
Or maybe it could also be made
diffExtension {
oldSchema<RemoteSchemaSource> {
...
}
newSchema<LocalSchemaSource> {
...
}
outputDir // DirectoryProperty
}
Or another option would be 4 methods
diffExtension {
remoteOldSchema {
...
}
localNewSchema {
...
}
outputDir // DirectoryProperty
}
and the remote and local of the same target exclude each other.ephemient
10/25/2022, 8:10 AMs/Class<T>/KClass<T>/
accessors for the extension like it does for other methods in the Gradle API 😞 so you'd have to write it in Kotlin to get 1 or 2 thereephemient
10/25/2022, 8:11 AMephemient
10/25/2022, 8:12 AM{remote,local}{Old,New}Schema
permutations is doable with this small number I guessNiels Doucet
10/25/2022, 8:25 AMoldSchema(RemoteSchemaResource::class) { }
. I'm in the process or trying out this approach as we speak. It seems like the dsl now looks like the following:
schemaDiff {
oldSchema(RemoteSchemaResource::class.java, {
schemaUrl.set("<https://some.uri>")
username.set("myUsername")
password.set("myPassword")
requiresExtraction.set(true)
schemaFile.set("filename.to.extract")
})
newSchema(LocalSchemaResource::class.java, {
schema.set(schemaPath)
})
}
it's not horrible, but I can't say it looks amazing either 🤔Niels Doucet
10/25/2022, 8:37 AMephemient
10/25/2022, 8:41 AMschemaDiff {
oldSchema(RemoteSchemaResource::class.java) {
schemaUrl.set("<https://some.uri>")
you can also write write the extension in Kotlin to add KClass
overloads if you want (gradle-kotlin-dsl has a bunch generated for the Gradle API but I haven't figured out how to get it to do that for custom types)ephemient
10/25/2022, 8:43 AMdiffExtension {
oldSchema.set(remote {
...
})
in Kotlin which I find more annoying, but YMMVVampire
10/25/2022, 8:51 AMNiels Doucet
10/25/2022, 8:52 AMNiels Doucet
10/25/2022, 8:54 AM