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

Archetype updates #712

Merged
merged 8 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from 7 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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,11 +18,12 @@
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
Expand Down Expand Up @@ -214,7 +215,7 @@ static boolean evaluateConditional(Conditional conditional, Map<String, String>
*
* @param outputDirectory output directory
*/
public void generate(File outputDirectory) {
public void generate(Path outputDirectory) {
try {
for (Entry<String, List<Transformation>> entry : templates.entrySet()) {
String resourcePath = entry.getKey().substring(1);
Expand All @@ -223,9 +224,9 @@ public void generate(File outputDirectory) {
throw new IllegalStateException(resourcePath + " not found");
}
Mustache m = mf.compile(new InputStreamReader(is), resourcePath);
File outputFile = new File(outputDirectory, transform(resourcePath, entry.getValue(), properties));
outputFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(outputFile)) {
Path outputFile = outputDirectory.resolve(transform(resourcePath, entry.getValue(), properties));
Files.createDirectories(outputFile.getParent());
try (Writer writer = Files.newBufferedWriter(outputFile)) {
m.execute(writer, properties).flush();
}
}
Expand All @@ -236,9 +237,9 @@ public void generate(File outputDirectory) {
if (is == null) {
throw new IllegalStateException(resourcePath + " not found");
}
File outputFile = new File(outputDirectory, transform(resourcePath, entry.getValue(), properties));
outputFile.getParentFile().mkdirs();
Files.copy(is, outputFile.toPath());
Path outputFile = outputDirectory.resolve(transform(resourcePath, entry.getValue(), properties));
Files.createDirectories(outputFile.getParent());
Files.copy(is, outputFile);
}
}
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ public static void main(String[] args) {
System.err.println(outputDir + " exists");
System.exit(1);
}
new ArchetypeEngine(loader, Maps.fromProperties(System.getProperties())).generate(outputDir);
new ArchetypeEngine(loader, Maps.fromProperties(System.getProperties())).generate(outputDir.toPath());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,6 +41,7 @@
import io.helidon.build.common.test.utils.TestFiles;
import org.junit.jupiter.api.Test;

import static io.helidon.build.common.Unchecked.unchecked;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
Expand Down Expand Up @@ -121,16 +122,14 @@ public void testGenerate() throws IOException {
properties.put("package", "com.example.myproject");
properties.put("maven", "true");
File targetDir = new File(new File("").getAbsolutePath(), "target");
File outputDir = new File(targetDir, "test-project");
Path outputDirPath = outputDir.toPath();
Path outputDirPath = targetDir.toPath().resolve("test-project");
if (Files.exists(outputDirPath)) {
Files.walk(outputDirPath)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
.forEach(unchecked(Files::delete));
}
assertThat(Files.exists(outputDirPath), is(false));
new ArchetypeEngine(targetDir(), properties).generate(outputDir);
new ArchetypeEngine(targetDir(), properties).generate(outputDirPath);
assertThat(Files.exists(outputDirPath), is(true));
assertThat(Files.walk(outputDirPath)
.filter(p -> !Files.isDirectory(p))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@
import io.helidon.build.archetype.engine.v2.ast.Location;
import io.helidon.build.archetype.engine.v2.ast.Method;
import io.helidon.build.archetype.engine.v2.ast.Node;
import io.helidon.build.archetype.engine.v2.ast.Node.BuilderInfo;
import io.helidon.build.archetype.engine.v2.ast.Preset;
import io.helidon.build.archetype.engine.v2.ast.Script;
import io.helidon.build.archetype.engine.v2.ast.Step;
import io.helidon.build.archetype.engine.v2.ast.Value;
import io.helidon.build.archetype.engine.v2.ast.Variable;
import io.helidon.build.archetype.v2.json.SimpleJSONParser.JSONReaderException;
import io.helidon.build.archetype.v2.json.SimpleJSONParser.KeyInfo;
import io.helidon.build.common.Maps;
Expand All @@ -66,6 +68,7 @@ public static Script deserialize(InputStream is) {
private enum State {
START,
PRESET,
VARIABLE,
INPUT,
EXPRESSIONS,
EXPRESSION,
Expand Down Expand Up @@ -111,7 +114,7 @@ private static final class ReaderImpl implements SimpleJSONParser.Reader {
private String qName;
private Map<String, Value> attrs;
private Context ctx;
private Location location;
private BuilderInfo info;
private Script.Builder scriptBuilder;

ReaderImpl(InputStream is) {
Expand Down Expand Up @@ -146,10 +149,11 @@ public KeyInfo keyInfo(String key) {
@Override
public void startElement(String qName, Map<String, JsonValue> attrs) {
this.qName = qName;
location = Location.of(path, parser.lineNumber(), parser.charNumber());
Location location = Location.of(path, parser.lineNumber(), parser.charNumber());
info = BuilderInfo.of(loader, path, location);
ctx = stack.peek();
if (ctx == null) {
scriptBuilder = Script.builder(loader, path);
scriptBuilder = Script.builder(info);
stack.push(new Context(State.START, scriptBuilder));
} else {
this.attrs = Maps.mapValue(attrs, JsonFactory::readValue);
Expand Down Expand Up @@ -205,6 +209,9 @@ void processElement() {
case PRESET:
processPreset();
break;
case VARIABLE:
processVariable();
break;
case INPUT:
processInput();
break;
Expand All @@ -215,13 +222,13 @@ void processElement() {
}

void processMethod() {
addChild(State.EXECUTABLE, Method.builder(loader, path, location)
addChild(State.EXECUTABLE, Method.builder(info)
.attribute("name", Value.create(qName)));
}

boolean processExec() {
if ("call".equals(qName)) {
addChild(ctx.state, Invocation.builder(loader, path, location, Invocation.Kind.CALL));
addChild(ctx.state, Invocation.builder(info, Invocation.Kind.CALL));
return true;
}
return false;
Expand Down Expand Up @@ -282,7 +289,7 @@ void processInput() {
throw new JSONReaderException(String.format(
"Invalid input block: %s. { element=%s }", kind, qName));
}
addChild(nextState, Input.builder(loader, path, location, kind));
addChild(nextState, Input.builder(info, kind));
}

void processPreset() {
Expand All @@ -293,10 +300,10 @@ void processPreset() {
case TEXT:
case ENUM:
case LIST:
builder = Preset.builder(loader, path, location, blockKind());
builder = Preset.builder(info, blockKind());
break;
case VALUE:
builder = Block.builder(loader, path, location, blockKind());
builder = Block.builder(info, blockKind());
break;
default:
throw new JSONReaderException(String.format(
Expand All @@ -306,6 +313,27 @@ void processPreset() {
addChild(ctx.state, builder);
}

void processVariable() {
Block.Builder builder;
Block.Kind kind = blockKind();
switch (kind) {
case BOOLEAN:
case TEXT:
case ENUM:
case LIST:
builder = Variable.builder(info, blockKind());
break;
case VALUE:
builder = Block.builder(info, blockKind());
break;
default:
throw new JSONReaderException(String.format(
"Invalid variable block: %s. { element=%s }", kind, qName));

}
addChild(ctx.state, builder);
}

void processBlock() {
State nextState = State.BLOCK;
Block.Builder builder = null;
Expand All @@ -319,22 +347,25 @@ void processBlock() {
break;
case METHOD:
nextState = State.EXECUTABLE;
builder = Method.builder(loader, path, location);
builder = Method.builder(info);
break;
case STEP:
nextState = State.EXECUTABLE;
builder = Step.builder(loader, path, location);
builder = Step.builder(info);
break;
case INPUTS:
nextState = State.INPUT;
break;
case VARIABLES:
nextState = State.VARIABLE;
break;
case PRESETS:
nextState = State.PRESET;
break;
default:
}
if (builder == null) {
builder = Block.builder(loader, path, location, kind);
builder = Block.builder(info, kind);
}
addChild(nextState, builder);
}
Expand All @@ -347,7 +378,7 @@ void addChild(State nextState, Node.Builder<? extends Node, ?> builder) {
if (expr == null) {
throw new IllegalStateException("Unresolved expression: " + ifExprId);
}
ctx.builder.addChild(Condition.builder(loader, path, location)
ctx.builder.addChild(Condition.builder(info)
.expression(expr)
.then(builder));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import io.helidon.build.archetype.engine.v2.ast.Expression;
import io.helidon.build.archetype.engine.v2.ast.Expression.Token;
import io.helidon.build.archetype.engine.v2.ast.Input;
import io.helidon.build.archetype.engine.v2.ast.Input.NamedInput;
import io.helidon.build.archetype.engine.v2.ast.Invocation;
import io.helidon.build.archetype.engine.v2.ast.Invocation.MethodInvocation;
import io.helidon.build.archetype.engine.v2.ast.Method;
Expand All @@ -47,6 +46,7 @@
import io.helidon.build.archetype.engine.v2.ast.Script;
import io.helidon.build.archetype.engine.v2.ast.Step;
import io.helidon.build.archetype.engine.v2.ast.Value;
import io.helidon.build.archetype.engine.v2.ast.Variable;
import io.helidon.build.archetype.engine.v2.util.ClientCompiler;

/**
Expand Down Expand Up @@ -219,6 +219,8 @@ public VisitResult visitBlock(Block block, Script script) {
default:
}
JsonObjectBuilder builder = blockBuilder(block);
String exprId = this.exprId;
this.exprId = null;
stack.push(new Context(builder, JsonFactory.createArrayBuilder(), exprId));
return block.accept(this, builder);
}
Expand Down Expand Up @@ -263,11 +265,18 @@ public VisitResult postVisitBlock(Block block, Script script) {
return VisitResult.CONTINUE;
}

private VisitResult visitNamed(Input.NamedInput input, JsonObjectBuilder builder) {
builder.add("name", input.name())
.add("global", input.isGlobal())
.add("optional", input.isOptional())
.add("default", JsonFactory.createValue(input.defaultValue()));
private VisitResult visitNamed(Input.DeclaredInput input, JsonObjectBuilder builder) {
builder.add("id", input.id());
if (input.isGlobal()) {
builder.add("global", true);
}
if (input.isOptional()) {
builder.add("optional", true);
}
Value defaultValue = input.defaultValue();
if (defaultValue != null && defaultValue != Value.NULL) {
builder.add("default", JsonFactory.createValue(defaultValue));
}
return VisitResult.CONTINUE;
}

Expand All @@ -278,9 +287,12 @@ private VisitResult visitOption(Input.Option option, JsonObjectBuilder builder)

@Override
public VisitResult visitInput(Input input, JsonObjectBuilder builder) {
builder.add("label", input.label());
if (input instanceof NamedInput) {
return visitNamed((NamedInput) input, builder);
builder.add("name", input.name());
if (input.description() != null) {
builder.add("description", input.description());
}
if (input instanceof Input.DeclaredInput) {
return visitNamed((Input.DeclaredInput) input, builder);
} else if (input instanceof Input.Option) {
return visitOption((Input.Option) input, builder);
}
Expand All @@ -294,9 +306,16 @@ public VisitResult visitPreset(Preset preset, JsonObjectBuilder builder) {
return VisitResult.SKIP_SUBTREE;
}

@Override
public VisitResult visitVariable(Variable variable, JsonObjectBuilder builder) {
builder.add("path", variable.path())
.add("value", JsonFactory.createValue(variable.value()));
return VisitResult.SKIP_SUBTREE;
}

@Override
public VisitResult visitStep(Step step, JsonObjectBuilder builder) {
builder.add("label", step.label())
builder.add("name", step.name())
.add("id", stepsIds.computeIfAbsent(step, this::stepId));
return VisitResult.CONTINUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void testDeserialize() throws IOException {
Script script = ScriptDeserializer.deserialize(Files.newInputStream(jsonFile));

JsonObject archetypeJson = ScriptSerializer.serialize(script);
System.out.println(JsonFactory.toPrettyString(archetypeJson));
assertThat(jsonDiff(archetypeJson, readJson(expected)), is(EMPTY_JSON_ARRAY));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ void testFiltering() throws IOException {
FileSystem fs = VirtualFileSystem.create(sourceDir);

JsonObject archetypeJson = ScriptSerializer.serialize(fs);
System.out.println(JsonFactory.toPrettyString(archetypeJson));
assertThat(jsonDiff(archetypeJson, readJson(expected)), is(EMPTY_JSON_ARRAY));
}

Expand Down
Loading