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

Add a new plugin for setting up a trait package #138

Merged
merged 3 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
}
}
Loading