Skip to content

Commit

Permalink
Add Smithy select task (#135)
Browse files Browse the repository at this point in the history
Adds Smithy select task that allows users to execute `smithy select` within their gradle projects.
  • Loading branch information
hpmellema authored Mar 20, 2024
1 parent 45eda40 commit 722decb
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace smithy.example

structure Foo {
/// a string member
bar: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package software.amazon.smithy.gradle;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import software.amazon.smithy.model.node.Node;

public class SelectTaskTest {
@Test
public void selectsString() {
Utils.withCopy("base-plugin/uses-explicitly-set-cli-version", buildDir -> {
BuildResult result = GradleRunner.create()
.forwardOutput()
.withProjectDir(buildDir)
.withArguments("select", "--selector", "member")
.build();

Utils.assertSmithyBuildDidNotRun(result);

Utils.assertArtifactsNotCreated(buildDir,
"build/smithyprojections/uses-explicitly-set-cli-version/source/build-info/smithy-build-info.json");

Assertions.assertTrue(result.getOutput().contains("smithy.example#Foo$bar"));
});
}

@Test
public void selectsWithShowString() {
Utils.withCopy("base-plugin/uses-explicitly-set-cli-version", buildDir -> {
BuildResult result = GradleRunner.create()
.forwardOutput()
.withProjectDir(buildDir)
.withArguments("select", "--selector", "member", "--show", "type,vars")
.build();

Utils.assertSmithyBuildDidNotRun(result);

Utils.assertArtifactsNotCreated(buildDir,
"build/smithyprojections/uses-explicitly-set-cli-version/source/build-info/smithy-build-info.json");

Assertions.assertTrue(result.getOutput().contains("\"shape\": \"smithy.example#Foo$bar\""));
});
}

@Test
public void selectsWithShowTraitsString() {
Utils.withCopy("base-plugin/uses-explicitly-set-cli-version", buildDir -> {
BuildResult result = GradleRunner.create()
.forwardOutput()
.withProjectDir(buildDir)
.withArguments("select", "--selector", "structure > member", "--show-traits", "documentation", "--stacktrace")
.build();

Utils.assertSmithyBuildDidNotRun(result);

Utils.assertArtifactsNotCreated(buildDir,
"build/smithyprojections/uses-explicitly-set-cli-version/source/build-info/smithy-build-info.json");

Assertions.assertTrue(result.getOutput().contains("\"smithy.api#documentation\": \"a string member\""));
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,24 @@
import software.amazon.smithy.gradle.internal.CliDependencyResolver;
import software.amazon.smithy.gradle.tasks.SmithyBuildTask;
import software.amazon.smithy.gradle.tasks.SmithyFormatTask;
import software.amazon.smithy.gradle.tasks.SmithySelectTask;

/**
* A {@link org.gradle.api.Plugin} that builds and validates Smithy models.
*/
public final class SmithyBasePlugin implements Plugin<Project> {
/**
* Default name to use for the build task created by this plugin.
* Default name to use for the {@link SmithyBuildTask} task created by this plugin.
*/
public static final String SMITHY_BUILD_TASK_NAME = "smithyBuild";
/**
* Default name to use for the {@link SmithySelectTask} task created by this plugin.
*/
public static final String SMITHY_SELECT_TASK_NAME = "select";
/**
* Default name to use for the {@link SmithyFormatTask} task created by this plugin.
*/
public static final String SMITHY_FORMAT_TASK_NAME = "smithyFormat";

private static final GradleVersion MINIMUM_GRADLE_VERSION = GradleVersion.version("8.2.0");

Expand Down Expand Up @@ -75,6 +84,7 @@ private void configureSourceSetDefaults(Project project, SmithyExtension extensi
project.getExtensions().getByType(SourceSetContainer.class).all(sourceSet -> {
createConfigurations(sourceSet, project.getConfigurations());
SmithySourceDirectorySet sds = registerSourceSets(sourceSet, extension);
addSelectTaskForSourceSet(sourceSet, sds, extension);
TaskProvider<SmithyBuildTask> buildTaskTaskProvider = addBuildTaskForSourceSet(sourceSet, sds, extension);
// Ensure smithy-build is executed as part of building the "main" feature
if (SourceSet.isMain(sourceSet)) {
Expand Down Expand Up @@ -143,7 +153,7 @@ private void addFormatTaskForSourceSet(SourceSet sourceSet, SmithySourceDirector
SmithyExtension extension
) {
// Set up format task and Register all smithy sourceSets as formatting targets
String taskName = SmithyUtils.getRelativeSourceSetName(sourceSet, "smithyFormat");
String taskName = SmithyUtils.getRelativeSourceSetName(sourceSet, SMITHY_FORMAT_TASK_NAME);
TaskProvider<SmithyFormatTask> smithyFormat = project.getTasks().register(taskName, SmithyFormatTask.class,
formatTask -> {
formatTask.getModels().set(sds.getSourceDirectories());
Expand All @@ -156,6 +166,18 @@ private void addFormatTaskForSourceSet(SourceSet sourceSet, SmithySourceDirector
}
}

private void addSelectTaskForSourceSet(SourceSet sourceSet, SmithySourceDirectorySet sds,
SmithyExtension extension
) {
String taskName = SmithyUtils.getRelativeSourceSetName(sourceSet, SMITHY_SELECT_TASK_NAME);
project.getTasks().register(taskName, SmithySelectTask.class, selectTask -> {
selectTask.setDescription("Selects smithy models in " + sourceSet.getName() + " source set.");
selectTask.getAllowUnknownTraits().set(extension.getAllowUnknownTraits());
selectTask.getModels().set(sds.getSourceDirectories());
selectTask.getFork().set(extension.getFork());
});
}

private TaskProvider<SmithyBuildTask> addBuildTaskForSourceSet(SourceSet sourceSet,
SmithySourceDirectorySet sds,
SmithyExtension extension
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.gradle.tasks;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.gradle.StartParameter;
import org.gradle.api.GradleException;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
import org.gradle.work.DisableCachingByDefault;


/**
* Executes the Smithy CLI {@code select} command on a set of source files.
*
* <p>This task queries a set of models from the provided sources using a selector.
*
* <p>NOTE: this task must be executed with the command line option `--selector` set.
*
* @see <a href="https://smithy.io/2.0/spec/selectors.html#selectors">Smithy Selectors</a>
*/
@DisableCachingByDefault(because = "Select task should only be called manually.")
public abstract class SmithySelectTask extends AbstractSmithyCliTask {
private static final String DESCRIPTION = "Queries Smithy models with a selector.";

@Inject
public SmithySelectTask(ObjectFactory objectFactory, StartParameter startParameter) {
super(objectFactory, startParameter);
setDescription(DESCRIPTION);
}

@Input
@Option(option = "selector", description = "The Smithy selector to execute")
abstract Property<String> getSelector();


@Input
@Optional
@Option(option = "show", description = "The Smithy selector to execute")
abstract Property<String> getShow();

@Input
@Optional
@Option(option = "show-traits", description = "The Smithy selector to execute")
abstract Property<String> getShowTraits();

@TaskAction
public void execute() {
if (!getSelector().isPresent()) {
throw new GradleException("Select task requires that the command line option `--select` be set.");
}
List<String> extraArgs = new ArrayList<>();
extraArgs.add("--selector");
extraArgs.add(getSelector().get());

if (getShow().isPresent()) {
extraArgs.add("--show");
extraArgs.add(getShow().get());
}

if (getShowTraits().isPresent()) {
extraArgs.add("--show-traits");
extraArgs.add(getShowTraits().get());
}

executeCliProcess("select",
extraArgs,
getModels().get(),
true
);
}
}

0 comments on commit 722decb

Please sign in to comment.