Skip to content

Commit

Permalink
Add a new plugin for setting up a trait package (#138)
Browse files Browse the repository at this point in the history
Add a new plugin for setting up a trait package.
  • Loading branch information
hpmellema authored Apr 19, 2024
1 parent 56665b1 commit 8a5c21b
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 10 deletions.
2 changes: 1 addition & 1 deletion examples/jar-plugin/kotlin-jvm-project/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This project adds smithy models to a JAR created by a Kotlin project

plugins {
kotlin("jvm") version "1.9.0"
kotlin("jvm") version "1.9.23"
id("software.amazon.smithy.gradle.smithy-jar").version("1.0.0")
}

Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ rootProject.name = "smithy-gradle"

include("smithy-base")
include("smithy-jar")
include("smithy-trait-package")
include("integ-test-utils")
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.Directory;
import org.gradle.api.file.FileCollection;
Expand Down Expand Up @@ -238,5 +239,17 @@ static String getRelativeSourceSetName(SourceSet sourceSet, String name) {
public static Configuration getCliConfiguration(Project project) {
return project.getConfigurations().getByName(SMITHY_CLI_CONFIGURATION_NAME);
}

/**
* Checks if a dependency matches an expected name.
*
* @param dependency Dependency to check
* @param name Name of expected dependency
* @return true if the dependency matches the expected name
*/
public static boolean isMatchingDependency(Dependency dependency, String name) {
return Objects.equals(dependency.getGroup(), "software.amazon.smithy")
&& dependency.getName().equals(name);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package software.amazon.smithy.gradle.internal;

import java.io.File;
import java.util.Objects;
import java.util.Optional;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
Expand Down Expand Up @@ -46,18 +45,19 @@ private CliDependencyResolver() {}
*
* @param project Project to add dependencies to.
*
* @return Returns the resolved CLI version
*/
public static void resolve(Project project) {
public static String resolve(Project project) {
Configuration cli = SmithyUtils.getCliConfiguration(project);

// Prefer explicitly set dependency first.
Optional<Dependency> explicitCliDepOptional = cli.getAllDependencies().stream()
.filter(CliDependencyResolver::isMatchingDependency)
.filter(d -> SmithyUtils.isMatchingDependency(d, SMITHY_CLI_DEP_NAME))
.findFirst();
if (explicitCliDepOptional.isPresent()) {
project.getLogger().info(String.format("(using explicitly configured Smithy CLI: %s)",
explicitCliDepOptional.get().getVersion()));
return;
return explicitCliDepOptional.get().getVersion();
}

// Force projects in the main smithy repo to use an explicit smithy cli dependency
Expand All @@ -66,6 +66,8 @@ public static void resolve(Project project) {
// If no explicit dependency was found, find the CLI version by scanning and set this as a dependency
String cliVersion = getCliVersion(project);
project.getDependencies().add(cli.getName(), String.format(DEPENDENCY_NOTATION, cliVersion));

return cliVersion;
}

private static String getCliVersion(Project project) {
Expand Down Expand Up @@ -101,11 +103,6 @@ public static String detectCliVersionInRuntimeDependencies(ConfigurationContaine
.orElse(null);
}

private static boolean isMatchingDependency(Dependency dependency) {
return Objects.equals(dependency.getGroup(), "software.amazon.smithy")
&& dependency.getName().equals(SMITHY_CLI_DEP_NAME);
}

private static String scanForSmithyCliVersion(Project project) {
// Finally, scan the buildScript dependencies for a smithy-model dependency. This
// should be found because the Gradle plugin has a dependency on it.
Expand Down
23 changes: 23 additions & 0 deletions smithy-trait-package/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
description = "Configures a Java library package for Smithy traits, using " +
"Smithy's trait-codegen plugin to generate Java implementation of traits."

plugins {
id("smithy-gradle-plugin.plugin-conventions")
}

gradlePlugin {
plugins {
create("smithy-trait-package-plugin") {
id = "${group}.smithy-trait-package"
displayName = "Smithy Gradle Trait Package plugin."
description = project.description
implementationClass = "software.amazon.smithy.gradle.SmithyTraitPackagePlugin"
tags.addAll("smithy", "api", "building")
}
}
}

dependencies {
implementation(project(":smithy-jar"))
implementation(project(":smithy-base"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.gradle;

import java.nio.file.Path;
import java.util.Optional;
import javax.inject.Inject;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import software.amazon.smithy.gradle.internal.CliDependencyResolver;

/**
* A {@link org.gradle.api.Plugin} that adds sets up a package for a custom trait.
*/
public class SmithyTraitPackagePlugin implements Plugin<Project> {
private static final String SMITHY_TRAIT_CODEGEN_DEP_NAME = "smithy-trait-codegen";
private static final String TRAIT_CODEGEN_PLUGIN_NAME = "trait-codegen";
private static final String DEPENDENCY_NOTATION = "software.amazon.smithy:%s:%s";

private static final String SOURCE = "source";

private SmithyExtension extension;
private final Project project;

@Inject
public SmithyTraitPackagePlugin(Project project) {
this.project = project;
}

@Override
public void apply(Project project) {
project.getPlugins().apply(JavaLibraryPlugin.class);
project.getPlugins().apply(SmithyJarPlugin.class);

extension = project.getExtensions().getByType(SmithyExtension.class);

// Only configure trait codegen dependency for main sourceSet
project.getExtensions().getByType(SourceSetContainer.class).all(sourceSet -> {
if (SourceSet.isMain(sourceSet)) {
// Add Trait codegen outputs to source set
addGeneratedTraits(sourceSet);
project.afterEvaluate(p -> configureDependencies(sourceSet));
}
});
}

private void addGeneratedTraits(SourceSet sourceSet) {
Path pluginOutput = extension.getPluginProjectionPath(SOURCE, TRAIT_CODEGEN_PLUGIN_NAME).get();
sourceSet.getJava().srcDir(pluginOutput);
sourceSet.getResources().srcDir(pluginOutput).exclude("**/*.java");
}

// TODO: Add smithy-model dependency?
private void configureDependencies(SourceSet sourceSet) {
Configuration smithyBuild = project.getConfigurations()
.getByName(SmithyUtils.getSmithyBuildConfigurationName(sourceSet));

// Prefer explicit dependency
Optional<Dependency> explicitDepOptional = smithyBuild.getAllDependencies().stream()
.filter(d -> SmithyUtils.isMatchingDependency(d,
SmithyTraitPackagePlugin.SMITHY_TRAIT_CODEGEN_DEP_NAME))
.findFirst();
if (explicitDepOptional.isPresent()) {
project.getLogger().info(String.format("(using explicitly configured Dependency for %s: %s)",
SmithyTraitPackagePlugin.SMITHY_TRAIT_CODEGEN_DEP_NAME, explicitDepOptional.get().getVersion()));
return;
}

// If trait codegen does not exist, add the dependency with the same version as the resolved CLI version
String cliVersion = CliDependencyResolver.resolve(project);
project.getDependencies().add(smithyBuild.getName(),
String.format(DEPENDENCY_NOTATION, SmithyTraitPackagePlugin.SMITHY_TRAIT_CODEGEN_DEP_NAME, cliVersion));
}
}

0 comments on commit 8a5c21b

Please sign in to comment.