Skip to content

Commit

Permalink
Add merge task to handle existing trait definitions (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
hpmellema authored Jun 13, 2024
1 parent 8a5c21b commit 4650d02
Show file tree
Hide file tree
Showing 20 changed files with 562 additions and 86 deletions.
11 changes: 11 additions & 0 deletions examples/trait-module-plugin/create-simple-trait/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Example Project - Custom Trait Module

TODO

## Using the example as a starting point

TODO

## See Also

TODO: Add plugin documentation when available
17 changes: 17 additions & 0 deletions examples/trait-module-plugin/create-simple-trait/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description = "Custom Smithy structure trait with multiple inputs"

plugins {
id("software.amazon.smithy.gradle.smithy-trait-module") version "1.0.0"
}

group = "software.amazon.smithy"
version = "9.9.9"

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation("software.amazon.smithy:smithy-model:[1.0, 2.0[")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
$version: "2.0"

namespace io.smithy.gradle.example

@trait(
selector: "resource"
breakingChanges: [
{
change: "presence"
}
]
)
structure resourceMetadata {
/// Provides a custom name for your resource.
@required
description: String

/// A type for the resource
@required
type: ResourceType

/// A list of associated structures
associated: Associated
}

@private
@idRef(failWhenMissing: true, selector: "structure")
string Associated

@private
enum ResourceType {
NORMAL
SPECIAL
OTHER
NONE
}

@trait(selector: "member")
string jsonName
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
rootProject.name = "create-simple-trait"

pluginManagement {
repositories {
mavenLocal()
mavenCentral()
// Uncomment these to use the published version of the plugin from your preferred source.
// gradlePluginPortal()
}
}
11 changes: 11 additions & 0 deletions examples/trait-module-plugin/create-simple-trait/smithy-build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "1.0",
"sources": ["model"],
"plugins": {
"trait-codegen": {
"package": "io.smithy.gradle.examples.traits",
"namespace": "io.smithy.gradle.example",
"header": ["Header line one", "Header line two"]
}
}
}
11 changes: 11 additions & 0 deletions examples/trait-module-plugin/use-with-existing-trait/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Example Project - Trait Module with both generated and manual traits

TODO

## Using the example as a starting point

TODO

## See Also

TODO: Add plugin documentation when available
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description = "Use existing"

plugins {
id("software.amazon.smithy.gradle.smithy-trait-module") version "1.0.0"
}

group = "software.amazon.smithy"
version = "9.9.9"

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation("software.amazon.smithy:smithy-model:[1.0, 2.0[")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
$version: "2.0"

namespace io.smithy.gradle.example

@trait(
selector: "resource"
breakingChanges: [
{
change: "presence"
}
]
)
structure resourceMetadata {
/// Provides a custom name for your resource.
@required
description: String

/// A type for the resource
@required
type: ResourceType

/// A list of associated structures
associated: Associated
}

@private
@idRef(failWhenMissing: true, selector: "structure")
string Associated

@private
enum ResourceType {
NORMAL
SPECIAL
OTHER
NONE
}

@tags(["no-generate"])
@trait(selector: "member")
string jsonName
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
rootProject.name = "use-with-existing-trait"

