This is an automated email from the ASF dual-hosted git repository.

claude pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/creadur-rat.git


The following commit(s) were added to refs/heads/master by this push:
     new 34dcb05d RAT-98: Add file arg converter (#425)
34dcb05d is described below

commit 34dcb05db326374b19ddb3d864cf60656d41bae4
Author: Claude Warren <[email protected]>
AuthorDate: Tue Feb 4 01:28:37 2025 +0100

    RAT-98: Add file arg converter (#425)
    
    * added working directory
    
    * updated merge issues
    
    * Added FSInfo to handle file system differences
    
    * updated spotbugs
    
    * attempt to fix windows error
    
    * fixed merge error
    
    * fixed pattern match
    
    * fix for file delete on windows
    
    * added more descriptive failure messages
    
    * added file converter + test
    
    * fixes file list walker
    
    * Prevent possible NPE
    
    * Minor review changes
    
    ---------
    
    Co-authored-by: P. Ottlinger <[email protected]>
---
 .../main/java/org/apache/rat/commandline/Arg.java  | 38 +++++++++------
 .../org/apache/rat/commandline/Converters.java     | 57 ++++++++++++++++++++--
 .../rat/config/exclusion/plexus/MatchPattern.java  |  3 +-
 .../rat/config/exclusion/plexus/MatchPatterns.java |  5 +-
 .../java/org/apache/rat/commandline/ArgTests.java  | 16 +++---
 .../java/org/apache/rat/mp/AbstractRatMojo.java    |  8 +--
 .../org/apache/rat/anttasks/ReportOptionTest.java  |  2 +-
 7 files changed, 91 insertions(+), 38 deletions(-)

diff --git a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java 
b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
index 3ba85b95..c14607c5 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/commandline/Arg.java
@@ -119,10 +119,14 @@ public enum Arg {
     CONFIGURATION(new OptionGroup()
             
.addOption(Option.builder().longOpt("config").hasArgs().argName("File")
                     .desc("File names for system configuration.")
+                    .converter(Converters.FILE_CONVERTER)
+                    .type(File.class)
                     .build())
             
.addOption(Option.builder().longOpt("licenses").hasArgs().argName("File")
                     .desc("File names for system configuration.")
                     
.deprecated(DeprecatedAttributes.builder().setSince("0.17").setForRemoval(true).setDescription(StdMsgs.useMsg("--config")).get())
+                    .converter(Converters.FILE_CONVERTER)
+                    .type(File.class)
                     .build())),
 
     /**
@@ -186,7 +190,6 @@ public enum Arg {
             .hasArg().argName("File").type(File.class)
             .converter(Converters.FILE_CONVERTER)
             .desc("Name of file containing the denied license IDs.")
-            .converter(Converters.FILE_CONVERTER)
             .build())),
 
     /**
@@ -234,6 +237,7 @@ public enum Arg {
                             "File names must use linux directory separator 
('/') or none at all. " +
                             "File names that do not start with '/' are 
relative to the directory where the " +
                             "argument is located.")
+                    .converter(Converters.FILE_CONVERTER)
                     .type(File.class)
                     .build())),
 
@@ -585,8 +589,9 @@ public enum Arg {
         try {
             Defaults.Builder defaultBuilder = Defaults.builder();
             if (CONFIGURATION.isSelected()) {
-                for (String fn : 
context.getCommandLine().getOptionValues(CONFIGURATION.getSelected())) {
-                    defaultBuilder.add(fn);
+                File[] files = 
CONFIGURATION.getParsedOptionValues(context.getCommandLine());
+                for (File file : files) {
+                    defaultBuilder.add(file);
                 }
             }
             if (CONFIGURATION_NO_DEFAULTS.isSelected()) {
@@ -607,7 +612,7 @@ public enum Arg {
                     try (InputStream in = Files.newInputStream(f.toPath())) {
                         
context.getConfiguration().addApprovedLicenseCategories(IOUtils.readLines(in, 
StandardCharsets.UTF_8));
                     }
-                } catch (IOException | ParseException e) {
+                } catch (IOException e) {
                     throw new ConfigurationException(e);
                 }
             }
@@ -622,7 +627,7 @@ public enum Arg {
                     try (InputStream in = Files.newInputStream(f.toPath())) {
                         
context.getConfiguration().removeApprovedLicenseCategories(IOUtils.readLines(in,
 StandardCharsets.UTF_8));
                     }
-                } catch (IOException | ParseException e) {
+                } catch (IOException e) {
                     throw new ConfigurationException(e);
                 }
             }
@@ -634,11 +639,11 @@ public enum Arg {
             }
             if (LICENSES_APPROVED_FILE.isSelected()) {
                 try {
-                    File f = 
context.getCommandLine().getParsedOptionValue(LICENSES_APPROVED_FILE.getSelected());
-                    try (InputStream in = Files.newInputStream(f.toPath())) {
+                    File file = 
context.getCommandLine().getParsedOptionValue(LICENSES_APPROVED_FILE.getSelected());
+                    try (InputStream in = Files.newInputStream(file.toPath())) 
{
                         
context.getConfiguration().addApprovedLicenseIds(IOUtils.readLines(in, 
StandardCharsets.UTF_8));
                     }
-                } catch (IOException | ParseException e) {
+                } catch (IOException e) {
                     throw new ConfigurationException(e);
                 }
             }
@@ -649,11 +654,11 @@ public enum Arg {
             }
             if (LICENSES_DENIED_FILE.isSelected()) {
                 try {
-                    File f = 
context.getCommandLine().getParsedOptionValue(LICENSES_DENIED_FILE.getSelected());
-                    try (InputStream in = Files.newInputStream(f.toPath())) {
+                    File file = 
context.getCommandLine().getParsedOptionValue(LICENSES_DENIED_FILE.getSelected());
+                    try (InputStream in = Files.newInputStream(file.toPath())) 
{
                         
context.getConfiguration().removeApprovedLicenseIds(IOUtils.readLines(in, 
StandardCharsets.UTF_8));
                     }
-                } catch (IOException | ParseException e) {
+                } catch (IOException e) {
                     throw new ConfigurationException(e);
                 }
             }
@@ -795,6 +800,7 @@ public enum Arg {
      * @throws ConfigurationException on error
      */
     public static void processArgs(final ArgumentContext context) throws 
ConfigurationException {
+        
Converters.FILE_CONVERTER.setWorkingDirectory(context.getWorkingDirectory());
         processOutputArgs(context);
         processEditArgs(context);
         processInputArgs(context);
@@ -843,12 +849,12 @@ public enum Arg {
 
         if (OUTPUT_FILE.isSelected()) {
             try {
-                File f = 
context.getCommandLine().getParsedOptionValue(OUTPUT_FILE.getSelected());
-                File parent = f.getParentFile();
+                File file = 
context.getCommandLine().getParsedOptionValue(OUTPUT_FILE.getSelected());
+                File parent = file.getParentFile();
                 if (!parent.mkdirs() && !parent.isDirectory()) {
-                    DefaultLog.getInstance().error("Could not create report 
parent directory " + f);
+                    DefaultLog.getInstance().error("Could not create report 
parent directory " + file);
                 }
-                context.getConfiguration().setOut(f);
+                context.getConfiguration().setOut(file);
             } catch (ParseException e) {
                 context.logParseException(e, OUTPUT_FILE.getSelected(), 
"System.out");
                 context.getConfiguration().setOut((IOSupplier<OutputStream>) 
null);
@@ -857,7 +863,7 @@ public enum Arg {
 
         if (OUTPUT_STYLE.isSelected()) {
             String selected = OUTPUT_STYLE.getSelected().getKey();
-            if (selected.equals("x")) {
+            if ("x".equals(selected)) {
                 // display deprecated message.
                 context.getCommandLine().hasOption("x");
                 
context.getConfiguration().setStyleSheet(StyleSheets.getStyleSheet("xml"));
diff --git 
a/apache-rat-core/src/main/java/org/apache/rat/commandline/Converters.java 
b/apache-rat-core/src/main/java/org/apache/rat/commandline/Converters.java
index 197703f9..78333e59 100644
--- a/apache-rat-core/src/main/java/org/apache/rat/commandline/Converters.java
+++ b/apache-rat-core/src/main/java/org/apache/rat/commandline/Converters.java
@@ -19,16 +19,18 @@
 package org.apache.rat.commandline;
 
 import java.io.File;
+import java.io.IOException;
 
 import org.apache.commons.cli.Converter;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.rat.ConfigurationException;
+import org.apache.rat.document.DocumentName;
 import org.apache.rat.report.claim.ClaimStatistic;
 
 import static java.lang.String.format;
 
 /**
- * Customized converters for Arg processing
+ * Customized converters for Arg processing.
  */
 public final class Converters {
 
@@ -37,11 +39,12 @@ public final class Converters {
     }
 
     /**
-     * Creates a File with fully qualified name
+     * Creates a File with fully qualified name.
      */
-    public static final Converter<File, NullPointerException> FILE_CONVERTER = 
s -> new File(s).getAbsoluteFile();
+    public static final FileConverter FILE_CONVERTER = new FileConverter();
+
     /**
-     * converts the Converter pattern into a Converter, count pair.
+     * Converts the Converter pattern into a Converter, count pair.
      */
     public static final Converter<Pair<ClaimStatistic.Counter, Integer>, 
ConfigurationException> COUNTER_CONVERTER = arg -> {
         String[] parts = arg.split(":");
@@ -55,4 +58,50 @@ public final class Converters {
             throw new ConfigurationException(format("'%s' is not a valid 
Counter", parts[0]), e);
         }
     };
+
+    /**
+     * A converter that can handle relative or absolute files.
+     */
+    public static final class FileConverter implements Converter<File, 
NullPointerException> {
+        /** The working directory to resolve relative files against. */
+        private DocumentName workingDirectory;
+
+        /**
+         * The constructor.
+         */
+        private FileConverter() {
+            // private construction only.
+        }
+
+        /**
+         * Sets the working directory for the conversion.
+         * @param workingDirectory current working directory
+         */
+        public void setWorkingDirectory(final DocumentName workingDirectory) {
+            this.workingDirectory = workingDirectory;
+        }
+
+        /**
+         * Applies the conversion function to the specified file name.
+         * @param fileName the file name to create a file from.
+         * @return a File.
+         * @throws NullPointerException if {@code fileName} is null.
+         */
+        public File apply(final String fileName) throws NullPointerException {
+            File file = new File(fileName);
+            // is this a relative file?
+            if (!fileName.startsWith(File.separator)) {
+                // check for a root provided (e.g. C:\\)"
+                if 
(!DocumentName.FSInfo.getDefault().rootFor(fileName).isPresent()) {
+                    // no root, resolve against workingDirectory
+                    file = new 
File(workingDirectory.resolve(fileName).getName()).getAbsoluteFile();
+                }
+            }
+            try {
+                return file.getCanonicalFile();
+            } catch (IOException e) {
+                return file.getAbsoluteFile();
+            }
+        }
+    }
 }
diff --git 
a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
 
b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
index 9932376f..11b71445 100644
--- 
a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
+++ 
b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPattern.java
@@ -117,8 +117,7 @@ public final class MatchPattern {
 
     @Override
     public String toString() {
-        return Arrays.asList(tokenized)
-                .toString();
+        return Arrays.asList(tokenized).toString();
     }
 
     public String source() {
diff --git 
a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
 
b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
index 0a670393..06c4672d 100644
--- 
a/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
+++ 
b/apache-rat-core/src/main/java/org/apache/rat/config/exclusion/plexus/MatchPatterns.java
@@ -42,10 +42,7 @@ public final class MatchPatterns {
 
     @Override
     public String toString() {
-        return Arrays.stream(patterns)
-                .map(MatchPattern::toString)
-                .collect(Collectors.toList())
-                .toString();
+        return 
Arrays.stream(patterns).map(MatchPattern::toString).collect(Collectors.toList()).toString();
     }
 
     public String source() {
diff --git 
a/apache-rat-core/src/test/java/org/apache/rat/commandline/ArgTests.java 
b/apache-rat-core/src/test/java/org/apache/rat/commandline/ArgTests.java
index 7472a0a9..7f27cb8d 100644
--- a/apache-rat-core/src/test/java/org/apache/rat/commandline/ArgTests.java
+++ b/apache-rat-core/src/test/java/org/apache/rat/commandline/ArgTests.java
@@ -18,6 +18,7 @@
  */
 package org.apache.rat.commandline;
 
+import java.io.IOException;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.Options;
@@ -25,12 +26,13 @@ import org.apache.commons.cli.ParseException;
 import org.apache.rat.DeprecationReporter;
 import org.apache.rat.OptionCollection;
 import org.apache.rat.ReportConfiguration;
+import org.apache.rat.document.DocumentName;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.File;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
 
 public class ArgTests {
 
@@ -40,9 +42,9 @@ public class ArgTests {
                 .setAllowPartialMatching(true).build().parse(opts, args);
     }
 
-    @ParameterizedTest
+    @ParameterizedTest(name = "{0}")
     @ValueSource(strings = { "rat.txt", "./rat.txt", "/rat.txt", 
"target/rat.test" })
-    public void outputFleNameNoDirectoryTest(String name) throws 
ParseException {
+    public void outputFleNameNoDirectoryTest(String name) throws 
ParseException, IOException {
         class OutputFileConfig extends ReportConfiguration  {
             private File actual = null;
             @Override
@@ -50,13 +52,13 @@ public class ArgTests {
                 actual = file;
             }
         }
+        String fileName = name.replace("/", 
DocumentName.FSInfo.getDefault().dirSeparator());
+        File expected = new File(fileName);
 
-        File expected = new File(name);
-
-        CommandLine commandLine = createCommandLine(new String[] 
{"--output-file", name});
+        CommandLine commandLine = createCommandLine(new String[] 
{"--output-file", fileName});
         OutputFileConfig configuration = new OutputFileConfig();
         ArgumentContext ctxt = new ArgumentContext(new File("."), 
configuration, commandLine);
         Arg.processArgs(ctxt);
-        assertEquals(expected.getAbsolutePath(), 
configuration.actual.getAbsolutePath());
+        
assertThat(configuration.actual.getAbsolutePath()).isEqualTo(expected.getCanonicalPath());
     }
 }
diff --git 
a/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java 
b/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
index d5e70ed7..29d77e96 100644
--- a/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
+++ b/apache-rat-plugin/src/main/java/org/apache/rat/mp/AbstractRatMojo.java
@@ -105,21 +105,21 @@ public abstract class AbstractRatMojo extends BaseRatMojo 
{
 
     /**
      * Whether to add the default list of license matchers.
-     * @deprecated @deprecated Use specific configuration under 
&lt;configuration&gt;.
+     * @deprecated Use specific configuration under &lt;configuration&gt;.
      */
     @Deprecated
     @Parameter(property = "rat.addDefaultLicenseMatchers")
     private boolean addDefaultLicenseMatchers;
 
     /** The list of approved licenses
-     * @deprecated @deprecated Use specific configuration under 
&lt;configuration&gt;.
+     * @deprecated Use specific configuration under &lt;configuration&gt;.
      */
     @Deprecated
-    @Parameter(required = false)
+    @Parameter
     private String[] approvedLicenses;
 
     /** The file of approved licenses
-     * @deprecated @deprecated Use specific configuration under 
&lt;configuration&gt;.
+     * @deprecated Use specific configuration under &lt;configuration&gt;.
      */
     @Deprecated
     @Parameter(property = "rat.approvedFile")
diff --git 
a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java 
b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
index cc465da3..6d23f061 100644
--- 
a/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
+++ 
b/apache-rat-tasks/src/test/java/org/apache/rat/anttasks/ReportOptionTest.java
@@ -81,7 +81,7 @@ public class ReportOptionTest  {
             super(BaseAntTask.unsupportedArgs(), testPath.toFile());
         }
 
-        protected ReportConfiguration generateConfig(List<Pair<Option, 
String[]>> args) {
+        protected final ReportConfiguration generateConfig(List<Pair<Option, 
String[]>> args) {
             BuildTask task = args.get(0).getKey() == null ? new BuildTask() : 
new BuildTask(args.get(0).getKey());
             task.setUp(args);
             task.buildRule.executeTarget(task.name);

Reply via email to