浏览代码

Add a gradle plugin for embedded providers (#105094)

x-content embeds its jackson implementation inside its jar. This commit
formalizes the setup for this embedding with a gradle plugin so that it
can be reused by other libs.
Ryan Ernst 1 年之前
父节点
当前提交
b250f06b09

+ 4 - 0
build-tools-internal/build.gradle

@@ -143,6 +143,10 @@ gradlePlugin {
       id = 'elasticsearch.mrjar'
       implementationClass = 'org.elasticsearch.gradle.internal.MrjarPlugin'
     }
+    embeddedProvider {
+      id = 'elasticsearch.embedded-providers'
+      implementationClass = 'org.elasticsearch.gradle.internal.EmbeddedProviderPlugin'
+    }
     releaseTools {
       id = 'elasticsearch.release-tools'
       implementationClass = 'org.elasticsearch.gradle.internal.release.ReleaseToolsPlugin'

+ 62 - 0
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/EmbeddedProviderExtension.java

@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.internal;
+
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.api.file.Directory;
+import org.gradle.api.provider.Provider;
+import org.gradle.api.tasks.SourceSet;
+import org.gradle.api.tasks.Sync;
+
+import static org.elasticsearch.gradle.internal.conventions.GUtils.capitalize;
+import static org.elasticsearch.gradle.util.GradleUtils.getJavaSourceSets;
+import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE;
+import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.DIRECTORY_TYPE;
+
+public class EmbeddedProviderExtension {
+
+    private final Project project;
+
+    public EmbeddedProviderExtension(Project project) {
+        this.project = project;
+    }
+
+    void impl(String implName, Project implProject) {
+        String projectName = implProject.getName();
+        String capitalName = capitalize(projectName);
+
+        Configuration implConfig = project.getConfigurations().detachedConfiguration(project.getDependencies().create(implProject));
+        implConfig.attributes(attrs -> {
+            attrs.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_TYPE);
+            attrs.attribute(EmbeddedProviderPlugin.IMPL_ATTR, true);
+        });
+
+        String manifestTaskName = "generate" + capitalName + "ProviderManifest";
+        Provider<Directory> generatedResourcesDir = project.getLayout().getBuildDirectory().dir("generated-resources");
+        var generateProviderManifest = project.getTasks().register(manifestTaskName, GenerateProviderManifest.class);
+        generateProviderManifest.configure(t -> {
+            t.getManifestFile().set(generatedResourcesDir.map(d -> d.file("LISTING.TXT")));
+            t.getProviderImplClasspath().from(implConfig);
+        });
+
+        String implTaskName = "generate" + capitalName + "ProviderImpl";
+        var generateProviderImpl = project.getTasks().register(implTaskName, Sync.class);
+        generateProviderImpl.configure(t -> {
+            t.into(generatedResourcesDir);
+            t.into("IMPL-JARS/" + implName, spec -> {
+                spec.from(implConfig);
+                spec.from(generateProviderManifest);
+            });
+        });
+
+        var mainSourceSet = getJavaSourceSets(project).findByName(SourceSet.MAIN_SOURCE_SET_NAME);
+        mainSourceSet.getOutput().dir(generateProviderImpl);
+    }
+}

+ 34 - 0
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/EmbeddedProviderPlugin.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.internal;
+
+import org.elasticsearch.gradle.transform.UnzipTransform;
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.attributes.Attribute;
+
+import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE;
+import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.DIRECTORY_TYPE;
+import static org.gradle.api.artifacts.type.ArtifactTypeDefinition.JAR_TYPE;
+
+public class EmbeddedProviderPlugin implements Plugin<Project> {
+    static final Attribute<Boolean> IMPL_ATTR = Attribute.of("is.impl", Boolean.class);
+
+    @Override
+    public void apply(Project project) {
+
+        project.getDependencies().registerTransform(UnzipTransform.class, transformSpec -> {
+            transformSpec.getFrom().attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_TYPE).attribute(IMPL_ATTR, true);
+            transformSpec.getTo().attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_TYPE).attribute(IMPL_ATTR, true);
+            transformSpec.parameters(parameters -> parameters.getIncludeArtifactName().set(true));
+        });
+
+        project.getExtensions().create("embeddedProviders", EmbeddedProviderExtension.class, project);
+    }
+}

+ 3 - 45
libs/x-content/build.gradle

@@ -6,44 +6,17 @@
  * Side Public License, v 1.
  */
 
-
-import org.elasticsearch.gradle.transform.UnzipTransform
-import org.elasticsearch.gradle.internal.GenerateProviderManifest
-import org.gradle.api.internal.artifacts.ArtifactAttributes
-
-import java.util.stream.Collectors
-
 apply plugin: 'elasticsearch.build'
 apply plugin: 'elasticsearch.publish'
+apply plugin: 'elasticsearch.embedded-providers'
 
-def isImplAttr = Attribute.of("is.impl", Boolean)
-
-configurations {
-  providerImpl {
-    attributes.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
-    attributes.attribute(isImplAttr, true)
-  }
+embeddedProviders {
+  impl 'x-content', project(':libs:elasticsearch-x-content:impl')
 }
 
 dependencies {
-  registerTransform(
-    UnzipTransform.class, transformSpec -> {
-    transformSpec.getFrom()
-      .attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.JAR_TYPE)
-      .attribute(isImplAttr, true)
-    transformSpec.getTo()
-      .attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.DIRECTORY_TYPE)
-      .attribute(isImplAttr, true)
-    transformSpec.parameters(parameters -> {
-      parameters.includeArtifactName.set(true)
-    })
-
-  })
-
   api project(':libs:elasticsearch-core')
 
-  providerImpl project(':libs:elasticsearch-x-content:impl')
-
   testImplementation(project(":test:framework")) {
     exclude group: 'org.elasticsearch', module: 'elasticsearch-x-content'
   }
@@ -66,18 +39,3 @@ tasks.named("thirdPartyAudit").configure {
 tasks.named("dependencyLicenses").configure {
   mapping from: /jackson-.*/, to: 'jackson'
 }
-
-Directory generatedResourcesDir = layout.buildDirectory.dir('generated-resources').get()
-def generateProviderManifest = tasks.register("generateProviderManifest", GenerateProviderManifest.class) {
-  manifestFile = generatedResourcesDir.file("LISTING.TXT")
-  getProviderImplClasspath().from(configurations.providerImpl)
-}
-
-def generateProviderImpl = tasks.register("generateProviderImpl", Sync) {
-  destinationDir = generatedResourcesDir.dir("impl").getAsFile()
-  into("IMPL-JARS/x-content") {
-    from(configurations.providerImpl)
-    from(generateProviderManifest)
-  }
-}
-sourceSets.main.output.dir(generateProviderImpl)