Search in sources :

Example 1 with Input

use of io.helidon.build.archetype.engine.v2.ast.Input in project helidon-build-tools by oracle.

the class InputResolver method onVisitInput.

/**
 * Invoked for every named input visit.
 *
 * @param input   input
 * @param scope   scope
 * @param context context
 * @return visit result if a value already exists, {@code null} otherwise
 */
protected VisitResult onVisitInput(DeclaredInput input, Context.Scope scope, Context context) {
    Step currentStep = currentSteps.peek();
    if (currentStep == null) {
        throw new IllegalStateException(input.location() + " Input not nested inside a step");
    }
    boolean global = input.isGlobal();
    if (global) {
        DeclaredInput parent = parents.peek();
        if (parent != null && !parent.isGlobal()) {
            throw new IllegalStateException(input.location() + " Parent input is not global");
        }
    }
    parents.push(input);
    Value value = context.getValue(scope.id());
    if (value == null) {
        if (!visitedSteps.contains(currentStep)) {
            visitedSteps.add(currentStep);
            onVisitStep(currentStep, context);
        }
        return null;
    }
    input.validate(value, scope.id());
    return input.visitValue(value);
}
Also used : DeclaredInput(io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput) Value(io.helidon.build.archetype.engine.v2.ast.Value) Step(io.helidon.build.archetype.engine.v2.ast.Step)

Example 2 with Input

use of io.helidon.build.archetype.engine.v2.ast.Input in project helidon-build-tools by oracle.

the class TerminalInputResolver method visitBoolean.

