Skip to content

Commit

Permalink
feat(avro)/refactor(core): unify *_POST_PROCESS_FILE behaviour and …
Browse files Browse the repository at this point in the history
…reuse code (#19761)

* feat(avro)/refactor: unify `*_POST_PROCESS_FILE` bahviour and code

* refactor: use existing function

* test: add simple test for post processor execution

* test: restrict concurrency to 1

* docs: add explanation to method
  • Loading branch information
joscha authored Oct 5, 2024
1 parent 98468ab commit 899ddec
Show file tree
Hide file tree
Showing 37 changed files with 219 additions and 484 deletions.
1 change: 1 addition & 0 deletions docs/file-post-processing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Also refer to the relevant documentation for [CLI](./usage.md), [Maven Plugin](h
The following environment variables are supported by their respective generators:
<!-- query with: grep -Rn '_POST_PROCESS_FILE"' modules | grep -Eo '[^"]+_POST_PROCESS_FILE' | sort -u -->

* `AVRO_POST_PROCESS_FILE`
* `CPP_POST_PROCESS_FILE`
* `CSHARP_POST_PROCESS_FILE`
* `C_POST_PROCESS_FILE`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentSkipListSet;
Expand Down Expand Up @@ -8088,6 +8092,43 @@ public void postProcessFile(File file, String fileType) {
LOGGER.debug("Post processing file {} ({})", file, fileType);
}

/**
* Executes an external command for file post processing.
*
* @param commandArr an array of commands and arguments. They will be concatenated with space and tokenized again.
* @return Whether the execution passed (true) or failed (false)
*/
protected boolean executePostProcessor(String[] commandArr) {
final String command = String.join(" ", commandArr);
try {
// we don't use the array variant here, because the command passed in by the user is often not only a single binary
// but a combination of binary + parameters, e.g. `/etc/bin prettier -w`, which would then not be found, as the
// first array item would be expected to be the binary only. The exec method is tokenizing the command for us.
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) {
try (InputStreamReader inputStreamReader = new InputStreamReader(p.getErrorStream(), StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(inputStreamReader)) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
LOGGER.error("Error running the command ({}). Exit value: {}, Error output: {}", command, exitValue, sb);
}
} else {
LOGGER.info("Successfully executed: {}", command);
return true;
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
return false;
}

/**
* Boolean value indicating the state of the option for post-processing file using environment variables.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.*;

import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
Expand Down Expand Up @@ -1065,20 +1064,8 @@ public void postProcessFile(File file, String fileType) {
if (StringUtils.isEmpty(commandPrefix)) {
commandPrefix = "gnatpp";
}

try {
Process p = Runtime.getRuntime().exec(new String[]{commandPrefix, "--no-compact", "--quiet", file.toString()});
int exitValue = p.waitFor();
if (exitValue != 0) {
LOGGER.error("Error running the command ({} {}). Exit code: {}", commandPrefix, file, exitValue);
} else {
LOGGER.debug("Successfully executed: {} {}", commandPrefix, file);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({} {}). Exception: {}", commandPrefix, file, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
String[] commandArr = new String[]{commandPrefix, "--no-compact", "--quiet", file.toString()};
this.executePostProcessor(commandArr);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ public void processOpts() {
if (StringUtils.isEmpty(System.getenv("CSHARP_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable CSHARP_POST_PROCESS_FILE not defined so the C# code may not be properly formatted by uncrustify (0.66 or later) or other code formatter. To define it, try `export CSHARP_POST_PROCESS_FILE=\"/usr/local/bin/uncrustify --no-backup\" && export UNCRUSTIFY_CONFIG=/path/to/uncrustify-rules.cfg` (Linux/Mac). Note: replace /path/to with the location of uncrustify-rules.cfg");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
} else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'CSHARP_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}

// License info
Expand Down Expand Up @@ -1879,6 +1881,7 @@ public void setParameterExampleValue(CodegenParameter p) {

@Override
public void postProcessFile(File file, String fileType) {
super.postProcessFile(file, fileType);
if (file == null) {
return;
}
Expand All @@ -1890,20 +1893,7 @@ public void postProcessFile(File file, String fileType) {

// only process files with .cs extension
if ("cs".equals(FilenameUtils.getExtension(file.toString()))) {
String command = csharpPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit code: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {csharpPostProcessFile, file.toString()});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -315,6 +314,8 @@ public void processOpts() {
if (StringUtils.isEmpty(System.getenv("CPP_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable CPP_POST_PROCESS_FILE not defined so the C++ code may not be properly formatted. To define it, try 'export CPP_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
} else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'CPP_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}

if (additionalProperties.containsKey(RESERVED_WORD_PREFIX_OPTION)) {
Expand All @@ -337,6 +338,7 @@ protected ImmutableMap.Builder<String, Lambda> addMustacheLambdas() {

@Override
public void postProcessFile(File file, String fileType) {
super.postProcessFile(file, fileType);
if (file == null) {
return;
}
Expand All @@ -346,21 +348,7 @@ public void postProcessFile(File file, String fileType) {
}
// only process files with cpp extension
if ("cpp".equals(FilenameUtils.getExtension(file.toString())) || "h".equals(FilenameUtils.getExtension(file.toString()))) {
String command = cppPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {cppPostProcessFile, file.toString()});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
Expand Down Expand Up @@ -229,6 +228,8 @@ public void processOpts() {
if (StringUtils.isEmpty(System.getenv("DART_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable DART_POST_PROCESS_FILE not defined so the Dart code may not be properly formatted. To define it, try `export DART_POST_PROCESS_FILE=\"/usr/local/bin/dartfmt -w\"` (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
} else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'DART_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}

if (additionalProperties.containsKey(PUB_NAME)) {
Expand Down Expand Up @@ -805,20 +806,7 @@ public void postProcessFile(File file, String fileType) {
// process all files with dart extension
if ("dart".equals(FilenameUtils.getExtension(file.toString()))) {
// currently supported is "dartfmt -w" and "dart format"
String command = dartPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit code: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {dartPostProcessFile, file.toString()});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.*;

import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
Expand Down Expand Up @@ -1039,6 +1038,7 @@ public void setParameterExampleValue(CodegenParameter codegenParameter) {

@Override
public void postProcessFile(File file, String fileType) {
super.postProcessFile(file, fileType);
if (file == null) {
return;
}
Expand All @@ -1050,20 +1050,7 @@ public void postProcessFile(File file, String fileType) {

// only process files with .fs extension
if ("fs".equals(FilenameUtils.getExtension(file.toString()))) {
String command = fsharpPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit code: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {fsharpPostProcessFile, file.toString()});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.*;

import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
Expand Down Expand Up @@ -173,6 +172,8 @@ public void processOpts() {
if (StringUtils.isEmpty(System.getenv("GO_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable GO_POST_PROCESS_FILE not defined so Go code may not be properly formatted. To define it, try `export GO_POST_PROCESS_FILE=\"/usr/local/bin/gofmt -w\"` (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
} else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'GO_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}
}

Expand Down Expand Up @@ -982,6 +983,7 @@ public String toDefaultValue(Schema schema) {

@Override
public void postProcessFile(File file, String fileType) {
super.postProcessFile(file, fileType);
if (file == null) {
return;
}
Expand All @@ -1007,20 +1009,7 @@ public void postProcessFile(File file, String fileType) {
if ("go".equals(FilenameUtils.getExtension(file.toString()))) {
// e.g. "gofmt -w yourcode.go"
// e.g. "go fmt path/to/your/package"
String command = goPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
int exitValue = p.waitFor();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit code: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {goPostProcessFile, file.toString()});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
Expand Down Expand Up @@ -409,6 +408,8 @@ public void processOpts() {
if (StringUtils.isEmpty(System.getenv("JAVA_POST_PROCESS_FILE"))) {
LOGGER.info("Environment variable JAVA_POST_PROCESS_FILE not defined so the Java code may not be properly formatted. To define it, try 'export JAVA_POST_PROCESS_FILE=\"/usr/local/bin/clang-format -i\"' (Linux/Mac)");
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
} else if (!this.isEnablePostProcessFile()) {
LOGGER.info("Warning: Environment variable 'JAVA_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
}

convertPropertyToBooleanAndWriteBack(BeanValidationFeatures.USE_BEANVALIDATION, this::setUseBeanValidation);
Expand Down Expand Up @@ -2226,6 +2227,7 @@ public String getterAndSetterCapitalize(String name) {

@Override
public void postProcessFile(File file, String fileType) {
super.postProcessFile(file, fileType);
if (file == null) {
return;
}
Expand All @@ -2237,21 +2239,7 @@ public void postProcessFile(File file, String fileType) {

// only process files with java extension
if ("java".equals(FilenameUtils.getExtension(file.toString()))) {
String command = javaPostProcessFile + " " + file;
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
int exitValue = p.exitValue();
if (exitValue != 0) {
LOGGER.error("Error running the command ({}). Exit value: {}", command, exitValue);
} else {
LOGGER.info("Successfully executed: {}", command);
}
} catch (InterruptedException | IOException e) {
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
// Restore interrupted state
Thread.currentThread().interrupt();
}
this.executePostProcessor(new String[] {javaPostProcessFile, file.toString()});
}
}

Expand Down
Loading

0 comments on commit 899ddec

Please sign in to comment.