From 31af28ee6a4499d6bf739803577f59d3d8d964ab Mon Sep 17 00:00:00 2001 From: aserkes Date: Tue, 3 Jan 2023 16:40:41 +0100 Subject: [PATCH] add --props-file option Signed-off-by: aserkes --- .../engine/v2/context/ContextPrinter.java | 4 +- .../engine/v2/context/ContextSerializer.java | 118 ++++++++++++++++++ .../v2/context/ContextSerializerTest.java | 62 +++++++++ .../build/cli/harness/CommandParser.java | 15 ++- .../build/cli/harness/GlobalOptions.java | 33 ++++- .../build/cli/harness/UsageCommand.java | 4 +- .../build/cli/harness/CommandParserTest.java | 33 ++++- .../helidon/build/cli/harness/cli-usage.txt | 2 + .../build/cli/harness/help-cmd-help.txt | 2 + .../build/cli/harness/simple-cmd-help.txt | 2 + .../cli/harness/test-props-file.properties | 4 + cli/impl/etc/spotbugs/exclude.xml | 8 +- .../helidon/build/cli/impl/CommonOptions.java | 14 ++- .../helidon/build/cli/impl/InitCommand.java | 2 +- .../build/cli/impl/ArchetypeInvokerTest.java | 2 +- .../io/helidon/build/common/FileUtils.java | 20 ++- 16 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextSerializer.java create mode 100644 archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/context/ContextSerializerTest.java create mode 100644 cli/harness/src/test/resources/io/helidon/build/cli/harness/test-props-file.properties diff --git a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextPrinter.java b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextPrinter.java index 764ebb5cc..455ea46e8 100644 --- a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextPrinter.java +++ b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. + * Copyright (c) 2022, 2023 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. @@ -40,7 +40,7 @@ private static boolean isLastChild(ContextNode node) { } private static String printValue(ContextValue value) { - return value.value().unwrap() + " (" + value.kind() + ')'; + return value == null ? "null" : value.value().unwrap() + " (" + value.kind() + ')'; } @Override diff --git a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextSerializer.java b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextSerializer.java new file mode 100644 index 000000000..1221a9016 --- /dev/null +++ b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/context/ContextSerializer.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.build.archetype.engine.v2.context; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * Context serializer. + */ +public class ContextSerializer implements ContextEdge.Visitor { + + private static final Set DEFAULT_VALUE_KIND_FILTER = + Set.of(ContextValue.ValueKind.EXTERNAL, ContextValue.ValueKind.USER); + private static final Predicate DEFAULT_CONTEXT_FILTER = + edge -> + edge.value() != null + && !edge.node().visibility().equals(ContextScope.Visibility.UNSET) + && DEFAULT_VALUE_KIND_FILTER.contains(edge.value().kind()); + private static final Function DEFAULT_VALUE_MAPPER = value -> { + Set forRemoval = Set.of('[', ']'); + if (value == null || value.length() == 0) { + return value; + } + StringBuilder builder = new StringBuilder(value); + if (forRemoval.contains(builder.charAt(0))) { + builder.deleteCharAt(0); + } + if (builder.length() > 0 && forRemoval.contains(builder.charAt(builder.length() - 1))) { + builder.deleteCharAt(builder.length() - 1); + } + return builder.toString(); + }; + private static final String DEFAULT_VALUE_DELIMITER = ","; + + private final Map result; + private final Predicate filter; + private final CharSequence valueDelimiter; + private final Function valueMapper; + + private ContextSerializer(Map result, + Predicate filter, + Function valueMapper, + CharSequence valueDelimiter) { + this.result = result; + this.filter = filter; + this.valueMapper = valueMapper; + this.valueDelimiter = valueDelimiter; + } + + @Override + public void visit(ContextEdge edge) { + ContextNode node = edge.node(); + ContextNode parent = node.parent0(); + if (parent != null) { + String key = node.path(); + Set valueSet = edge.variations().stream() + .filter(filter) + .map(variation -> variation.value().unwrap().toString()) + .map(valueMapper) + .collect(Collectors.toSet()); + if (valueSet.size() > 0) { + result.put(key, String.join(valueDelimiter, valueSet)); + } + } + } + + /** + * Visit the given archetype context and return values from the context in form of a map where keys are paths of nodes and + * values are related values for these nodes. + * + * @param context context for processing + * @param filter filter for context values + * @param valueMapper mapper for the values of the nodes + * @param valueDelimiter delimiter for the values + * @return map where keys are paths of nodes and values are related values for these nodes + */ + public static Map serialize(Context context, + Predicate filter, + Function valueMapper, + CharSequence valueDelimiter) { + Map result = new HashMap<>(); + context.scope().visitEdges(new ContextSerializer(result, filter, valueMapper, valueDelimiter), false); + return result; + } + + /** + * Visit the given archetype context and return values from the context that were used by an user during the project + * generation in form of a map where keys are paths of nodes and values are related values for these nodes. + * + * @param context context for processing + * @return map where keys are paths of nodes and values are related values for these nodes + */ + public static Map serialize(Context context) { + Map result = new HashMap<>(); + context.scope() + .visitEdges(new ContextSerializer(result, DEFAULT_CONTEXT_FILTER, DEFAULT_VALUE_MAPPER, DEFAULT_VALUE_DELIMITER), + false); + return result; + } +} diff --git a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/context/ContextSerializerTest.java b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/context/ContextSerializerTest.java new file mode 100644 index 000000000..ccf789efa --- /dev/null +++ b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/context/ContextSerializerTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.helidon.build.archetype.engine.v2.context; + +import java.util.Map; +import java.util.function.Function; + +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.everyItem; +import static org.hamcrest.Matchers.isIn; + +/** + * Tests {@link ContextSerializer}. + */ +class ContextSerializerTest { + + @Test + public void testSerialize() { + Map expectedResult = Map.of( + "foo", "foo", + "foo1", "", + "foo2", "some_var_default", + "foo3", "bar1_value" + ); + Context context = Context.builder() + .externalDefaults(Map.of( + "some_var", "some_var_default", + "bar1", "bar1_default_value" + )) + .externalValues(Map.of( + "foo", "foo", + "bar", "${foo}", + "foo1", "${non_exist_var}", + "foo2", "${some_var}", + "bar1", "bar1_value", + "foo3", "${bar1}" + )) + .build(); + + Map result = ContextSerializer.serialize(context, + edge -> edge.node().path().startsWith("foo"), + Function.identity(), + ","); + + assertThat(result.entrySet(), everyItem(isIn(expectedResult.entrySet()))); + } +} diff --git a/cli/harness/src/main/java/io/helidon/build/cli/harness/CommandParser.java b/cli/harness/src/main/java/io/helidon/build/cli/harness/CommandParser.java index 9fc5f50d4..269f20693 100644 --- a/cli/harness/src/main/java/io/helidon/build/cli/harness/CommandParser.java +++ b/cli/harness/src/main/java/io/helidon/build/cli/harness/CommandParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2023 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. @@ -39,6 +39,8 @@ import io.helidon.build.cli.harness.CommandModel.KeyValueInfo; import io.helidon.build.cli.harness.CommandModel.KeyValuesInfo; import io.helidon.build.cli.harness.CommandParameters.ParameterInfo; +import io.helidon.build.common.FileUtils; +import io.helidon.build.common.RequirementFailure; /** * Command parser. @@ -242,7 +244,16 @@ private Resolver parseCommand(Map> parametersMap) { continue; } } - parsedParams.put(optionName, new KeyValueParam(optionName, it.next().trim())); + KeyValueParam keyValueParam = new KeyValueParam(optionName, it.next().trim()); + parsedParams.put(optionName, keyValueParam); + if (keyValueParam.name().equals(GlobalOptions.PROPS_FILE_OPTION_NAME)) { + try { + Properties props = FileUtils.loadProperties(keyValueParam.value); + props.forEach((key, value) -> properties.put(String.valueOf(key), String.valueOf(value))); + } catch (IOException e) { + throw new RequirementFailure(e.getMessage()); + } + } } else if (paramInfo instanceof KeyValuesInfo) { boolean required = ((KeyValuesInfo) paramInfo).required(); if (!it.hasNext()) { diff --git a/cli/harness/src/main/java/io/helidon/build/cli/harness/GlobalOptions.java b/cli/harness/src/main/java/io/helidon/build/cli/harness/GlobalOptions.java index 580a32d64..7c4d4843e 100644 --- a/cli/harness/src/main/java/io/helidon/build/cli/harness/GlobalOptions.java +++ b/cli/harness/src/main/java/io/helidon/build/cli/harness/GlobalOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2023 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. @@ -131,6 +131,37 @@ public class GlobalOptions { */ public static final String PLAIN_FLAG_ARGUMENT = "--" + PLAIN_FLAG_NAME; + /** + * The --args-file option name. + */ + public static final String ARGS_FILE_OPTION_NAME = "args-file"; + + /** + * The --args-file option description. + */ + public static final String ARGS_FILE_OPTION_DESCRIPTION = "Path to a file with arguments for Helidon CLI tool"; + + /** + * The --args-file option argument. + */ + public static final String ARGS_FILE_OPTION_ARGUMENT = "--" + ARGS_FILE_OPTION_NAME; + + /** + * The --props-file option name. + */ + public static final String PROPS_FILE_OPTION_NAME = "props-file"; + + /** + * The --props-file option description. + */ + public static final String PROPS_FILE_OPTION_DESCRIPTION = "Path to a properties file with user inputs for Helidon init " + + "command"; + + /** + * The --props-file option argument. + */ + public static final String PROPS_FILE_OPTION_ARGUMENT = "--" + PROPS_FILE_OPTION_NAME; + /** * Tests whether the given argument is a global flag. * diff --git a/cli/harness/src/main/java/io/helidon/build/cli/harness/UsageCommand.java b/cli/harness/src/main/java/io/helidon/build/cli/harness/UsageCommand.java index de63d545f..ecdc8db9a 100644 --- a/cli/harness/src/main/java/io/helidon/build/cli/harness/UsageCommand.java +++ b/cli/harness/src/main/java/io/helidon/build/cli/harness/UsageCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2023 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. @@ -53,6 +53,8 @@ private static Map createGlobalOptionsMap() { map.put(GlobalOptions.DEBUG_FLAG_ARGUMENT, GlobalOptions.DEBUG_FLAG_DESCRIPTION); map.put(GlobalOptions.ERROR_FLAG_ARGUMENT, GlobalOptions.ERROR_FLAG_DESCRIPTION); map.put(GlobalOptions.PLAIN_FLAG_ARGUMENT, GlobalOptions.PLAIN_FLAG_DESCRIPTION); + map.put(GlobalOptions.ARGS_FILE_OPTION_ARGUMENT, GlobalOptions.ARGS_FILE_OPTION_DESCRIPTION); + map.put(GlobalOptions.PROPS_FILE_OPTION_ARGUMENT, GlobalOptions.PROPS_FILE_OPTION_DESCRIPTION); return map; } diff --git a/cli/harness/src/test/java/io/helidon/build/cli/harness/CommandParserTest.java b/cli/harness/src/test/java/io/helidon/build/cli/harness/CommandParserTest.java index a35c26666..d405e0965 100644 --- a/cli/harness/src/test/java/io/helidon/build/cli/harness/CommandParserTest.java +++ b/cli/harness/src/test/java/io/helidon/build/cli/harness/CommandParserTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2023 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. @@ -20,11 +20,13 @@ import java.net.URISyntaxException; import java.nio.file.Paths; import java.util.Map; +import java.util.Objects; import java.util.Properties; import io.helidon.build.cli.harness.CommandModel.KeyValueInfo; import io.helidon.build.cli.harness.CommandModel.FlagInfo; import io.helidon.build.cli.harness.CommandParser.CommandParserException; +import io.helidon.build.common.RequirementFailure; import org.junit.jupiter.api.Test; @@ -305,4 +307,33 @@ public void testArgsFileOptionWithIncorrectFile() { ); assertThat(e.getMessage(), containsString("java.nio.file.NoSuchFileException: not_existing_file.txt")); } + + @Test + public void testPropsFileOptionWithExistingFile() { + String argsFilePath = Objects.requireNonNull(getClass().getResource("test-props-file.properties")).getPath(); + KeyValueInfo propsFileOption = new KeyValueInfo<>(String.class, "props-file", "properties file", null, false); + CommandParameters cmd = new CommandParameters(propsFileOption); + + CommandParser parser = CommandParser.create("command", "--props-file", argsFilePath); + CommandParser.Resolver resolver = parser.parseCommand(cmd); + + Properties properties = resolver.properties(); + assertThat(properties.get("security.atz"), is("abac")); + assertThat(properties.get("flavor"), is("mp")); + assertThat(properties.get("media"), is("json,multipart")); + } + + @Test + public void testPropsFileOptionWithIncorrectFile() { + KeyValueInfo propsFileOption = new KeyValueInfo<>(String.class, "props-file", "properties file", null, false); + CommandParameters cmd = new CommandParameters(propsFileOption); + + CommandParser parser = CommandParser.create("command", "--props-file", "not_existing_props_file.txt"); + + RequirementFailure e = assertThrows( + RequirementFailure.class, + () -> parser.parseCommand(cmd) + ); + assertThat(e.getMessage(), containsString("not_existing_props_file.txt (No such file or directory)")); + } } diff --git a/cli/harness/src/test/resources/io/helidon/build/cli/harness/cli-usage.txt b/cli/harness/src/test/resources/io/helidon/build/cli/harness/cli-usage.txt index be27d8763..a50451d1a 100644 --- a/cli/harness/src/test/resources/io/helidon/build/cli/harness/cli-usage.txt +++ b/cli/harness/src/test/resources/io/helidon/build/cli/harness/cli-usage.txt @@ -10,6 +10,8 @@ Options --debug Produce debug output --error Print error stack traces --plain Do not use color or styles in output + --args-file Path to a file with arguments for Helidon CLI tool + --props-file Path to a properties file with user inputs for Helidon init command Commands diff --git a/cli/harness/src/test/resources/io/helidon/build/cli/harness/help-cmd-help.txt b/cli/harness/src/test/resources/io/helidon/build/cli/harness/help-cmd-help.txt index 27ff079f9..87be22baa 100644 --- a/cli/harness/src/test/resources/io/helidon/build/cli/harness/help-cmd-help.txt +++ b/cli/harness/src/test/resources/io/helidon/build/cli/harness/help-cmd-help.txt @@ -10,3 +10,5 @@ Options --debug Produce debug output --error Print error stack traces --plain Do not use color or styles in output + --args-file Path to a file with arguments for Helidon CLI tool + --props-file Path to a properties file with user inputs for Helidon init command diff --git a/cli/harness/src/test/resources/io/helidon/build/cli/harness/simple-cmd-help.txt b/cli/harness/src/test/resources/io/helidon/build/cli/harness/simple-cmd-help.txt index 9f61400f7..0280dad14 100644 --- a/cli/harness/src/test/resources/io/helidon/build/cli/harness/simple-cmd-help.txt +++ b/cli/harness/src/test/resources/io/helidon/build/cli/harness/simple-cmd-help.txt @@ -10,5 +10,7 @@ Options --debug Produce debug output --error Print error stack traces --plain Do not use color or styles in output + --args-file Path to a file with arguments for Helidon CLI tool + --props-file Path to a properties file with user inputs for Helidon init command --foo Foo option --bar Bar option diff --git a/cli/harness/src/test/resources/io/helidon/build/cli/harness/test-props-file.properties b/cli/harness/src/test/resources/io/helidon/build/cli/harness/test-props-file.properties new file mode 100644 index 000000000..288332241 --- /dev/null +++ b/cli/harness/src/test/resources/io/helidon/build/cli/harness/test-props-file.properties @@ -0,0 +1,4 @@ +#test properties +flavor=mp +security.atz=abac +media=json,multipart diff --git a/cli/impl/etc/spotbugs/exclude.xml b/cli/impl/etc/spotbugs/exclude.xml index f1b61600c..84dcc9735 100644 --- a/cli/impl/etc/spotbugs/exclude.xml +++ b/cli/impl/etc/spotbugs/exclude.xml @@ -1,7 +1,7 @@ + + + + diff --git a/cli/impl/src/main/java/io/helidon/build/cli/impl/CommonOptions.java b/cli/impl/src/main/java/io/helidon/build/cli/impl/CommonOptions.java index 3c0167681..74b422216 100644 --- a/cli/impl/src/main/java/io/helidon/build/cli/impl/CommonOptions.java +++ b/cli/impl/src/main/java/io/helidon/build/cli/impl/CommonOptions.java @@ -42,6 +42,8 @@ import static io.helidon.build.cli.harness.GlobalOptions.ERROR_FLAG_NAME; import static io.helidon.build.cli.harness.GlobalOptions.PLAIN_FLAG_DESCRIPTION; import static io.helidon.build.cli.harness.GlobalOptions.PLAIN_FLAG_NAME; +import static io.helidon.build.cli.harness.GlobalOptions.PROPS_FILE_OPTION_DESCRIPTION; +import static io.helidon.build.cli.harness.GlobalOptions.PROPS_FILE_OPTION_NAME; import static io.helidon.build.cli.harness.GlobalOptions.VERBOSE_FLAG_DESCRIPTION; import static io.helidon.build.cli.harness.GlobalOptions.VERBOSE_FLAG_NAME; import static io.helidon.build.common.FileUtils.WORKING_DIR; @@ -70,6 +72,7 @@ final class CommonOptions { private final boolean resetCache; private final MavenVersion sinceCliVersion; private Metadata metadata; + private final String propsFile; @Creator CommonOptions(@Flag(name = VERBOSE_FLAG_NAME, description = VERBOSE_FLAG_DESCRIPTION, visible = false) boolean verbose, @@ -81,7 +84,10 @@ final class CommonOptions { @KeyValue(name = "url", description = "Metadata base URL", visible = false) String metadataUrl, @Flag(name = "reset", description = "Reset metadata cache", visible = false) boolean resetCache, @KeyValue(name = "since", description = "Check for updates since this version", - visible = false) String since) { + visible = false) String since, + @KeyValue(name = PROPS_FILE_OPTION_NAME, description = PROPS_FILE_OPTION_DESCRIPTION, + visible = false) String propsFile + ) { this.verbose = verbose || debug; this.debug = debug; this.error = error; @@ -91,6 +97,7 @@ final class CommonOptions { this.metadataUrl = Strings.isValid(metadataUrl) ? metadataUrl : Config.userConfig().updateUrl(); this.resetCache = resetCache || since != null; this.sinceCliVersion = toMavenVersion(since == null ? Config.buildVersion() : since); + this.propsFile = propsFile; } CommonOptions(Path projectDir, CommonOptions options) { @@ -104,6 +111,7 @@ final class CommonOptions { this.resetCache = false; // Don't do it again this.sinceCliVersion = options.sinceCliVersion; this.metadata = options.metadata; + this.propsFile = options.propsFile; } boolean verbose() { @@ -154,6 +162,10 @@ Metadata metadata() { return metadata; } + String propsFile() { + return propsFile; + } + void checkForUpdates(boolean quiet) { try { Optional cliUpdate = metadata().checkForCliUpdate(sinceCliVersion, quiet); diff --git a/cli/impl/src/main/java/io/helidon/build/cli/impl/InitCommand.java b/cli/impl/src/main/java/io/helidon/build/cli/impl/InitCommand.java index b9032ae4d..3fad3ebd1 100644 --- a/cli/impl/src/main/java/io/helidon/build/cli/impl/InitCommand.java +++ b/cli/impl/src/main/java/io/helidon/build/cli/impl/InitCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022 Oracle and/or its affiliates. + * Copyright (c) 2020, 2023 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. diff --git a/cli/impl/src/test/java/io/helidon/build/cli/impl/ArchetypeInvokerTest.java b/cli/impl/src/test/java/io/helidon/build/cli/impl/ArchetypeInvokerTest.java index c13624cb6..7dd44e224 100644 --- a/cli/impl/src/test/java/io/helidon/build/cli/impl/ArchetypeInvokerTest.java +++ b/cli/impl/src/test/java/io/helidon/build/cli/impl/ArchetypeInvokerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Oracle and/or its affiliates. + * Copyright (c) 2022F 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. diff --git a/common/common/src/main/java/io/helidon/build/common/FileUtils.java b/common/common/src/main/java/io/helidon/build/common/FileUtils.java index e8c0bb8ba..61ee12910 100644 --- a/common/common/src/main/java/io/helidon/build/common/FileUtils.java +++ b/common/common/src/main/java/io/helidon/build/common/FileUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. + * Copyright (c) 2019, 2023 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. @@ -16,7 +16,9 @@ package io.helidon.build.common; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.UncheckedIOException; import java.net.URI; import java.net.URISyntaxException; @@ -39,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Properties; import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -936,4 +939,19 @@ public static List readAllLines(URI fileUri) throws IOException, URISynt Path path = Paths.get(fileUri.getPath()); return Files.readAllLines(path); } + + /** + * Load content of the properties file. + * + * @param filePath path to file + * @return content of the properties file + * @throws IOException IOException + */ + public static Properties loadProperties(String filePath) throws IOException { + try (InputStream input = new FileInputStream(filePath)) { + Properties props = new Properties(); + props.load(input); + return props; + } + } }