From c49259ca6a01da2149649cf2b73217d996ff8019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9da=20Housni=20Alaoui?= Date: Thu, 17 Sep 2026 22:42:34 +0200 Subject: [PATCH] Display the command formatting all the files when the validation fails --- .../code/format/ValidateCodeFormat.java | 24 ++++++++- .../code/format/maven/MavenDocumentation.java | 54 +++++++++++++++++++ .../code/format/AbstractMavenModuleTest.java | 10 ++++ .../cosium/code/format/MavenWrapperTest.java | 16 ++++++ 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/com/cosium/code/format/maven/MavenDocumentation.java diff --git a/core/src/main/java/com/cosium/code/format/ValidateCodeFormat.java b/core/src/main/java/com/cosium/code/format/ValidateCodeFormat.java index 841e266b..291c8bf9 100644 --- a/core/src/main/java/com/cosium/code/format/ValidateCodeFormat.java +++ b/core/src/main/java/com/cosium/code/format/ValidateCodeFormat.java @@ -1,27 +1,49 @@ package com.cosium.code.format; import com.cosium.code.format.formatter.CodeFormatters; +import com.cosium.code.format.maven.MavenDocumentation; import com.cosium.code.format_spi.CodeFormatter; import com.cosium.code.format_spi.FileExtension; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; /** * @author Réda Housni Alaoui */ @Mojo(name = "validate-code-format", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true) public class ValidateCodeFormat extends AbstractFormatMojo { + + @Parameter(readonly = true, defaultValue = "${plugin}") + private PluginDescriptor pluginDescriptor; + + @Parameter(readonly = true, defaultValue = "${session.executionRootDirectory}") + private String executionRootDirectory; + @Override protected void process(CodeFormatters codeFormatters, Path path) throws MojoFailureException { if (validate(codeFormatters, path)) { return; } - throw new MojoFailureException(path + " is not correctly formatted !"); + throw new MojoFailureException( + path + + " is not correctly formatted !" + + System.lineSeparator() + + "Run '" + + mavenDocumentation().createFormatCodeCommand() + + "' to format all the files."); + } + + private MavenDocumentation mavenDocumentation() { + return new MavenDocumentation( + this::getLog, pluginDescriptor, baseDir(), gitBaseDir(), Paths.get(executionRootDirectory)); } private boolean validate(CodeFormatters codeFormatters, Path path) { diff --git a/core/src/main/java/com/cosium/code/format/maven/MavenDocumentation.java b/core/src/main/java/com/cosium/code/format/maven/MavenDocumentation.java new file mode 100644 index 00000000..4fd415fb --- /dev/null +++ b/core/src/main/java/com/cosium/code/format/maven/MavenDocumentation.java @@ -0,0 +1,54 @@ +package com.cosium.code.format.maven; + +import static java.util.Objects.requireNonNull; + +import java.io.File; +import java.nio.file.Path; +import java.util.function.Supplier; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.logging.Log; + +/** + * @author Réda Housni Alaoui + */ +public class MavenDocumentation { + + private final MavenWrapperExecutables wrapperExecutables; + private final PluginDescriptor pluginDescriptor; + private final Path executionRootDirectory; + + public MavenDocumentation( + Supplier log, + PluginDescriptor pluginDescriptor, + Path baseDir, + Path gitBaseDir, + Path executionRootDirectory) { + this.wrapperExecutables = new MavenWrapperExecutables(log, baseDir, gitBaseDir); + this.pluginDescriptor = requireNonNull(pluginDescriptor); + this.executionRootDirectory = requireNonNull(executionRootDirectory); + } + + /** + * @return The command formatting all the files, to be run from the execution root directory + */ + public String createFormatCodeCommand() { + return "%s %s:format-code".formatted(createMavenCommand(), pluginDescriptor.getGoalPrefix()); + } + + private String createMavenCommand() { + return wrapperExecutables.stream(false) + .filter(MavenExecutable::isValid) + .findFirst() + .map(MavenExecutable::path) + .map(this::createWrapperCommand) + .orElse("mvn"); + } + + private String createWrapperCommand(Path wrapperPath) { + Path directory = executionRootDirectory.toAbsolutePath().normalize(); + if (!wrapperPath.startsWith(directory)) { + return wrapperPath.toString(); + } + return "." + File.separator + directory.relativize(wrapperPath); + } +} diff --git a/core/src/test/java/com/cosium/code/format/AbstractMavenModuleTest.java b/core/src/test/java/com/cosium/code/format/AbstractMavenModuleTest.java index ffc0a26a..21812737 100644 --- a/core/src/test/java/com/cosium/code/format/AbstractMavenModuleTest.java +++ b/core/src/test/java/com/cosium/code/format/AbstractMavenModuleTest.java @@ -44,6 +44,16 @@ public void GIVEN_bad_formatted_files_WHEN_format_code_THEN_all_files_should_hav assertMatchExpected(badFormatJava); } + @MavenPluginTest + public void + GIVEN_bad_formatted_file_WHEN_validating_THEN_the_command_formatting_all_files_is_displayed() + throws Exception { + mavenExecution() + .withCliOptions(goalCliOption("validate-code-format")) + .execute() + .assertLogText("Run 'mvn git-code-format:format-code' to format all the files."); + } + @MavenPluginTest public void GIVEN_bad_formatted_file_WHEN_adding_and_committing_it_THEN_it_should_have_correct_format() diff --git a/core/src/test/java/com/cosium/code/format/MavenWrapperTest.java b/core/src/test/java/com/cosium/code/format/MavenWrapperTest.java index 55fcdb55..51bbe651 100644 --- a/core/src/test/java/com/cosium/code/format/MavenWrapperTest.java +++ b/core/src/test/java/com/cosium/code/format/MavenWrapperTest.java @@ -5,6 +5,7 @@ import io.takari.maven.testing.executor.MavenRuntime; import io.takari.maven.testing.executor.MavenVersions; import io.takari.maven.testing.executor.junit.MavenPluginTest; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -104,6 +105,21 @@ public void GIVEN_a_maven_wrapper_WHEN_committing_THEN_the_wrapper_formats_the_s .isEqualTo("public class BadFormat {\n" + "\n" + " void a() {}\n" + "}\n"); } + @MavenPluginTest + public void + GIVEN_a_maven_wrapper_WHEN_the_validation_fails_THEN_the_wrapper_is_the_command_to_run() + throws Exception { + installMavenWrapper(projectRoot()); + + buildMavenExecution(projectRoot()) + .withCliOptions(goalCliOption("validate-code-format")) + .execute() + .assertLogText( + "Run '." + + File.separator + + "mvnw git-code-format:format-code' to format all the files."); + } + private void write(String sourceName, String content) throws IOException { Files.write( resolveRelativelyToProjectRoot(sourceName), content.getBytes(StandardCharsets.UTF_8));