diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 87f868510d5..443f5b52b48 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -321,6 +321,12 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "generateAliasAsModel", property = "openapi.generator.maven.plugin.generateAliasAsModel") private Boolean generateAliasAsModel; + /** + * Only write output files that have changed. + */ + @Parameter(name = "minimalUpdate", property = "openapi.generator.maven.plugin.minimalUpdate") + private Boolean minimalUpdate; + /** * A map of language-specific parameters as passed with the -c option to the command line */ @@ -698,6 +704,10 @@ public class CodeGenMojo extends AbstractMojo { configurator.setGenerateAliasAsModel(generateAliasAsModel); } + if (minimalUpdate != null) { + configurator.setEnableMinimalUpdate(minimalUpdate); + } + if (isNotEmpty(generatorName)) { configurator.setGeneratorName(generatorName); } else { diff --git a/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java b/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java index 37940366fd3..d08c88b8fac 100644 --- a/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java +++ b/modules/openapi-generator-maven-plugin/src/test/java/org/openapitools/codegen/plugin/CodeGenMojoTest.java @@ -38,6 +38,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Comparator; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -88,6 +89,17 @@ public class CodeGenMojoTest extends BaseTestCase { assertEquals("joda", configOptions.get("dateLibrary")); } + public void testMinimalUpdateConfiguration() throws Exception { + // GIVEN + CodeGenMojo mojo = loadMojo(newTempFolder(), "src/test/resources/minimal-update", null); + + // WHEN + mojo.execute(); + + // THEN + assertEquals(Boolean.TRUE, getVariableValueFromObject(mojo, "minimalUpdate")); + } + public void testHashGenerationFileContainsExecutionId() throws Exception { // GIVEN final Path tempDir = newTempFolder(); @@ -136,6 +148,50 @@ public class CodeGenMojoTest extends BaseTestCase { assertFalse("src directory should not have been regenerated", Files.exists(generatedDir.resolve("src"))); } + public void testMinimalUpdate() throws Exception { + //GIVEN + /* Set up the mojo */ + final Path tempDir = newTempFolder(); + final CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/minimal-update", null, "executionId"); + + /* Perform an initial generation */ + mojo.execute(); + + /* Collect last modified times of generated files */ + final Path generatedDir = tempDir.resolve("target/generated-sources/minimal-update"); + assertTrue("Generated directory should exist", Files.exists(generatedDir)); + + Map lastModifiedTimes = new HashMap<>(); + try (Stream files = Files.walk(generatedDir)) { + files + .filter(Files::isRegularFile) + .filter(path -> !path.getFileName().toString().endsWith(".sha256")) + .filter(path -> !path.getFileName().toString().equals("FILES")) + .forEach(file -> { + try { + lastModifiedTimes.put(file, Files.getLastModifiedTime(file).toMillis()); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } + assertTrue("Should have recorded last modified times for more than 3 files", lastModifiedTimes.size() > 3); + + // WHEN + /* Execute the mojo again */ + mojo.execute(); + + // THEN + /* Verify that file modification times haven't changed (files weren't touched) */ + for (Map.Entry entry : lastModifiedTimes.entrySet()) { + Path file = entry.getKey(); + Long originalTime = entry.getValue(); + Long currentTime = Files.getLastModifiedTime(file).toMillis(); + assertEquals("File " + file + " should not have been modified (minimal update should skip unchanged files)", + originalTime, currentTime); + } + } + /** * For a Pom file which refers to an input file which will be on the classpath, as opposed to a file path, * test that the generated source is regenerated when the hash has changed. @@ -242,7 +298,7 @@ public class CodeGenMojoTest extends BaseTestCase { final Path generatedDir = tempDir.resolve("target/generated-sources/issue-16489"); final Path hashFile = generatedDir.resolve(".openapi-generator/petstore.yaml-default.sha256"); final CodeGenMojo mojo = loadMojo(tempDir, "src/test/resources/issue-16489", null); - mojo.execute(); // Perform an initial generation + mojo.execute(); // Perform an initial generation var currentHash = Files.readString(hashFile); // read hash FileUtils.deleteDirectory(generatedDir.resolve("src").toFile()); // Remove the generated source Files.writeString( // change schema definition in external file diff --git a/modules/openapi-generator-maven-plugin/src/test/resources/minimal-update/pom.xml b/modules/openapi-generator-maven-plugin/src/test/resources/minimal-update/pom.xml new file mode 100644 index 00000000000..75f9dc3925f --- /dev/null +++ b/modules/openapi-generator-maven-plugin/src/test/resources/minimal-update/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + minimal.update.test + minimal-update-test + jar + 1.0.0-SNAPSHOT + OpenAPI Generator Minimal Update Test + https://openapi-generator.tech/ + + minimal-update-test + + + org.openapitools + openapi-generator-maven-plugin + + petstore-on-classpath.yaml + spring + ${basedir}/target/generated-sources/minimal-update + true + + true + + + + + executionId + generate-sources + + generate + + + + + + +