Compare commits

...

10 commits

10 changed files with 165 additions and 79 deletions

View file

@ -1,6 +1,6 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<copyright> <copyright>
<option name="notice" value="Copyright 2023-Copyright &amp;#36;today.yearamp;#36;today.year the original author or authors.&#10; &#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; https://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." /> <option name="notice" value="Copyright 2023-&amp;#36;today.year the original author or authors.&#10; &#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; https://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="myName" value="Apache License" /> <option name="myName" value="Apache License" />
</copyright> </copyright>
</component> </component>

View file

@ -37,5 +37,5 @@ not provided by the extension. For example:
```java ```java
repositories = List.of(MAVEN_CENTRAL); repositories = List.of(MAVEN_CENTRAL);
scope(test).include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 15, 0))); scope(test).include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 16, 0)));
``` ```

View file

@ -7,6 +7,10 @@ TMPOLD=/tmp/checkcliargs-old
java -cp "lib/test/*" $MAIN --help >$TMPNEW java -cp "lib/test/*" $MAIN --help >$TMPNEW
java -cp "examples/lib/test/*" $MAIN --help >$TMPOLD java -cp "examples/lib/test/*" $MAIN --help >$TMPOLD
diff $TMPOLD $TMPNEW if [ "$1" == "-v" ]; then
code --wait --diff $TMPOLD $TMPNEW
else
diff $TMPOLD $TMPNEW
fi
rm -rf $TMPNEW $TMPOLD rm -rf $TMPNEW $TMPOLD

View file

@ -1,6 +1,6 @@
bld.downloadExtensionJavadoc=false bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true bld.downloadExtensionSources=true
bld.extensions=com.uwyn.rife2:bld-checkstyle:0.9.6 bld.extensions=com.uwyn.rife2:bld-checkstyle:1.0.0
bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.downloadLocation= bld.downloadLocation=
bld.sourceDirectories= bld.sourceDirectories=

View file

@ -16,12 +16,14 @@ public class ExamplesBuild extends BaseProject {
mainClass = "com.example.ExamplesMain"; mainClass = "com.example.ExamplesMain";
version = version(0, 1, 0); version = version(0, 1, 0);
javaRelease = 17;
autoDownloadPurge = true; autoDownloadPurge = true;
downloadSources = true; downloadSources = true;
repositories = List.of(MAVEN_CENTRAL); repositories = List.of(MAVEN_CENTRAL);
scope(test).include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 15, 0))); scope(test).include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 16, 0)));
testOperation().mainClass("com.example.ExamplesTest"); testOperation().mainClass("com.example.ExamplesTest");
} }

View file

@ -1,7 +1,7 @@
bld.downloadExtensionJavadoc=false bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true bld.downloadExtensionSources=true
bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.8 bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.9
bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.3 bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.5
bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES
bld.downloadLocation= bld.downloadLocation=
bld.sourceDirectories= bld.sourceDirectories=

View file

@ -35,7 +35,7 @@ public class CheckstyleOperationBuild extends Project {
public CheckstyleOperationBuild() { public CheckstyleOperationBuild() {
pkg = "rife.bld.extension"; pkg = "rife.bld.extension";
name = "CheckstyleOperation"; name = "CheckstyleOperation";
version = version(0, 9, 6); version = version(1, 0, 0);
javaRelease = 17; javaRelease = 17;
downloadSources = true; downloadSources = true;
@ -45,7 +45,7 @@ public class CheckstyleOperationBuild extends Project {
scope(compile) scope(compile)
.include(dependency("com.uwyn.rife2", "bld", version(1, 9, 0))); .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 0)));
scope(test) scope(test)
.include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 15, 0))) .include(dependency("com.puppycrawl.tools", "checkstyle", version(10, 16, 0)))
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2)))
.include(dependency("org.assertj", "assertj-core", version(3, 25, 3))); .include(dependency("org.assertj", "assertj-core", version(3, 25, 3)));

View file

@ -0,0 +1,32 @@
/*
* Copyright 2023-2004 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 rife.bld.extension;
/**
* The Checkstyle output format for XML, sarif and default (plaib) logger.
*/
public enum CheckstyleFormatOption {
XML("xml"),
SARIF("sarif"),
PLAIN("plain");
public final String label;
CheckstyleFormatOption(String label) {
this.label = label;
}
}

View file

