Skip to content

Commit

Permalink
Resolve all imports relative to their config
Browse files Browse the repository at this point in the history
  • Loading branch information
JordonPhillips authored and kstich committed Jun 5, 2020
1 parent f1d6487 commit e0e53fe
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 40 deletions.
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"]
}

0 comments on commit e0e53fe

Please sign in to comment.