Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bc38597
fix DocumentName issues
Claudenw Jun 9, 2026
c2c2d9d
checkpoint
Claudenw Jun 16, 2026
082579e
Fixed several parsing errors in DocumentName.Builder
Claudenw Jun 18, 2026
188a671
initial changes
Claudenw May 10, 2026
53fc65f
created testhelper and updated tests
Claudenw May 10, 2026
d9f42f0
fixed tests
Claudenw May 10, 2026
5e0aebd
Change to Reporter.Output usage
Claudenw May 24, 2026
e625ea6
updated javadoc
Claudenw May 24, 2026
d6f9c33
updated UI strategy
Claudenw May 31, 2026
597808c
Remove ArchiveEntryDocument and clean up ArchiveWalker.
Claudenw Jun 1, 2026
63592fd
Change ArgumentContext to build from Options and arguments rather tha…
Claudenw Jun 1, 2026
d250a12
Switch to UnmodifiableSets for licences
Claudenw Jun 1, 2026
04a5e45
fix spotbugs issues
Claudenw Jun 1, 2026
7ea7d82
fix spotbugs issues
Claudenw Jun 1, 2026
27d16f9
fix spotbugs issues
Claudenw Jun 1, 2026
c828f9c
created TempDir replacement to support Windows
Claudenw Jun 1, 2026
892ea59
Fixed issues with DocumentName and DocumentNameBuilder.
Claudenw Jun 5, 2026
aa88fcb
fixes for DocumentName errors
Claudenw Jun 9, 2026
2632460
fixed rebasing issues
Claudenw Jun 22, 2026
01b4af7
fix DocumentName issues
Claudenw Jun 9, 2026
cba7296
checkpoint
Claudenw Jun 16, 2026
36fc67e
Fixed several parsing errors in DocumentName.Builder
Claudenw Jun 18, 2026
789ce73
RAT-559: Refactor during review
ottlinger Jun 23, 2026
181aafb
RAT-559: Shorten tests
ottlinger Jun 23, 2026
43ad0dd
fixed merge issues
Claudenw Jun 24, 2026
f10553c
fixed rebase issues
Claudenw Jun 25, 2026
59b3b69
fix some sonarqube issues
Claudenw Jun 25, 2026
98d1d6d
fixed sonar issues
Claudenw Jun 26, 2026
ab6f099
fixes for SonarQube results
Claudenw Jun 27, 2026
7ae7c49
cleaned up checkstyle issues
Claudenw Jun 27, 2026
5753369
cleaned up SonarQube issues
Claudenw Jun 27, 2026
14a9187
fixed tests
Claudenw Jun 29, 2026
335aa27
merged main branch
Claudenw Jul 5, 2026
fd06cde
fixup from rebase
Claudenw Jul 23, 2026
36ca0f2
fixed some sonarcloud issues
Claudenw Jul 25, 2026
96e7681
fixed null pointer issue
Claudenw Jul 25, 2026
a9720a4
fixed some sonarcloud issues
Claudenw Jul 26, 2026
3180bf8
fixed bad comments
Claudenw Jul 26, 2026
24953a9
Fixed UIOption build issues
Claudenw Aug 3, 2026
ff90a56
removed dead code
Claudenw Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions apache-rat-core/src/it/java/org/apache/rat/ReportTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@
* associated with the exception.</li>
* </ul>
*/
public class ReportTest {
class ReportTest {

private String[] asArgs(final List<String> argsList) {
return argsList.toArray(new String[0]);
}

@ParameterizedTest(name = "{index} {0}")
@MethodSource("args")
public void integrationTest(String testName, Document commandLineDoc) throws Exception {
void integrationTest(String testName, Document commandLineDoc) throws Exception {
DefaultLog.getInstance().log(Log.Level.INFO, "Running test for " + testName);
File baseDir = new File(commandLineDoc.getName().getName()).getParentFile();

Expand Down Expand Up @@ -119,9 +119,11 @@ public void integrationTest(String testName, Document commandLineDoc) throws Exc

File expectedMsg = new File(baseDir, "expected-message.txt");
if (expectedMsg.exists()) {
String msg = IOUtils.readLines(new FileReader(expectedMsg)).get(0).trim();
assertThrows(RatDocumentAnalysisException.class, () -> Report.main(asArgs(argsList)),
msg);
try (FileReader fr = new FileReader(expectedMsg)) {
String msg = IOUtils.readLines(fr).get(0).trim();
assertThrows(RatDocumentAnalysisException.class, () -> Report.main(asArgs(argsList)),
msg);
}
} else {
Report.main(asArgs(argsList));
}
Expand All @@ -142,7 +144,7 @@ public void integrationTest(String testName, Document commandLineDoc) throws Exc
try {
Object value = shell.run(groovyScript, new String[]{outputFile.getAbsolutePath(), logFile.getAbsolutePath()});
if (value != null) {
fail(String.format("%s", value));
fail(String.format("%s: %s", testName, value));
}
} catch (AssertionError e) {
throw new AssertionError(String.format("%s: %s", testName, e.getMessage()), e);
Expand Down Expand Up @@ -204,6 +206,7 @@ public static class FileLog implements Log {
*
* @param level the level to use when writing messages.
*/
@Override
public void setLevel(final Level level) {
this.level = level;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,9 @@ myArgs[3] = src.getAbsolutePath()

ReportConfiguration configuration = OptionCollection.parseCommands(src, myArgs, { opts -> })
assertNotNull(configuration)
configuration.validate(DefaultLog.getInstance().&error)
configuration.validate()
Reporter reporter = new Reporter(configuration)
Reporter.Output output = reporter.execute()
ClaimStatistic statistic = output.getStatistic()
ClaimStatistic statistic = reporter.execute().getStatistic()

assertEquals(3, statistic.getCounter(ClaimStatistic.Counter.APPROVED))
assertEquals(2, statistic.getCounter(ClaimStatistic.Counter.ARCHIVES))
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Issues with UNAPPROVED
Issues with LICENSE_CATEGORIES, LICENSE_NAMES, STANDARDS
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
--licenses-denied
DOJO
--
24 changes: 21 additions & 3 deletions apache-rat-core/src/main/java/org/apache/rat/CLIOption.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@
*/
package org.apache.rat;

import java.util.function.Function;

import org.apache.commons.cli.Option;
import org.apache.commons.lang3.StringUtils;
import org.apache.rat.ui.ArgumentTracker;
import org.apache.rat.ui.UIOption;
import org.apache.rat.ui.UIOptionCollection;
import org.apache.rat.utils.CasedString;

/**
* The CLI option definition.
*/
public final class CLIOption extends UIOption<CLIOption> {

public CLIOption(final UIOptionCollection<CLIOption> collection, final Option option) {
super(collection, option, ArgumentTracker.extractName(option));
private CLIOption(final CLIBuilder builder) {
super(builder);
}

@Override
Expand Down Expand Up @@ -70,4 +72,20 @@ public String getExample() {
}
return sb.toString();
}

/**
* Builder for a CLI Option.
*/
public static class CLIBuilder extends UIOption.Builder<CLIOption, CLIBuilder> {

@Override
protected Function<Option, CasedString> getNameFactory() {
return ArgumentTracker::extractName;
}

@Override
protected CLIOption doBuild() {
return new CLIOption(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
import org.apache.commons.cli.Option;
import org.apache.rat.ui.UIOptionCollection;

/**
* The collection of CLI Options.
*/
public final class CLIOptionCollection extends UIOptionCollection<CLIOption> {
/** The Help option */
static final Option HELP = new Option("?", "help", false, "Print help for the RAT command line interface and exit.");

/** The instance of the collection */
public static final CLIOptionCollection INSTANCE = new CLIOptionCollection();

private CLIOptionCollection() {
public CLIOptionCollection() {
super(new Builder().uiOption(HELP));
}

private static final class Builder extends UIOptionCollection.Builder<CLIOption, Builder> {
private Builder() {
super(CLIOption::new);
super(CLIOption.CLIBuilder::new);
}
}
}
71 changes: 42 additions & 29 deletions apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.util.stream.Collectors;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
Expand All @@ -51,6 +50,8 @@
import org.apache.rat.license.LicenseSetFactory;
import org.apache.rat.report.Reportable;
import org.apache.rat.report.claim.ClaimStatistic;
import org.apache.rat.ui.ArgumentTracker;
import org.apache.rat.ui.UIOptionCollection;
import org.apache.rat.utils.DefaultLog;
import org.apache.rat.utils.Log.Level;
import org.apache.rat.walker.ArchiveWalker;
Expand All @@ -68,6 +69,11 @@
// do not instantiate
}

/**
* The collection of UI Options.
*/
private static UIOptionCollection baseOptionCollection = new CLIOptionCollection();

/**
* The Option comparator to sort the help.
*/
Expand Down Expand Up @@ -123,36 +129,30 @@
*
* @param workingDirectory The directory to resolve relative file names against.
* @param args the arguments to parse.
* @param helpCmd the help command to run when necessary.

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK25

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK25

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK25

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / macos-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK20

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK21

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK25

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK25

reference not found

Check failure on line 132 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View workflow job for this annotation

GitHub Actions / ubuntu-latest-JDK25

reference not found
* @param noArgs If {@code true} then the commands do not need extra arguments.
* @return a ReportConfiguration or {@code null} if Help was printed.
* @throws IOException on error.
*/
public static ReportConfiguration parseCommands(final File workingDirectory, final String[] args,
final Consumer<Options> helpCmd, final boolean noArgs) throws IOException {

Options opts = buildOptions();
CommandLine commandLine;
ArgumentContext argumentContext;
try {
commandLine = DefaultParser.builder().setDeprecatedHandler(DeprecationReporter.getLogReporter())
.setAllowPartialMatching(true).build().parse(opts, args);
argumentContext = new ArgumentContext(workingDirectory, opts, args);
} catch (ParseException e) {
DefaultLog.getInstance().error(e.getMessage());
DefaultLog.getInstance().error("Please use the \"--help\" option to see a list of valid commands and options.", e);
System.exit(1);
return null; // dummy return (won't be reached) to avoid Eclipse complaint about possible NPE
// for "commandLine"
}
Arg.processLogLevel(argumentContext, baseOptionCollection);

ArgumentContext argumentContext = new ArgumentContext(workingDirectory, commandLine);
Arg.processLogLevel(argumentContext, CLIOptionCollection.INSTANCE);

if (commandLine.hasOption(HELP)) {
if (argumentContext.getCommandLine().hasOption(HELP)) {
helpCmd.accept(opts);
return null;
}

if (commandLine.hasOption(Arg.HELP_LICENSES.option())) {
if (argumentContext.getCommandLine().hasOption(Arg.HELP_LICENSES.option())) {
new Licenses(createConfiguration(argumentContext), new PrintWriter(System.out, false, StandardCharsets.UTF_8)).printHelp();
return null;
}
Expand All @@ -178,25 +178,37 @@
* @see #parseCommands(File, String[], Consumer, boolean)
*/
public static ReportConfiguration createConfiguration(final ArgumentContext argumentContext) {
argumentContext.processArgs(CLIOptionCollection.INSTANCE);
final ReportConfiguration configuration = argumentContext.getConfiguration();
final CommandLine commandLine = argumentContext.getCommandLine();
Optional<Option> dirOpt = CLIOptionCollection.INSTANCE.getSelected(Arg.DIR);
if (dirOpt.isPresent()) {
try {
configuration.addSource(getReportable(commandLine.getParsedOptionValue(
dirOpt.get()), configuration));
} catch (ParseException e) {
throw new ConfigurationException("Unable to set parse " + dirOpt.get(), e);
try {
argumentContext.processArgs(baseOptionCollection);
final ReportConfiguration configuration = argumentContext.getConfiguration();
final CommandLine commandLine = argumentContext.getCommandLine();
Optional<Option> dirOpt = baseOptionCollection.getSelected(Arg.DIR);
if (dirOpt.isPresent()) {
try {
DocumentName directoryName = commandLine.getParsedOptionValue(dirOpt.get());
configuration.addSource(getReportable(directoryName.asFile(), configuration));
} catch (ParseException e) {
throw new ConfigurationException("Unable to set parse " + dirOpt.get(), e);
}
}
}
for (String s : commandLine.getArgs()) {
Reportable reportable = getReportable(new File(s), configuration);
if (reportable != null) {
configuration.addSource(reportable);
for (String s : commandLine.getArgs()) {
Reportable reportable = getReportable(new File(s), configuration);
if (reportable != null) {
configuration.addSource(reportable);

Check warning on line 197 in apache-rat-core/src/main/java/org/apache/rat/OptionCollection.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested try block into a separate method.

See more on https://sonarcloud.io/project/issues?id=apache_creadur-rat&issues=AZ_Iw5r6C2tP99px9euZ&open=AZ_Iw5r6C2tP99px9euZ&pullRequest=655
}
}
return configuration;
} catch (RuntimeException e) {
try (PrintWriter pw = new PrintWriter(DefaultLog.getInstance().asWriter(Level.ERROR))) {
pw.println("Unable to create Configuration: " + e.getMessage());
pw.println("=== Command line options ===");
for (Option opt : argumentContext.getCommandLine().getOptions()) {
pw.printf(" %s: %s%n", ArgumentTracker.extractKey(opt), String.join(", ", opt.getValues()));
}
}
throw new ConfigurationException("Unable to create Configuration", e);
}
return configuration;

}

/**
Expand All @@ -205,7 +217,8 @@
* @return the Options comprised of the Options defined in this class.
*/
public static Options buildOptions() {
return CLIOptionCollection.INSTANCE.getOptions();
baseOptionCollection.resetSelected();
return baseOptionCollection.getOptions();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.rat.api.RatException;
import org.apache.rat.commandline.Arg;
import org.apache.rat.commandline.ArgumentContext;
import org.apache.rat.help.Licenses;
import org.apache.rat.report.Reportable;
import org.apache.rat.ui.UIOption;
import org.apache.rat.ui.UIOptionCollection;
import org.apache.rat.utils.DefaultLog;

Expand All @@ -44,15 +46,21 @@
/**
* Uses the AbstractOptionCollection to parse the command line options.
* Contains utility methods to ReportConfiguration from the options and an array of arguments.
*
* @param <T> The UIOption type that this parser is handeling.
*/
@SuppressFBWarnings("EI_EXPOSE_REP2")
public final class OptionCollectionParser {
public final class OptionCollectionParser<T extends UIOption<T>> {
/**
* The OptionCollection that we are working with.
*/
private final UIOptionCollection<?> uiOptionCollection;
private final UIOptionCollection<T> uiOptionCollection;

public OptionCollectionParser(final UIOptionCollection<?> optionCollection) {
/**
* Constructor.
* @param optionCollection The option collection to use for
*/
public OptionCollectionParser(final UIOptionCollection<T> optionCollection) {
this.uiOptionCollection = optionCollection;
}

Expand All @@ -62,11 +70,10 @@ public OptionCollectionParser(final UIOptionCollection<?> optionCollection) {
* @param workingDirectory The directory to resolve relative file names against.
* @param args the arguments to parse
* @return the ArgumentContext for the process.
* @throws IOException on error.
* @throws ParseException on option parsing error.
* @throws RatException on error.
*/
public ArgumentContext parseCommands(final File workingDirectory, final String[] args)
throws IOException, ParseException {
throws RatException {
return parseCommands(workingDirectory, args, uiOptionCollection.getOptions());
}

Expand All @@ -77,8 +84,7 @@ public ArgumentContext parseCommands(final File workingDirectory, final String[]
* @return the CommandLine
* @throws ParseException on option parsing error.
*/
//@VisibleForTesting
CommandLine parseCommandLine(final Options opts, final String[] args) throws ParseException {
public static CommandLine parseCommandLine(final Options opts, final String[] args) throws ParseException {
try {
return DefaultParser.builder().setDeprecatedHandler(DeprecationReporter.getLogReporter())
.setAllowPartialMatching(true).build().parse(opts, args);
Expand All @@ -89,29 +95,39 @@ CommandLine parseCommandLine(final Options opts, final String[] args) throws Par
}
}

// visible for testing
void printHelp(final ArgumentContext argumentContext) throws RatException {
try {
new Licenses(argumentContext.getConfiguration(),
new PrintWriter(argumentContext.getConfiguration().getOutput().get(),
false, StandardCharsets.UTF_8)).printHelp();
} catch (IOException e) {
throw new RatException("Unable to print help: " + e.getMessage(), e);
}
}
/**
* Parses the standard options to create a ReportConfiguration.
*
* @param workingDirectory The directory to resolve relative file names against.
* @param args the arguments to parse.
* @param options An Options object containing Apache command line options.
* @return the ArgumentContext for the process.
* @throws IOException on error.
* @throws ParseException on option parsing error.
* @throws RatException on error.
*/
private ArgumentContext parseCommands(final File workingDirectory, final String[] args,
final Options options) throws IOException, ParseException {
CommandLine commandLine = parseCommandLine(options, args);
ArgumentContext argumentContext = new ArgumentContext(workingDirectory, commandLine);
Arg.processLogLevel(argumentContext, uiOptionCollection);
populateConfiguration(argumentContext);
if (uiOptionCollection.isSelected(Arg.HELP_LICENSES)) {
new Licenses(argumentContext.getConfiguration(),
new PrintWriter(argumentContext.getConfiguration().getOutput().get(),
false, StandardCharsets.UTF_8)).printHelp();
// visible for testing
ArgumentContext parseCommands(final File workingDirectory, final String[] args,
final Options options) throws RatException {
try {
ArgumentContext argumentContext = new ArgumentContext(workingDirectory, options, args);
Arg.processLogLevel(argumentContext, uiOptionCollection);
populateConfiguration(argumentContext);
if (uiOptionCollection.isSelected(Arg.HELP_LICENSES)) {
printHelp(argumentContext);
}
return argumentContext;
} catch (ParseException e) {
throw new RatException("Unable to parse command line: " + e.getMessage(), e);
}

return argumentContext;
}

/**
Expand Down
Loading
Loading