@ -32,11 +32,12 @@ import java.util.logging.Logger;
*/ */
public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOperation> { public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOperation> {
private static final Logger LOGGER = Logger.getLogger(CheckstyleOperation.class.getName()); private static final Logger LOGGER = Logger.getLogger(CheckstyleOperation.class.getName());
protected final List<String> exclude = new ArrayList<>();
protected final List<String> excludeRegex = new ArrayList<>();
/** /**
* The command line options. * The command line options.
*/ */
protected final Map<String, String> options = new ConcurrentHashMap<>(); protected final Map<String, String> options = new ConcurrentHashMap<>();
/** /**
* The source files(s) or folder(s). * The source files(s) or folder(s).
*/ */
@ -97,7 +98,7 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
public CheckstyleOperation exclude(String... path) { public CheckstyleOperation exclude(String... path) {
for (var p : path) { for (var p : path) {
if (isNotBlank(p)) { if (isNotBlank(p)) {
options.put("-e", p); exclude.add(p);
} }
} }
return this; return this;
@ -107,29 +108,50 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
* Directory/file to exclude from CheckStyle. The path can be the full, absolute path, or relative to the current * Directory/file to exclude from CheckStyle. The path can be the full, absolute path, or relative to the current
* path. Multiple excludes are allowed. * path. Multiple excludes are allowed.
* *
* @param paths the list of paths * @param paths the paths
* @return the checkstyle operation * @return the checkstyle operation
* @see #exclude(String...) * @see #exclude(String...)
*/ */
public CheckstyleOperation exclude(Collection<String> paths) { public CheckstyleOperation exclude(Collection<String> paths) {
for (var p : paths) { for (var p : paths) {
if (isNotBlank(p)) { if (isNotBlank(p)) {
options.put("-e", p); exclude.add(p);
} }
} }
return this; return this;
} }
/** /**
* Directory/file pattern to exclude from CheckStyle. Multiple excludes are allowed. * Directory/file pattern to exclude from CheckStyle. Multiple exclude are allowed.
* *
* @param pattern the pattern * @param regex the pattern to exclude
* @return the checkstyle operation * @return the checkstyle operation
* @see #excludeRegex(Collection)
*/ */
public CheckstyleOperation excludedPathPattern(String pattern) { public CheckstyleOperation excludeRegex(String... regex) {
if (isNotBlank(pattern)) { for (var r : regex) {
options.put("-x", pattern); if (isNotBlank(r)) {
excludeRegex.add(r);
}
} }
return this;
}
/**
* Directory/file pattern to exclude from CheckStyle. Multiple exclude are allowed.
*
* @param regex the patterns to exclude
* @return the checkstyle operation
* @see #excludeRegex(String...)
*/
public CheckstyleOperation excludeRegex(Collection<String> regex) {
for (var r : regex) {
if (isNotBlank(r)) {
excludeRegex.add(r);
}
}
return this; return this;
} }
@ -162,6 +184,22 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
}); });
if (!exclude.isEmpty()) {
for (var e : exclude) {
if (isNotBlank(e)) {
args.add("-e " + e);
}
}
}
if (!excludeRegex.isEmpty()) {
for (var e : excludeRegex) {
if (isNotBlank(e)) {
args.add("-x " + e);
}
}
}
args.addAll(sourceDirs); args.addAll(sourceDirs);
return args; return args;
@ -192,16 +230,17 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Specifies the output format. Valid values: {@code xml}, {@code sarif}, {@code plain} for the XML, sarif and * Specifies the output format. Valid values: {@link CheckstyleFormatOption#XML},
* default logger respectively. Defaults to {@code plain}. * {@link CheckstyleFormatOption#SARIF}, {@link CheckstyleFormatOption#PLAIN} for the XML, sarif and default logger
* respectively.
* <p>
* Defaults to {@link CheckstyleFormatOption#PLAIN}.
* *
* @param format the format * @param format the output format
* @return the checkstyle operation * @return the checkstyle operation
*/ */
public CheckstyleOperation format(String format) { public CheckstyleOperation format(CheckstyleFormatOption format) {
if (isNotBlank(format)) { options.put("-f", format.label.toLowerCase());
options.put("-f", format);
}
return this; return this;
} }
@ -209,7 +248,7 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
* Generates to output a suppression xml to use to suppress all violations from user's config. Instead of printing * Generates to output a suppression xml to use to suppress all violations from user's config. Instead of printing
* every violation, all violations will be caught and single suppressions xml file will be printed out. * every violation, all violations will be caught and single suppressions xml file will be printed out.
* Used only with the {@link #configurationFile(String) configurationFile} option. Output location can be specified * Used only with the {@link #configurationFile(String) configurationFile} option. Output location can be specified
* with the {@link #output(String) output} option. * with the {@link #outputPath(String) output} option.
* *
* @param xPathSuppression {@code true} or {@code false} * @param xPathSuppression {@code true} or {@code false}
* @return the checkstyle operation * @return the checkstyle operation
@ -231,9 +270,9 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Prints Parse Tree of the Javadoc comment. The file have to contain <b>only Javadoc comment content</b> * This option is used to print the Parse Tree of the Javadoc comment. The file has to contain only Javadoc comment
* without including '&#47;**' and '*&#47;' at the beginning and at the end respectively. The option cannot * content excluding '&#47;**' and '*&#47;' at the beginning and at the end respectively. It can only be used on a
* be used other options and requires exactly one file to run on to be specified. * single file and cannot be combined with other options.
* *
* @param isTree {@code true} or {@code false} * @param isTree {@code true} or {@code false}
* @return the checkstyle operation * @return the checkstyle operation
@ -248,31 +287,14 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Prints xpath suppressions at the file's line and column position. Argument is the line and column number * Sets the output file.
* (separated by a {@code :} ) in the file that the suppression should be generated for. The option cannot be
* used with other options and requires exactly one file to run on to be specified.
* <p> * <p>
* <b>ATTENTION</b>: generated result will have few queries, joined by pipe(|). Together they will match all AST nodes * Defaults to stdout.
* on specified line and column. You need to choose only one and recheck that it works. Usage of all of them is also
* ok, but might result in undesirable matching and suppress other issues.
* *
* @param lineColumn the line column * @param file the output file
* @return the checkstyle operation * @return the checkstyle operation
*/ */
public CheckstyleOperation lineColumn(String lineColumn) { public CheckstyleOperation outputPath(String file) {
if (isNotBlank(lineColumn)) {
options.put("-s", lineColumn);
}
return this;
}
/**
* Sets the output file. Defaults to stdout.
*
* @param file the file
* @return the checkstyle operation
*/
public CheckstyleOperation output(String file) {
if (isNotBlank(file)) { if (isNotBlank(file)) {
options.put("-o", file); options.put("-o", file);
} }
@ -317,7 +339,28 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Sets the length of the tab character. Used only with the {@link #lineColumn(String) lineColum} option. * Prints xpath suppressions at the file's line and column position. Argument is the line and column number
* (separated by a {@code :} ) in the file that the suppression should be generated for. The option cannot be
* used with other options and requires exactly one file to run on to be specified.
* <p>
* Note that the generated result will have few queries, joined by pipe({@code |}). Together they will match all
* AST nodes on specified line and column. You need to choose only one and recheck that it works. Usage of all of
* them is also ok, but might result in undesirable matching and suppress other issues.
*
* @param lineColumnNumber the line column number
* @return the checkstyle operation
*/
public CheckstyleOperation suppressionLineColumnNumber(String lineColumnNumber) {
if (isNotBlank(lineColumnNumber)) {
options.put("-s", lineColumnNumber);
}
return this;
}
/**
* Sets the length of the tab character. Used only with the
* {@link #suppressionLineColumnNumber(String) suppressionLineColumnNumber} option.
* <p>
* Default value is {@code 8}. * Default value is {@code 8}.
* *
* @param length the length * @param length the length
@ -329,8 +372,8 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Prints Abstract Syntax Tree(AST) of the checked file. The option cannot be used other options and requires * This option is used to display the Abstract Syntax Tree (AST) without any comments of the specified file. It can
* exactly one file to run on to be specified. * only be used on a single file and cannot be combined with other options.
* *
* @param isTree {@code true} or {@code false} * @param isTree {@code true} or {@code false}
* @return the checkstyle operation * @return the checkstyle operation
@ -345,8 +388,8 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Prints Abstract Syntax Tree(AST) with comment nodes of the checked file. The option cannot be used with other * This option is used to display the Abstract Syntax Tree (AST) with comment nodes excluding Javadoc of the
* options and requires exactly one file to run on to be specified. * specified file. It can only be used on a single file and cannot be combined with other options.
* *
* @param isTree {@code true} or {@code false} * @param isTree {@code true} or {@code false}
* @return the checkstyle operation * @return the checkstyle operation
@ -361,10 +404,8 @@ public class CheckstyleOperation extends AbstractProcessOperation<CheckstyleOper
} }
/** /**
* Prints Abstract Syntax Tree(AST) with Javadoc nodes and comment nodes of the checked file. Attention that line * This option is used to display the Abstract Syntax Tree (AST) with Javadoc nodes of the specified file. It can
* number and columns will not be the same as it is a file due to the fact that each javadoc comment is parsed * only be used on a single file and cannot be combined with other options.
* separately from java file. The option cannot be used with other options and requires exactly one file to run on
* to be specified.
* *
* @param isTree {@code true} or {@code false} * @param isTree {@code true} or {@code false}
* @return the checkstyle operation * @return the checkstyle operation

View file

@ -58,18 +58,25 @@ class CheckstyleOperationTest {
@Test @Test
void exclude() { void exclude() {
var op = new CheckstyleOperation().fromProject(new Project()).exclude(FOO); var op = new CheckstyleOperation().fromProject(new Project()).exclude(FOO, BAR);
assertThat(op.options.get("-e")).isEqualTo(FOO); var e = "-e ";
op = new CheckstyleOperation().fromProject(new Project()).exclude(List.of(FOO)); assertThat(op.executeConstructProcessCommandList()).contains(e + FOO, e + BAR);
assertThat(op.options.get("-e")).as("as list").isEqualTo(FOO);
op = new CheckstyleOperation().fromProject(new Project()).exclude(List.of(FOO, BAR));
assertThat(op.executeConstructProcessCommandList()).as("as list").contains(e + FOO, e + BAR);
} }
@Test @Test
void excludedPathPattern() { void excludeRegex() {
var op = new CheckstyleOperation().fromProject(new Project()).excludedPathPattern(FOO); var op = new CheckstyleOperation().fromProject(new Project()).excludeRegex(FOO, BAR);
assertThat(op.options.get("-x")).isEqualTo(FOO); var x = "-x ";
assertThat(op.executeConstructProcessCommandList()).contains(x + FOO, x + BAR);
op = new CheckstyleOperation().fromProject(new Project()).excludeRegex(List.of(FOO, BAR));
assertThat(op.executeConstructProcessCommandList()).as("as list").contains(x + FOO, x + BAR);
} }
@Test @Test
void execute() throws IOException, ExitStatusException, InterruptedException { void execute() throws IOException, ExitStatusException, InterruptedException {
var tmpFile = File.createTempFile("checkstyle-google", ".txt"); var tmpFile = File.createTempFile("checkstyle-google", ".txt");
@ -78,7 +85,7 @@ class CheckstyleOperationTest {
.fromProject(new WebProject()) .fromProject(new WebProject())
.sourceDir("src/main/java", "src/test/java") .sourceDir("src/main/java", "src/test/java")
.configurationFile("src/test/resources/google_checks.xml") .configurationFile("src/test/resources/google_checks.xml")
.output(tmpFile.getAbsolutePath()); .outputPath(tmpFile.getAbsolutePath());
op.execute(); op.execute();
assertThat(tmpFile).exists(); assertThat(tmpFile).exists();
} }
@ -119,15 +126,15 @@ class CheckstyleOperationTest {
.fromProject(new WebProject()) .fromProject(new WebProject())
.sourceDir(List.of("src/main/java", "src/test/java")) .sourceDir(List.of("src/main/java", "src/test/java"))
.configurationFile("src/test/resources/sun_checks.xml") .configurationFile("src/test/resources/sun_checks.xml")
.output(tmpFile.getAbsolutePath()); .outputPath(tmpFile.getAbsolutePath());
assertThatCode(op::execute).isInstanceOf(ExitStatusException.class); assertThatCode(op::execute).isInstanceOf(ExitStatusException.class);
assertThat(tmpFile).exists(); assertThat(tmpFile).exists();
} }
@Test @Test
void format() { void format() {
var op = new CheckstyleOperation().fromProject(new Project()).format(FOO); var op = new CheckstyleOperation().fromProject(new Project()).format(CheckstyleFormatOption.XML);
assertThat(op.options.get("-f")).isEqualTo(FOO); assertThat(op.options.get("-f")).isEqualTo("xml");
} }
@Test @Test
@ -147,14 +154,8 @@ class CheckstyleOperationTest {
} }
@Test @Test
void lineColumn() { void outputPath() {
var op = new CheckstyleOperation().fromProject(new Project()).lineColumn(FOO); var op = new CheckstyleOperation().fromProject(new Project()).outputPath(FOO);
assertThat(op.options.get("-s")).isEqualTo(FOO);
}
@Test
void output() {
var op = new CheckstyleOperation().fromProject(new Project()).output(FOO);
assertThat(op.options.get("-o")).isEqualTo(FOO); assertThat(op.options.get("-o")).isEqualTo(FOO);
} }
@ -172,6 +173,12 @@ class CheckstyleOperationTest {
assertThat(op.sourceDirs).as("foo, bar").hasSize(2).contains(FOO).contains(BAR); assertThat(op.sourceDirs).as("foo, bar").hasSize(2).contains(FOO).contains(BAR);
} }
@Test
void suppressionLineColumnNumber() {
var op = new CheckstyleOperation().fromProject(new Project()).suppressionLineColumnNumber(FOO + ':' + BAR);
assertThat(op.options.get("-s")).isEqualTo(FOO + ':' + BAR);
}
@Test @Test
void tabWith() { void tabWith() {
var op = new CheckstyleOperation().fromProject(new Project()).tabWith(9); var op = new CheckstyleOperation().fromProject(new Project()).tabWith(9);