forked from loafle/openapi-generator-original
1391 jel minimal overwrite option (#2451)
Option to overwrite only changed files
This commit is contained in:
parent
fef2970dab
commit
dc78405a68
@ -217,6 +217,11 @@ public class Generate implements Runnable {
|
||||
@Option(name = {"--generate-alias-as-model"}, title = "generate alias (array, map) as model", description = CodegenConstants.GENERATE_ALIAS_AS_MODEL_DESC)
|
||||
private Boolean generateAliasAsModel;
|
||||
|
||||
@Option(name = {"--minimal-update"},
|
||||
title = "Minimal update",
|
||||
description = "Only write output files that have changed.")
|
||||
private Boolean minimalUpdate;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (logToStderr != null) {
|
||||
@ -346,6 +351,9 @@ public class Generate implements Runnable {
|
||||
if (generateAliasAsModel != null) {
|
||||
configurator.setGenerateAliasAsModel(generateAliasAsModel);
|
||||
}
|
||||
if (minimalUpdate != null) {
|
||||
configurator.setEnableMinimalUpdate(minimalUpdate);
|
||||
}
|
||||
|
||||
applySystemPropertiesKvpList(systemProperties, configurator);
|
||||
applyInstantiationTypesKvpList(instantiationTypes, configurator);
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
package org.openapitools.codegen;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -28,23 +32,78 @@ import java.util.regex.Pattern;
|
||||
|
||||
public abstract class AbstractGenerator {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGenerator.class);
|
||||
|
||||
/**
|
||||
* Is the minimal-file-update option enabled?
|
||||
*
|
||||
* @return Option value
|
||||
*/
|
||||
public abstract boolean getEnableMinimalUpdate();
|
||||
|
||||
@SuppressWarnings("static-method")
|
||||
/**
|
||||
* Write String to a file, formatting as UTF-8
|
||||
*
|
||||
* @param filename The name of file to write
|
||||
* @param contents The contents string.
|
||||
* @return File representing the written file.
|
||||
* @throws IOException If file cannot be written.
|
||||
*/
|
||||
public File writeToFile(String filename, String contents) throws IOException {
|
||||
LOGGER.info("writing file " + filename);
|
||||
return writeToFile(filename, contents.getBytes(Charset.forName("UTF-8")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write bytes to a file
|
||||
*
|
||||
* @param filename The name of file to write
|
||||
* @param contents The contents bytes. Typically this is a UTF-8 formatted string.
|
||||
* @return File representing the written file.
|
||||
* @throws IOException If file cannot be written.
|
||||
*/
|
||||
@SuppressWarnings("static-method")
|
||||
public File writeToFile(String filename, byte contents[]) throws IOException {
|
||||
if (getEnableMinimalUpdate()) {
|
||||
String tempFilename = filename + ".tmp";
|
||||
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
|
||||
File outputFile = Paths.get(filename).toFile();
|
||||
File tempFile = null;
|
||||
try {
|
||||
tempFile = writeToFileRaw(tempFilename, contents);
|
||||
if (!filesEqual(tempFile, outputFile)) {
|
||||
LOGGER.info("writing file " + filename);
|
||||
Files.move(tempFile.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
tempFile = null;
|
||||
} else {
|
||||
LOGGER.info("skipping unchanged file " + filename);
|
||||
}
|
||||
} finally {
|
||||
if (tempFile != null && tempFile.exists()) {
|
||||
try {
|
||||
tempFile.delete();
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("Error removing temporary file " + tempFile, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputFile;
|
||||
} else {
|
||||
LOGGER.info("writing file " + filename);
|
||||
return writeToFileRaw(filename, contents);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filesEqual(File file1, File file2) throws IOException {
|
||||
return file1.exists() && file2.exists() && Arrays.equals(Files.readAllBytes(file1.toPath()), Files.readAllBytes(file2.toPath()));
|
||||
}
|
||||
|
||||
private File writeToFileRaw(String filename, byte[] contents) throws IOException {
|
||||
// Use Paths.get here to normalize path (for Windows file separator, space escaping on Linux/Mac, etc)
|
||||
File output = Paths.get(filename).toFile();
|
||||
|
||||
if (output.getParent() != null && !new File(output.getParent()).exists()) {
|
||||
File parent = new File(output.getParent());
|
||||
File parent = Paths.get(output.getParent()).toFile();
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
try (Writer out = new BufferedWriter(new OutputStreamWriter(
|
||||
new FileOutputStream(output), "UTF-8"))) {
|
||||
out.write(contents);
|
||||
}
|
||||
Files.write(output.toPath(), contents);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -260,4 +260,8 @@ public interface CodegenConfig {
|
||||
*/
|
||||
void setOpenAPI(OpenAPI openAPI);
|
||||
|
||||
public boolean isEnableMinimalUpdate();
|
||||
|
||||
public void setEnableMinimalUpdate(boolean isEnableMinimalUpdate);
|
||||
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
protected String ignoreFilePathOverride;
|
||||
// flag to indicate whether to use environment variable to post process file
|
||||
protected boolean enablePostProcessFile = false;
|
||||
// flag to indicate whether to only update files whose contents have changed
|
||||
protected boolean enableMinimalUpdate = false;
|
||||
|
||||
// make openapi available to all methods
|
||||
protected OpenAPI openAPI;
|
||||
@ -4834,4 +4836,22 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
this.enablePostProcessFile = enablePostProcessFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the boolean value indicating the state of the option for updating only changed files
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnableMinimalUpdate() {
|
||||
return enableMinimalUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the boolean value indicating the state of the option for updating only changed files
|
||||
*
|
||||
* @param enableMinimalUpdate true to enable minimal update
|
||||
*/
|
||||
@Override
|
||||
public void setEnableMinimalUpdate(boolean enableMinimalUpdate) {
|
||||
this.enableMinimalUpdate = enableMinimalUpdate;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,6 +67,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
private String contextPath;
|
||||
private Map<String, String> generatorPropertyDefaults = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean getEnableMinimalUpdate() {
|
||||
return config.isEnableMinimalUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Generator opts(ClientOptInput opts) {
|
||||
this.opts = opts;
|
||||
@ -797,16 +802,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
|
||||
}
|
||||
|
||||
protected File writeInputStreamToFile(String filename, InputStream in, String templateFile) throws FileNotFoundException, IOException {
|
||||
File outputFile = java.nio.file.Paths.get(filename).toFile();
|
||||
if (in != null) {
|
||||
OutputStream out = new FileOutputStream(outputFile, false);
|
||||
LOGGER.info("writing file " + outputFile);
|
||||
IOUtils.copy(in, out);
|
||||
out.close();
|
||||
byte bytes[] = IOUtils.toByteArray(in);
|
||||
return writeToFile(filename, bytes);
|
||||
} else {
|
||||
LOGGER.error("can't open '" + templateFile + "' for input; cannot write '" + filename + "'");
|
||||
return null;
|
||||
}
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildSupportFileBundle(List<Object> allOperations, List<Object> allModels) {
|
||||
|
@ -101,6 +101,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
private boolean logToStderr;
|
||||
private boolean validateSpec;
|
||||
private boolean enablePostProcessFile;
|
||||
private boolean enableMinimalUpdate;
|
||||
private String templateDir;
|
||||
private String auth;
|
||||
private String apiPackage;
|
||||
@ -239,6 +240,15 @@ public class CodegenConfigurator implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean getEnableMinimalUpdate() {
|
||||
return enableMinimalUpdate;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setEnableMinimalUpdate(boolean enableMinimalUpdate) {
|
||||
this.enableMinimalUpdate = enableMinimalUpdate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isGenerateAliasAsModel() {
|
||||
return ModelUtils.isGenerateAliasAsModel();
|
||||
}
|
||||
@ -545,6 +555,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
config.setIgnoreFilePathOverride(ignoreFileOverride);
|
||||
config.setRemoveOperationIdPrefix(removeOperationIdPrefix);
|
||||
config.setEnablePostProcessFile(enablePostProcessFile);
|
||||
config.setEnableMinimalUpdate(enableMinimalUpdate);
|
||||
|
||||
config.instantiationTypes().putAll(instantiationTypes);
|
||||
config.typeMapping().putAll(typeMappings);
|
||||
|
@ -9,11 +9,15 @@ import io.swagger.v3.oas.models.media.StringSchema;
|
||||
import io.swagger.v3.oas.models.parameters.QueryParameter;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.models.responses.ApiResponses;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class DefaultGeneratorTest {
|
||||
|
||||
@ -46,4 +50,32 @@ public class DefaultGeneratorTest {
|
||||
Assert.assertEquals(defaultList.get(3).path, "/path4");
|
||||
Assert.assertEquals(defaultList.get(3).allParams.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalUpdateTest() throws IOException {
|
||||
OpenAPI openAPI = TestUtils.createOpenAPI();
|
||||
ClientOptInput opts = new ClientOptInput();
|
||||
opts.setOpenAPI(openAPI);
|
||||
DefaultCodegen codegen = new DefaultCodegen();
|
||||
codegen.setEnableMinimalUpdate(true);
|
||||
opts.setConfig(codegen);
|
||||
opts.setOpts(new ClientOpts());
|
||||
DefaultGenerator generator = new DefaultGenerator();
|
||||
generator.opts(opts);
|
||||
File testPath = new File("temp/overwrite.test");
|
||||
if (testPath.exists()) {
|
||||
testPath.delete();
|
||||
}
|
||||
generator.writeToFile(testPath.toString(), "some file contents");
|
||||
long createTime = testPath.lastModified();
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
generator.writeToFile(testPath.toString(), "some file contents");
|
||||
Assert.assertEquals(createTime, testPath.lastModified());
|
||||
File testPathTmp = new File("temp/overwrite.test.tmp");
|
||||
Assert.assertFalse(testPathTmp.exists());
|
||||
testPath.delete();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user