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

Resolve all imports relative to their config #457

Merged
merged 1 commit into from
Jun 5, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public final class SmithyBuild {
public static final String VERSION = "1.0";

SmithyBuildConfig config;
Path importBasePath;
Path outputDirectory;
Function<String, Optional<ProjectionTransformer>> transformFactory;
Function<String, Optional<SmithyBuildPlugin>> pluginFactory;
Expand Down Expand Up @@ -170,7 +169,6 @@ public void build(Consumer<ProjectionResult> resultCallback, BiConsumer<String,
*/
public SmithyBuild config(SmithyBuildConfig config) {
this.config = config;
config.getImportBasePath().ifPresent(this::importBasePath);
return this;
}

Expand All @@ -197,14 +195,8 @@ public SmithyBuild model(Model model) {
return this;
}

/**
* Sets the base path for where imports are found.
*
* @param importBasePath Base path to look for imports.
* @return Returns the builder.
*/
@Deprecated
public SmithyBuild importBasePath(Path importBasePath) {
this.importBasePath = importBasePath;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ final class SmithyBuildImpl {
private final Function<String, Optional<ProjectionTransformer>> transformFactory;
private final Function<String, Optional<SmithyBuildPlugin>> pluginFactory;
private final Model model;
private final Path importBasePath;
private final ClassLoader pluginClassLoader;
private final Set<Path> sources;
private final Predicate<String> projectionFilter;
Expand Down Expand Up @@ -100,11 +99,6 @@ final class SmithyBuildImpl {
outputDirectory = Paths.get(".").toAbsolutePath().normalize().resolve("build").resolve("smithy");
}

// Use the base path of the configuration or get the current working directory.
importBasePath = builder.importBasePath != null
? builder.importBasePath
: Paths.get(".").toAbsolutePath().normalize();

// Create the transformers for each projection.
config.getProjections().forEach((projectionName, projectionConfig) -> {
transformers.put(projectionName, createTransformers(projectionName, projectionConfig));
Expand Down Expand Up @@ -267,7 +261,7 @@ private Model createBaseModel() {
if (!config.getImports().isEmpty()) {
LOGGER.fine(() -> "Merging the following imports into the loaded model: " + config.getImports());
ModelAssembler assembler = modelAssemblerSupplier.get().addModel(model);
config.getImports().forEach(path -> assembler.addImport(importBasePath.resolve(path)));
config.getImports().forEach(assembler::addImport);
resolvedModel = assembler.assemble().unwrap();
}

Expand All @@ -283,7 +277,7 @@ private ProjectionResult applyProjection(String projectionName, ProjectionConfig
"Merging the following `%s` projection imports into the loaded model: %s",
projectionName, projection.getImports()));
ModelAssembler assembler = modelAssemblerSupplier.get().addModel(resolvedModel);
projection.getImports().forEach(path -> assembler.addImport(importBasePath.resolve(path)));
projection.getImports().forEach(assembler::addImport);
ValidatedResult<Model> resolvedResult = assembler.assemble();

// Fail if the model can't be merged with the imports.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
package software.amazon.smithy.build.model;

import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import software.amazon.smithy.build.SmithyBuildException;
import software.amazon.smithy.model.SourceLocation;
import software.amazon.smithy.model.loader.ModelSyntaxException;
Expand All @@ -41,7 +44,7 @@ private ConfigLoader() {}
static SmithyBuildConfig load(Path path) {
try {
String content = IoUtils.readUtf8File(path);
return load(loadWithJson(path, content).expectObjectNode());
return load(path.getParent(), loadWithJson(path, content).expectObjectNode());
} catch (ModelSyntaxException e) {
throw new SmithyBuildException(e);
}
Expand All @@ -51,9 +54,31 @@ private static Node loadWithJson(Path path, String contents) {
return Node.parseJsonWithComments(contents, path.toString()).accept(new VariableExpander());
}

private static SmithyBuildConfig load(ObjectNode node) {
private static SmithyBuildConfig load(Path baseImportPath, ObjectNode node) {
NodeMapper mapper = new NodeMapper();
return mapper.deserialize(node, SmithyBuildConfig.class);
return resolveImports(baseImportPath, mapper.deserialize(node, SmithyBuildConfig.class));
}

private static SmithyBuildConfig resolveImports(Path baseImportPath, SmithyBuildConfig config) {
List<String> imports = config.getImports().stream()
.map(importPath -> baseImportPath.resolve(importPath).toString())
.collect(Collectors.toList());

Map<String, ProjectionConfig> projections = config.getProjections().entrySet().stream()
.map(entry -> Pair.of(entry.getKey(), resolveProjectionImports(baseImportPath, entry.getValue())))
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));

return config.toBuilder()
.imports(imports)
.projections(projections)
.build();
}

private static ProjectionConfig resolveProjectionImports(Path baseImportPath, ProjectionConfig config) {
List<String> imports = config.getImports().stream()
.map(importPath -> baseImportPath.resolve(importPath).toString())
.collect(Collectors.toList());
return config.toBuilder().imports(imports).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.MapUtils;
import software.amazon.smithy.utils.SmithyBuilder;
import software.amazon.smithy.utils.ToSmithyBuilder;

/**
* ProjectionConfig stored in a {@link SmithyBuildConfig}.
*/
public final class ProjectionConfig {
public final class ProjectionConfig implements ToSmithyBuilder<ProjectionConfig> {
private final boolean isAbstract;
private final List<String> imports;
private final List<TransformConfig> transforms;
Expand All @@ -50,6 +51,15 @@ public static Builder builder() {
return new Builder();
}

@Override
public Builder toBuilder() {
return builder()
.imports(imports)
.plugins(plugins)
.transforms(transforms)
.setAbstract(isAbstract);
}

/**
* @return Gets the immutable transforms in the projection.
*/
Expand Down Expand Up @@ -80,6 +90,8 @@ public List<String> getImports() {
return imports;
}



/**
* Builds a {@link ProjectionConfig}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,10 @@ public final class SmithyBuildConfig implements ToSmithyBuilder<SmithyBuildConfi
private final String outputDirectory;
private final Map<String, ProjectionConfig> projections;
private final Map<String, ObjectNode> plugins;
private final Path importBasePath;

private SmithyBuildConfig(Builder builder) {
SmithyBuilder.requiredState("version", builder.version);
version = builder.version;
importBasePath = builder.importBasePath;
outputDirectory = builder.outputDirectory;
imports = ListUtils.copyOf(builder.imports);
projections = MapUtils.copyOf(builder.projections);
Expand Down Expand Up @@ -110,14 +108,12 @@ public static SmithyBuildConfig load(Path file) {

@Override
public Builder toBuilder() {
Builder builder = builder()
return builder()
.version(version)
.outputDirectory(outputDirectory)
.imports(imports)
.projections(projections)
.plugins(plugins);
builder.importBasePath = importBasePath;
return builder;
}

/**
Expand Down Expand Up @@ -167,15 +163,6 @@ public Map<String, ObjectNode> getPlugins() {
return Collections.unmodifiableMap(plugins);
}

/**
* Gets the base path of where the config file was loaded from.
*
* @return Returns the optionally present base path.
*/
public Optional<Path> getImportBasePath() {
return Optional.ofNullable(importBasePath);
}

/**
* Builder used to create a {@link SmithyBuildConfig}.
*/
Expand All @@ -185,7 +172,6 @@ public static final class Builder implements SmithyBuilder<SmithyBuildConfig> {
private final Map<String, ObjectNode> plugins = new LinkedHashMap<>();
private String version;
private String outputDirectory;
private Path importBasePath;

Builder() {}

Expand All @@ -212,7 +198,6 @@ public Builder version(String version) {
* @return Returns the updated builder.
*/
public Builder load(Path config) {
importBasePath = config.getParent();
return merge(ConfigLoader.load(config));
}

Expand All @@ -228,9 +213,6 @@ public Builder merge(SmithyBuildConfig config) {
imports.addAll(config.getImports());
projections.putAll(config.getProjections());
plugins.putAll(config.getPlugins());
if (config.importBasePath != null) {
importBasePath = config.importBasePath;
}
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.DocumentationTrait;
import software.amazon.smithy.model.traits.SensitiveTrait;
import software.amazon.smithy.model.traits.TagsTrait;
import software.amazon.smithy.utils.IoUtils;
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.MapUtils;
Expand Down Expand Up @@ -197,6 +198,7 @@ public void cannotSetFiltersOrMappersOnSourceProjection() {
public void loadsImports() throws Exception {
SmithyBuildConfig config = SmithyBuildConfig.builder()
.load(Paths.get(getClass().getResource("imports/smithy-build.json").toURI()))
.load(Paths.get(getClass().getResource("otherimports/smithy-build.json").toURI()))
.outputDirectory(outputDirectory.toString())
.build();
SmithyBuild builder = new SmithyBuild(config);
Expand All @@ -210,20 +212,32 @@ public void loadsImports() throws Exception {
.getTrait(SensitiveTrait.class).isPresent());
assertFalse(resultA.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(DocumentationTrait.class).isPresent());
assertTrue(resultA.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).isPresent());
assertThat(resultA.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).get().getValues().get(0), equalTo("multi-import"));

assertTrue(resultB.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(SensitiveTrait.class).isPresent());
assertTrue(resultB.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(DocumentationTrait.class).isPresent());
assertThat(resultB.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(DocumentationTrait.class).get().getValue(), equalTo("b.json"));
assertTrue(resultB.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).isPresent());
assertThat(resultB.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).get().getValues().get(0), equalTo("multi-import"));

assertTrue(resultC.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(SensitiveTrait.class).isPresent());
assertTrue(resultC.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(DocumentationTrait.class).isPresent());
assertThat(resultC.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(DocumentationTrait.class).get().getValue(), equalTo("c.json"));
assertTrue(resultC.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).isPresent());
assertThat(resultC.getShape(ShapeId.from("com.foo#String")).get()
.getTrait(TagsTrait.class).get().getValues().get(0), equalTo("multi-import"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"smithy": "1.0",
"shapes": {
"com.foo#String": {
"type": "apply",
"traits": {
"smithy.api#tags": ["multi-import"]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"version": "1.0",
"imports": ["d.json"]
}