View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.rat.mp;
20  
21  import java.io.ByteArrayOutputStream;
22  import java.io.File;
23  import java.io.IOException;
24  import java.nio.charset.StandardCharsets;
25  import java.util.List;
26  
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugins.annotations.LifecyclePhase;
30  import org.apache.maven.plugins.annotations.Mojo;
31  import org.apache.maven.plugins.annotations.Parameter;
32  import org.apache.rat.ReportConfiguration;
33  import org.apache.rat.Reporter;
34  import org.apache.rat.commandline.Arg;
35  import org.apache.rat.commandline.StyleSheets;
36  import org.apache.rat.license.LicenseSetFactory.LicenseFilter;
37  import org.apache.rat.report.claim.ClaimStatistic;
38  import org.apache.rat.utils.DefaultLog;
39  
40  import static java.lang.String.format;
41  
42  /**
43   * Run RAT to perform a violation check.
44   * <p>
45   *     This documentation mentions data types for some arguments.
46   * </p>
47   */
48  @Mojo(name = "check", defaultPhase = LifecyclePhase.VALIDATE, threadSafe = true)
49  public class RatCheckMojo extends AbstractRatMojo {
50  
51      /** The default output file if no other is specified.
52       * @deprecated Use &lt;outputFile&gt; instead.
53       */
54      @Deprecated
55      @Parameter(defaultValue = "${project.build.directory}/rat.txt")
56      private File defaultReportFile;
57  
58      /**
59       * Where to store the report.
60       * @deprecated Use 'out' property instead.
61       */
62      @Deprecated
63      @Parameter
64      public void setReportFile(final File reportFile) {
65          if (!reportFile.getParentFile().exists() && !reportFile.getParentFile().mkdirs()) {
66              getLog().error("Unable to create directory " + reportFile.getParentFile());
67          }
68          setOutputFile(reportFile.getAbsolutePath());
69      }
70  
71      /**
72       * Output style of the report. Use "plain" (the default) for a plain text report
73       * or "xml" for the raw XML report. Alternatively you can give the path of an
74       * XSL transformation that will be applied on the raw XML to produce the report
75       * written to the output file.
76       * @deprecated Use setStyleSheet or xml instead.
77       */
78      @Deprecated
79      @Parameter(property = "rat.outputStyle")
80      public void setReportStyle(final String value) {
81          if (value.equalsIgnoreCase("xml")) {
82              setXml(true);
83          } else if (value.equalsIgnoreCase("plain")) {
84              setStylesheet("plain-rat");
85          } else {
86              setStylesheet(value);
87          }
88      }
89  
90      /**
91       * Maximum number of files with unapproved licenses.
92       * @deprecated Use &lt;counterMax&gt;Unapproved:value&lt;/counterMax&gt;.
93       */
94      @Deprecated
95      @Parameter(property = "rat.numUnapprovedLicenses", defaultValue = "0")
96      private int numUnapprovedLicenses;
97  
98      /**
99       * Whether to add license headers; possible values are {@code forced},
100      * {@code true}, and {@code false} (default).
101      * @deprecated Use &lt;editLicense&gt; and &lt;editOverwrite&gt;.
102      */
103     @Deprecated
104     @Parameter(property = "rat.addLicenseHeaders")
105     public void setAddLicenseHeaders(final String addLicenseHeaders) {
106         switch (addLicenseHeaders.trim().toUpperCase()) {
107             case "FALSE":
108                 // do nothing;
109                 break;
110             case "TRUE":
111                 setAddLicense(true);
112                 break;
113             case "FORCED":
114                 setAddLicense(true);
115                 setForce(true);
116                 break;
117             default:
118                 throw new IllegalArgumentException("Unknown addlicense header: " + addLicenseHeaders);
119         }
120     }
121 
122     /**
123      * Copyright message to add to license headers.
124      * @deprecated Deprecated for removal since 0.17: Use &lt;editCopyright&gt; instead.
125      */
126     @Deprecated
127     @Parameter(property = "rat.copyrightMessage")
128     public void setCopyrightMessage(final String copyrightMessage) {
129         setCopyright(copyrightMessage);
130     }
131 
132     /**
133      * Will ignore RAT errors and display a log message if any. Its use is NOT
134      * RECOMMENDED, but quite convenient on occasion.
135      *
136      * @since 0.9
137      */
138     @Parameter(property = "rat.ignoreErrors", defaultValue = "false")
139     private boolean ignoreErrors;
140 
141     /**
142      * Whether to output the names of files that have unapproved licenses to the
143      * console. Defaults to {@code true} to ease builds in containers where you are
144      * unable to access rat.txt easily.
145      *
146      * @since 0.12
147      */
148     @Parameter(property = "rat.consoleOutput", defaultValue = "true")
149     private boolean consoleOutput;
150 
151     /** The reporter that this mojo uses */
152     private Reporter reporter;
153 
154     @Override
155     protected ReportConfiguration getConfiguration() throws MojoExecutionException {
156         ReportConfiguration result = super.getConfiguration();
157         if (numUnapprovedLicenses > 0) {
158             result.getClaimValidator().setMax(ClaimStatistic.Counter.UNAPPROVED, numUnapprovedLicenses);
159         }
160         return result;
161     }
162 
163         /**
164          * Invoked by Maven to execute the Mojo.
165          *
166          * @throws MojoFailureException if an error in the plugin configuration was
167          * detected.
168          * @throws MojoExecutionException if another error occurred while executing the
169          * plugin.
170          */
171     @Override
172     public void execute() throws MojoExecutionException, MojoFailureException {
173         if (skip) {
174             getLog().info("RAT will not execute since it is configured to be skipped via system property 'rat.skip'.");
175             return;
176         }
177 
178         if (getValues(Arg.OUTPUT_FILE).isEmpty()) {
179             setArg(Arg.OUTPUT_FILE.option().getLongOpt(), defaultReportFile.getAbsolutePath());
180         }
181 
182         ReportConfiguration config = getConfiguration();
183 
184         logLicenses(config.getLicenses(LicenseFilter.ALL));
185         try {
186             this.reporter = new Reporter(config);
187             reporter.output();
188             check(config);
189         } catch (MojoFailureException e) {
190             throw e;
191         } catch (Exception e) {
192             throw new MojoExecutionException(e.getMessage(), e);
193         }
194     }
195 
196     protected void check(final ReportConfiguration config) throws MojoFailureException {
197         ClaimStatistic statistics = reporter.getClaimsStatistic();
198         try {
199            reporter.writeSummary(DefaultLog.getInstance().asWriter());
200            if (config.getClaimValidator().hasErrors()) {
201                config.getClaimValidator().logIssues(statistics);
202                if (consoleOutput &&
203                        !config.getClaimValidator().isValid(ClaimStatistic.Counter.UNAPPROVED, statistics.getCounter(ClaimStatistic.Counter.UNAPPROVED))) {
204                    try {
205                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
206                        reporter.output(StyleSheets.UNAPPROVED_LICENSES.getStyleSheet(), () -> baos);
207                        getLog().warn(baos.toString(StandardCharsets.UTF_8.name()));
208                    } catch (Exception e) {
209                        getLog().warn("Unable to print the files with unapproved licenses to the console.");
210                    }
211                }
212 
213                String msg = format("Counter(s) %s exceeded minimum or maximum values. See RAT report in: '%s'.",
214                        String.join(", ", config.getClaimValidator().listIssues(statistics)),
215                        getRatTxtFile());
216 
217                if (!ignoreErrors) {
218                    throw new RatCheckException(msg);
219                } else {
220                    getLog().info(msg);
221                }
222            }
223         } catch (IOException e) {
224            throw new MojoFailureException(e);
225        }
226     }
227 
228     /**
229      * Reads the location of the RAT text file from the Mojo.
230      *
231      * @return Value of the "reportFile" property.
232      * @throws MojoFailureException If no output file was specified.
233      */
234     public File getRatTxtFile() throws MojoFailureException {
235         List<String> args = getValues(Arg.OUTPUT_FILE);
236         if (args != null) {
237             return new File(args.get(0));
238         }
239         throw new MojoFailureException("No output file specified");
240     }
241 }