@Override
public VisitResult visitBoolean(Input.Boolean input, Context context) {
    Context.Scope scope = context.newScope(input.id(), input.isGlobal());
    VisitResult result = onVisitInput(input, scope, context);
    while (result == null) {
        try {
            Value defaultValue = defaultValue(input, context);
            String defaultText = defaultValue != null ? BoldBlue.apply(Input.Boolean.asString(defaultValue)) : null;
            String question = String.format("%s (yes/no)", Bold.apply(input.name()));
            String response = prompt(question, defaultText);
            if (response == null || response.trim().length() == 0) {
                context.setValue(scope.id(), defaultValue, ContextValue.ValueKind.DEFAULT);
                if (defaultValue == null || !defaultValue.asBoolean()) {
                    result = VisitResult.SKIP_SUBTREE;
                } else {
                    result = VisitResult.CONTINUE;
                }
                break;
            }
            boolean value;
            try {
                value = Input.Boolean.valueOf(response, true);
            } catch (Exception e) {
                System.out.println(BoldRed.apply("Invalid response: " + response));
                if (LogLevel.isDebug()) {
                    Log.debug(e.getMessage());
                }
                continue;
            }
            context.setValue(scope.id(), Value.create(value), ContextValue.ValueKind.USER);
            if (!value) {
                result = VisitResult.SKIP_SUBTREE;
            } else {
                result = VisitResult.CONTINUE;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    context.pushScope(scope);
    return result;
}
Also used : Value(io.helidon.build.archetype.engine.v2.ast.Value) VisitResult(io.helidon.build.archetype.engine.v2.ast.Node.VisitResult) IOException(java.io.IOException) IOException(java.io.IOException)

Example 3 with Input

use of io.helidon.build.archetype.engine.v2.ast.Input in project helidon-build-tools by oracle.

the class ArchetypeEngineV2 method generate.

/**
 * Generate a project.
 *
 * @param inputResolver     input resolver
 * @param externalValues    external values
 * @param externalDefaults  external defaults
 * @param onResolved        callback executed when inputs are fully resolved
 * @param directorySupplier output directory supplier
 * @return output directory
 */
public Path generate(InputResolver inputResolver, Map<String, String> externalValues, Map<String, String> externalDefaults, Runnable onResolved, Function<String, Path> directorySupplier) {
    Context context = Context.create(cwd, externalValues, externalDefaults);
    Script script = ScriptLoader.load(cwd.resolve(ENTRYPOINT));
    // resolve inputs (full traversal)
    Controller.walk(inputResolver, script, context);
    if (context.peekScope() != Context.Scope.ROOT) {
        throw new IllegalStateException("Invalid scope");
    }
    onResolved.run();
    // resolve output directory
    String artifactId = requireNonNull(context.lookup(ARTIFACT_ID), ARTIFACT_ID + " is null").asString();
    Path directory = directorySupplier.apply(artifactId);
    // resolve model  (full traversal)
    MergedModel model = MergedModel.resolveModel(script, context);
    // generate output  (full traversal)
    OutputGenerator outputGenerator = new OutputGenerator(model, directory);
    Controller.walk(outputGenerator, script, context);
    if (context.peekScope() != Context.Scope.ROOT) {
        throw new IllegalStateException("Invalid scope");
    }
    return directory;
}
Also used : Path(java.nio.file.Path) Script(io.helidon.build.archetype.engine.v2.ast.Script)

Example 4 with Input

use of io.helidon.build.archetype.engine.v2.ast.Input in project helidon-build-tools by oracle.

the class Context method defaultValue.

/**
 * Get an external default value.
 *
 * @param id     input id
 * @param global global
 * @return value
 */
public Value defaultValue(String id, boolean global) {
    Value defaultValue = defaults.get(path(id, global));
    String wrapped = defaultValue != null ? defaultValue.asString() : null;
    if (wrapped != null) {
        defaultValue = Value.create(substituteVariables(wrapped));
    }
    return defaultValue;
}
Also used : Value(io.helidon.build.archetype.engine.v2.ast.Value)

Example 5 with Input

use of io.helidon.build.archetype.engine.v2.ast.Input in project helidon-build-tools by oracle.

the class ScriptLoaderTest method testNestedInputs.

@Test
void testNestedInputs() {
    Script script = load("loader/nested-inputs.xml");
    int[] index = new int[] { 0 };
    walk(new Input.Visitor<>() {

        @Override
        public VisitResult visitBoolean(Input.Boolean input, Void arg) {
            assertThat(++index[0] <= 5, is(true));
            assertThat(input.id(), is("input" + index[0]));
            assertThat(input.name(), is("label" + index[0]));
            return VisitResult.CONTINUE;
        }
    }, script);
    assertThat(index[0], is(5));
}
Also used : Script(io.helidon.build.archetype.engine.v2.ast.Script) Input(io.helidon.build.archetype.engine.v2.ast.Input) VisitResult(io.helidon.build.archetype.engine.v2.ast.Node.VisitResult) Test(org.junit.jupiter.api.Test)

Aggregations

Test (org.junit.jupiter.api.Test)31 Block (io.helidon.build.archetype.engine.v2.ast.Block)17 VisitResult (io.helidon.build.archetype.engine.v2.ast.Node.VisitResult)15 PresetNode (io.helidon.build.archetype.engine.v2.util.InputTree.PresetNode)14 Input (io.helidon.build.archetype.engine.v2.ast.Input)13 Node (io.helidon.build.archetype.engine.v2.util.InputTree.Node)13 ValueNode (io.helidon.build.archetype.engine.v2.util.InputTree.ValueNode)13 Script (io.helidon.build.archetype.engine.v2.ast.Script)11 Step (io.helidon.build.archetype.engine.v2.ast.Step)9 Value (io.helidon.build.archetype.engine.v2.ast.Value)9 Node (io.helidon.build.archetype.engine.v2.ast.Node)7 LinkedHashMap (java.util.LinkedHashMap)7 NodeIndex (io.helidon.build.archetype.engine.v2.util.InputTree.NodeIndex)6 IOException (java.io.IOException)4 DeclaredInput (io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput)3 List (java.util.List)3 Matchers.nullValue (org.hamcrest.Matchers.nullValue)3 InvocationException (io.helidon.build.archetype.engine.v2.InvocationException)2 Preset (io.helidon.build.archetype.engine.v2.ast.Preset)2 Path (java.nio.file.Path)2