pluginManagement {
repositories {
mavenLocal()
mavenCentral()
// Uncomment these to use the published version of the plugin from your preferred source.
// gradlePluginPortal()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "1.0",
"sources": ["model"],
"plugins": {
"trait-codegen": {
"package": "io.smithy.gradle.examples.traits",
"namespace": "io.smithy.gradle.example",
"excludeTags": ["no-generate"],
"header": ["Header line one", "Header line two"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.smithy.gradle.examples.traits;

import software.amazon.smithy.model.FromSourceLocation;
import software.amazon.smithy.model.SourceLocation;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.StringTrait;
public final class JsonNameTrait extends StringTrait {

public static final ShapeId ID = ShapeId.from("io.smithy.gradle.example#jsonName");

private JsonNameTrait(String name) {
super(ID, name, SourceLocation.NONE);
}

private JsonNameTrait(String name, FromSourceLocation sourceLocation) {
super(ID, name, sourceLocation);
}

public static final class Provider extends StringTrait.Provider<JsonNameTrait> {
public Provider() {
super(ID, JsonNameTrait::new);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.smithy.gradle.examples.traits.JsonNameTrait$Provider
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
Expand All @@ -35,6 +36,7 @@
import org.gradle.testkit.runner.BuildTask;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.Assertions;
import software.amazon.smithy.utils.IoUtils;

public final class Utils {
private Utils() {}
Expand Down Expand Up @@ -179,4 +181,14 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
}
});
}

public static String getJarEntryContents(File jarFile, String entryPath) {
try (JarFile jar = new JarFile(jarFile);
InputStream is = jar.getInputStream(jar.getJarEntry(entryPath))
) {
return IoUtils.toUtf8String(is);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ rootProject.name = "smithy-gradle"

include("smithy-base")
include("smithy-jar")
include("smithy-trait-package")
include("smithy-trait-module")
include("integ-test-utils")
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ plugins {

gradlePlugin {
plugins {
create("smithy-trait-package-plugin") {
id = "${group}.smithy-trait-package"
create("smithy-trait-module-plugin") {
id = "${group}.smithy-trait-module"
displayName = "Smithy Gradle Trait Package plugin."
description = project.description
implementationClass = "software.amazon.smithy.gradle.SmithyTraitPackagePlugin"
implementationClass = "software.amazon.smithy.gradle.SmithyTraitModulePlugin"
tags.addAll("smithy", "api", "building")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package software.amazon.smithy.gradle;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.jupiter.api.Test;

public class CreatesCustomTraitTest {

@Test
public void createsTraitsAndAddsToJar() {
Utils.withCopy("trait-module-plugin/create-simple-trait", buildDir -> {
BuildResult result = GradleRunner.create()
.forwardOutput()
.withProjectDir(buildDir)
.withArguments("clean", "build", "--stacktrace")
.build();

Utils.assertSmithyBuildTaskRan(result);
Utils.assertValidationRan(result);
Utils.assertJarContains(buildDir, "build/libs/create-simple-trait-9.9.9.jar",
"META-INF/MANIFEST.MF",
"META-INF/smithy/manifest",
"META-INF/smithy/custom-trait.smithy",
"META-INF/services/software.amazon.smithy.model.traits.TraitService",
"io/smithy/gradle/examples/traits/ResourceMetadataTrait.class",
"io/smithy/gradle/examples/traits/ResourceType.class",
"io/smithy/gradle/examples/traits/JsonNameTrait.class"
);

String spiContents = Utils.getJarEntryContents(new File(buildDir, "build/libs/create-simple-trait-9.9.9.jar"),
"META-INF/services/software.amazon.smithy.model.traits.TraitService");

assertTrue(spiContents.contains("io.smithy.gradle.examples.traits.ResourceMetadataTrait$Provider"));
assertTrue(spiContents.contains("io.smithy.gradle.examples.traits.JsonNameTrait$Provider"));
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package software.amazon.smithy.gradle;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class RespectsManualTraitTest {

@Test
public void respectsExistingTraitAndMergesSpiFiles() {
Utils.withCopy("trait-module-plugin/use-with-existing-trait", buildDir -> {
BuildResult result = GradleRunner.create()
.forwardOutput()
.withProjectDir(buildDir)
.withArguments("clean", "build", "--stacktrace")
.build();

Utils.assertSmithyBuildTaskRan(result);
Utils.assertValidationRan(result);

// Check that the merge task was executed successfully
Assertions.assertTrue(result.task(":mergeSpiFiles").getOutcome() == TaskOutcome.SUCCESS);

Utils.assertJarContains(buildDir, "build/libs/use-with-existing-trait-9.9.9.jar",
"META-INF/MANIFEST.MF",
"META-INF/smithy/manifest",
"META-INF/smithy/custom-trait.smithy",
"META-INF/services/software.amazon.smithy.model.traits.TraitService",
"io/smithy/gradle/examples/traits/ResourceMetadataTrait.class",
"io/smithy/gradle/examples/traits/ResourceType.class",
"io/smithy/gradle/examples/traits/JsonNameTrait.class"
);

String spiContents = Utils.getJarEntryContents(new File(buildDir, "build/libs/use-with-existing-trait-9.9.9.jar"),
"META-INF/services/software.amazon.smithy.model.traits.TraitService");

assertTrue(spiContents.contains("io.smithy.gradle.examples.traits.ResourceMetadataTrait$Provider"));
assertTrue(spiContents.contains("io.smithy.gradle.examples.traits.JsonNameTrait$Provider"));
});
}
}
Loading

0 comments on commit 4650d02

Please sign in to comment.