diff --git a/initializr-docs/src/main/asciidoc/configuration-guide.adoc b/initializr-docs/src/main/asciidoc/configuration-guide.adoc index 5fe9adf6ab..31c4389203 100644 --- a/initializr-docs/src/main/asciidoc/configuration-guide.adoc +++ b/initializr-docs/src/main/asciidoc/configuration-guide.adoc @@ -189,6 +189,20 @@ requires you to add a certain plugin to the build, you can provide a `BuildCusto that adds the plugin and the customizer will be called according to the order specified on it. +Similarly, an `ApplicationPropertiesCustomizer` can be used to contribute properties to +the application configuration file of the generated project, that is +`application.properties` or `application.yaml` depending on the requested +`ConfigurationFileFormat`. Properties added directly to the `ApplicationProperties` +argument are written to the configuration file of the main source set and the default +profile. Properties for another source set or Spring profile can be added to the matching +`section`, and a `src/{sourceSet}/resources/application[-{profile}]` file is generated +for every section that contains properties, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/doc/generator/project/ProjectCustomizationExamples.java[tag=application-properties-customizer] +---- + [[initializr-generator-spring-requirements]] diff --git a/initializr-docs/src/main/java/io/spring/initializr/doc/generator/project/ProjectCustomizationExamples.java b/initializr-docs/src/main/java/io/spring/initializr/doc/generator/project/ProjectCustomizationExamples.java index 2cc739bb66..f0447f6946 100644 --- a/initializr-docs/src/main/java/io/spring/initializr/doc/generator/project/ProjectCustomizationExamples.java +++ b/initializr-docs/src/main/java/io/spring/initializr/doc/generator/project/ProjectCustomizationExamples.java @@ -16,12 +16,14 @@ package io.spring.initializr.doc.generator.project; +import io.spring.initializr.generator.buildsystem.SourceSet; import io.spring.initializr.generator.buildsystem.gradle.GradleBuild; import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem; import io.spring.initializr.generator.condition.ConditionalOnBuildSystem; import io.spring.initializr.generator.condition.ConditionalOnPackaging; import io.spring.initializr.generator.packaging.war.WarPackaging; import io.spring.initializr.generator.spring.build.BuildCustomizer; +import io.spring.initializr.generator.spring.properties.ApplicationPropertiesCustomizer; import org.springframework.context.annotation.Bean; @@ -41,4 +43,18 @@ public BuildCustomizer warPluginContributor() { } // end::war-plugin-contributor[] + // tag::application-properties-customizer[] + @Bean + public ApplicationPropertiesCustomizer applicationPropertiesContributor() { + return (properties) -> { + // src/main/resources/application.properties (or .yaml) + properties.add("spring.application.name", "acme"); + // src/test/resources/application.properties + properties.section(SourceSet.TEST).add("spring.datasource.url", "jdbc:h2:mem:acme"); + // src/main/resources/application-dev.properties + properties.section(SourceSet.MAIN, "dev").add("logging.level.root", "DEBUG"); + }; + } + // end::application-properties-customizer[] + } diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/AbstractApplicationPropertiesContributor.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/AbstractApplicationPropertiesContributor.java new file mode 100644 index 0000000000..3fb65ff808 --- /dev/null +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/AbstractApplicationPropertiesContributor.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012 - present the original author or authors. + * + * 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 + * + * https://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.spring.initializr.generator.spring.properties; + +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Map; + +import io.spring.initializr.generator.buildsystem.SourceSet; +import io.spring.initializr.generator.project.contributor.ProjectContributor; +import io.spring.initializr.generator.spring.properties.ApplicationProperties.SectionKey; +import org.jspecify.annotations.Nullable; + +/** + * Base {@link ProjectContributor} that contributes application configuration files to a + * project. A file is written per source set and Spring profile that has properties, + * following the {@code src/{sourceSet}/resources/application[-{profile}]} convention. The + * file for the main source set and the default profile is always written, even if it is + * empty. + * + * @author Denis A. AltoƩ Falqueto + * @see ApplicationProperties#section(SourceSet, String) + */ +public abstract class AbstractApplicationPropertiesContributor implements ProjectContributor { + + private final ApplicationProperties properties; + + private final String extension; + + protected AbstractApplicationPropertiesContributor(ApplicationProperties properties, String extension) { + this.properties = properties; + this.extension = extension; + } + + @Override + public void contribute(Path projectRoot) throws IOException { + writeSection(projectRoot, SourceSet.MAIN, null, this.properties); + for (Map.Entry entry : this.properties.getSections().entrySet()) { + ApplicationProperties section = entry.getValue(); + if (!section.isEmpty()) { + writeSection(projectRoot, entry.getKey().sourceSet(), entry.getKey().profile(), section); + } + } + } + + /** + * Writes the given properties using the given writer. + * @param properties the properties to write + * @param writer the writer to use + */ + protected abstract void write(ApplicationProperties properties, PrintWriter writer); + + private void writeSection(Path projectRoot, SourceSet sourceSet, @Nullable String profile, + ApplicationProperties properties) throws IOException { + Path output = projectRoot.resolve(resolveFileName(sourceSet, profile)); + if (!Files.exists(output)) { + Files.createDirectories(output.getParent()); + Files.createFile(output); + } + try (PrintWriter writer = new PrintWriter(Files.newOutputStream(output, StandardOpenOption.APPEND), false, + StandardCharsets.UTF_8)) { + write(properties, writer); + } + } + + private String resolveFileName(SourceSet sourceSet, @Nullable String profile) { + String profileSuffix = (profile != null) ? "-" + profile : ""; + return "src/%s/resources/application%s.%s".formatted(sourceSet.getDirectoryName(), profileSuffix, + this.extension); + } + +} diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationProperties.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationProperties.java index 30d58f108b..e904ae9e26 100644 --- a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationProperties.java +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationProperties.java @@ -18,9 +18,12 @@ import java.io.PrintWriter; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import io.spring.initializr.generator.buildsystem.SourceSet; import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; @@ -28,6 +31,11 @@ /** * Application properties. + *

+ * Properties added directly to this instance belong to the main source set and the + * default profile, and are written to {@code src/main/resources}. Properties for another + * source set or Spring profile can be added to the {@link #section(SourceSet, String) + * matching section}. * * @author Moritz Halbritter * @author Rodrigo Mibielli Peixoto @@ -38,6 +46,57 @@ public class ApplicationProperties { private final Map properties = new HashMap<>(); + private final Map sections = new LinkedHashMap<>(); + + private final boolean root; + + /** + * Creates the application properties of the main source set and the default profile. + */ + public ApplicationProperties() { + this(true); + } + + private ApplicationProperties(boolean root) { + this.root = root; + } + + /** + * Returns the application properties for the given source set and profile, creating + * the section if necessary. Calling this method with {@link SourceSet#MAIN} and a + * {@code null} profile returns this instance. + * @param sourceSet the source set the properties belong to + * @param profile the Spring profile the properties belong to, or {@code null} for the + * default profile + * @return the application properties for the given source set and profile + * @throws IllegalStateException if called on a section rather than on the root + * application properties + */ + public ApplicationProperties section(SourceSet sourceSet, @Nullable String profile) { + Assert.notNull(sourceSet, "'sourceSet' must not be null"); + Assert.state(this.root, "Sections cannot be nested"); + if (profile != null) { + Assert.hasText(profile, "'profile' must not be empty"); + } + if (sourceSet == SourceSet.MAIN && profile == null) { + return this; + } + return this.sections.computeIfAbsent(new SectionKey(sourceSet, profile), + (key) -> new ApplicationProperties(false)); + } + + /** + * Returns the application properties for the given source set and the default + * profile, creating the section if necessary. + * @param sourceSet the source set the properties belong to + * @return the application properties for the given source set + * @throws IllegalStateException if called on a section rather than on the root + * application properties + */ + public ApplicationProperties section(SourceSet sourceSet) { + return section(sourceSet, null); + } + /** * Adds a new property. * @param key the key of the property @@ -198,4 +257,22 @@ private void add(String key, Object value) { this.properties.put(key, value); } + boolean isEmpty() { + return this.properties.isEmpty(); + } + + Map getSections() { + return Collections.unmodifiableMap(this.sections); + } + + /** + * The source set and profile a section of application properties belongs to. + * + * @param sourceSet the source set the properties belong to + * @param profile the Spring profile the properties belong to, or {@code null} for the + * default profile + */ + record SectionKey(SourceSet sourceSet, @Nullable String profile) { + } + } diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributor.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributor.java index e19a629438..57ef445855 100644 --- a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributor.java +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributor.java @@ -16,43 +16,26 @@ package io.spring.initializr.generator.spring.properties; -import java.io.IOException; import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import io.spring.initializr.generator.project.contributor.ProjectContributor; /** - * A {@link ProjectContributor} that contributes a {@code application.properties} file to - * a project. + * A {@link ProjectContributor} that contributes {@code application.properties} files to a + * project, one per source set and Spring profile that has properties. * * @author Stephane Nicoll * @author Moritz Halbritter */ -public class ApplicationPropertiesContributor implements ProjectContributor { - - private static final String FILE = "src/main/resources/application.properties"; - - private final ApplicationProperties properties; +public class ApplicationPropertiesContributor extends AbstractApplicationPropertiesContributor { public ApplicationPropertiesContributor(ApplicationProperties properties) { - this.properties = properties; + super(properties, "properties"); } @Override - public void contribute(Path projectRoot) throws IOException { - Path output = projectRoot.resolve(FILE); - if (!Files.exists(output)) { - Files.createDirectories(output.getParent()); - Files.createFile(output); - } - try (PrintWriter writer = new PrintWriter(Files.newOutputStream(output, StandardOpenOption.APPEND), false, - StandardCharsets.UTF_8)) { - this.properties.writeProperties(writer); - } + protected void write(ApplicationProperties properties, PrintWriter writer) { + properties.writeProperties(writer); } } diff --git a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationYamlPropertiesContributor.java b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationYamlPropertiesContributor.java index bfa40e8a26..73e57155f7 100644 --- a/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationYamlPropertiesContributor.java +++ b/initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationYamlPropertiesContributor.java @@ -16,42 +16,25 @@ package io.spring.initializr.generator.spring.properties; -import java.io.IOException; import java.io.PrintWriter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import io.spring.initializr.generator.project.contributor.ProjectContributor; /** - * A {@link ProjectContributor} that contributes a {@code application.yaml} file to a - * project. + * A {@link ProjectContributor} that contributes {@code application.yaml} files to a + * project, one per source set and Spring profile that has properties. * * @author Sijun Yang */ -public class ApplicationYamlPropertiesContributor implements ProjectContributor { - - private static final String FILE = "src/main/resources/application.yaml"; - - private final ApplicationProperties properties; +public class ApplicationYamlPropertiesContributor extends AbstractApplicationPropertiesContributor { public ApplicationYamlPropertiesContributor(ApplicationProperties properties) { - this.properties = properties; + super(properties, "yaml"); } @Override - public void contribute(Path projectRoot) throws IOException { - Path output = projectRoot.resolve(FILE); - if (!Files.exists(output)) { - Files.createDirectories(output.getParent()); - Files.createFile(output); - } - try (PrintWriter writer = new PrintWriter(Files.newOutputStream(output, StandardOpenOption.APPEND), false, - StandardCharsets.UTF_8)) { - this.properties.writeYaml(writer); - } + protected void write(ApplicationProperties properties, PrintWriter writer) { + properties.writeYaml(writer); } } diff --git a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesComplianceTests.java b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesComplianceTests.java index 47c1e2f8ce..d7a239ad58 100644 --- a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesComplianceTests.java +++ b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesComplianceTests.java @@ -19,6 +19,7 @@ import java.util.stream.Stream; import io.spring.initializr.generator.buildsystem.BuildSystem; +import io.spring.initializr.generator.buildsystem.SourceSet; import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem; import io.spring.initializr.generator.configuration.format.ConfigurationFileFormat; import io.spring.initializr.generator.configuration.format.properties.PropertiesFormat; @@ -27,6 +28,7 @@ import io.spring.initializr.generator.language.java.JavaLanguage; import io.spring.initializr.generator.spring.AbstractComplianceTests; import io.spring.initializr.generator.test.project.ProjectStructure; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -52,6 +54,15 @@ static Stream parameters() { Arguments.arguments(ConfigurationFileFormat.forId(YamlFormat.ID), "application.yaml")); } + static Stream sectionParameters() { + return parameters().flatMap((parameters) -> { + @Nullable Object[] arguments = parameters.get(); + return Stream.of(Arguments.arguments(arguments[0], arguments[1], SourceSet.TEST, null), + Arguments.arguments(arguments[0], arguments[1], SourceSet.MAIN, "dev"), + Arguments.arguments(arguments[0], arguments[1], SourceSet.TEST, "integration")); + }); + } + @ParameterizedTest @MethodSource("parameters") void applicationPropertiesGenerated(ConfigurationFileFormat format, String fileName) { @@ -74,8 +85,33 @@ void applicationPropertiesWithCustomProperties(ConfigurationFileFormat format, S .hasSameContentAs(new ClassPathResource(path)); } + @ParameterizedTest + @MethodSource("sectionParameters") + void applicationPropertiesWithSectionProperties(ConfigurationFileFormat format, String fileName, + SourceSet sourceSet, @Nullable String profile) { + ProjectStructure project = generateProject(java, maven, "2.4.1", + (description) -> description.setConfigurationFileFormat(format), + (projectGenerationContext) -> projectGenerationContext.registerBean( + ApplicationPropertiesCustomizer.class, + () -> (properties) -> properties.section(sourceSet, profile) + .add("spring.application.name", "app-name"))); + String path = "project/properties/" + format + "/" + getAssertFileName(fileName); + assertThat(project).textFile(getSectionFilePath(fileName, sourceSet, profile)) + .as("Resource " + path) + .hasSameContentAs(new ClassPathResource(path)); + assertThat(project).filePaths().contains("src/main/resources/%s".formatted(fileName)); + } + private String getAssertFileName(String fileName) { return fileName + ".gen"; } + private String getSectionFilePath(String fileName, SourceSet sourceSet, @Nullable String profile) { + int extensionSeparator = fileName.lastIndexOf('.'); + String sectionFileName = (profile != null) + ? fileName.substring(0, extensionSeparator) + "-" + profile + fileName.substring(extensionSeparator) + : fileName; + return "src/%s/resources/%s".formatted(sourceSet.getDirectoryName(), sectionFileName); + } + } diff --git a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributorTests.java b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributorTests.java index 97f02698de..e034999ce8 100644 --- a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributorTests.java +++ b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesContributorTests.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.nio.file.Path; +import io.spring.initializr.generator.buildsystem.SourceSet; import io.spring.initializr.generator.test.project.ProjectStructure; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -55,4 +56,55 @@ void shouldAddStringProperty() throws IOException { .contains("spring.application.name=test"); } + @Test + void shouldWriteTestSourceSetPropertiesToTestResources() throws IOException { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.TEST, null).add("spring.datasource.url", "jdbc:h2:mem:test"); + new ApplicationPropertiesContributor(properties).contribute(this.directory); + assertThat(new ProjectStructure(this.directory)).textFile("src/test/resources/application.properties") + .lines() + .contains("spring.datasource.url=jdbc:h2:mem:test"); + } + + @Test + void shouldWriteProfilePropertiesToProfileSpecificFile() throws IOException { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.MAIN, "dev").add("logging.level.root", "DEBUG"); + new ApplicationPropertiesContributor(properties).contribute(this.directory); + assertThat(new ProjectStructure(this.directory)).textFile("src/main/resources/application-dev.properties") + .lines() + .contains("logging.level.root=DEBUG"); + } + + @Test + void shouldWriteTestSourceSetProfileProperties() throws IOException { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.TEST, "integration").add("spring.application.name", "it"); + new ApplicationPropertiesContributor(properties).contribute(this.directory); + assertThat(new ProjectStructure(this.directory)) + .textFile("src/test/resources/application-integration.properties") + .lines() + .contains("spring.application.name=it"); + } + + @Test + void shouldNotWriteFileForEmptySection() throws IOException { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.TEST, null); + new ApplicationPropertiesContributor(properties).contribute(this.directory); + assertThat(new ProjectStructure(this.directory)).filePaths() + .containsOnly("src/main/resources/application.properties"); + } + + @Test + void shouldAlwaysWriteMainDefaultFileEvenWhenOnlySectionsHaveProperties() throws IOException { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.MAIN, "dev").add("test", "value"); + new ApplicationPropertiesContributor(properties).contribute(this.directory); + assertThat(new ProjectStructure(this.directory)).filePaths() + .containsOnly("src/main/resources/application.properties", "src/main/resources/application-dev.properties"); + assertThat(new ProjectStructure(this.directory)).textFile("src/main/resources/application.properties") + .isEmpty(); + } + } diff --git a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesTests.java b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesTests.java index 5b4e26c292..3a9b790f7f 100644 --- a/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesTests.java +++ b/initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesTests.java @@ -21,10 +21,12 @@ import java.util.Collections; import java.util.List; +import io.spring.initializr.generator.buildsystem.SourceSet; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; /** @@ -153,6 +155,51 @@ void booleanProperty() { assertThat(written).isEqualToIgnoringNewLines("test=false"); } + @Test + void sectionForMainSourceSetAndDefaultProfileReturnsRoot() { + ApplicationProperties properties = new ApplicationProperties(); + assertThat(properties.section(SourceSet.MAIN, null)).isSameAs(properties); + } + + @Test + void sectionReturnsSameInstanceForSameSourceSetAndProfile() { + ApplicationProperties properties = new ApplicationProperties(); + ApplicationProperties section = properties.section(SourceSet.TEST, "integration"); + assertThat(properties.section(SourceSet.TEST, "integration")).isSameAs(section); + } + + @Test + void sectionKeepsPropertiesIsolated() { + ApplicationProperties properties = new ApplicationProperties(); + properties.add("test", "main-value"); + properties.section(SourceSet.TEST).add("test", "test-value"); + assertThat(properties.get("test")).isEqualTo("main-value"); + assertThat(properties.section(SourceSet.TEST).get("test")).isEqualTo("test-value"); + } + + @Test + void sectionsWithSameSourceSetAndDifferentProfilesAreIsolated() { + ApplicationProperties properties = new ApplicationProperties(); + properties.section(SourceSet.MAIN, "dev").add("test", "dev-value"); + properties.section(SourceSet.MAIN, "prod").add("test", "prod-value"); + assertThat(properties.section(SourceSet.MAIN, "dev").get("test")).isEqualTo("dev-value"); + assertThat(properties.section(SourceSet.MAIN, "prod").get("test")).isEqualTo("prod-value"); + } + + @Test + void sectionOfSectionThrows() { + ApplicationProperties properties = new ApplicationProperties(); + ApplicationProperties section = properties.section(SourceSet.TEST, null); + assertThatIllegalStateException().isThrownBy(() -> section.section(SourceSet.MAIN, "dev")) + .withMessage("Sections cannot be nested"); + } + + @Test + void sectionWithEmptyProfileThrows() { + ApplicationProperties properties = new ApplicationProperties(); + assertThatIllegalArgumentException().isThrownBy(() -> properties.section(SourceSet.MAIN, " ")); + } + @Test void shouldFailOnExistingProperty() { ApplicationProperties properties = new ApplicationProperties(); diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/SourceSet.java b/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/SourceSet.java new file mode 100644 index 0000000000..fce8efb9a4 --- /dev/null +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/SourceSet.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012 - present the original author or authors. + * + * 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 + * + * https://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.spring.initializr.generator.buildsystem; + +/** + * A source set of a generated project, following the standard directory layout of the + * supported build systems (for example {@code src/main} and {@code src/test}). + * + * @author Denis A. AltoƩ Falqueto + */ +public enum SourceSet { + + /** + * The main source set, packaged with the application. + */ + MAIN("main"), + + /** + * The test source set, only available to tests. + */ + TEST("test"); + + private final String directoryName; + + SourceSet(String directoryName) { + this.directoryName = directoryName; + } + + /** + * Returns the name of the directory of this source set, relative to {@code src}. + * @return the directory name + */ + public String getDirectoryName() { + return this.directoryName; + } + +}