From 4a4f32d3292e4876d38170e9bf44033d66bc6263 Mon Sep 17 00:00:00 2001 From: Peter Palaga Date: Tue, 26 Feb 2019 22:10:14 +0100 Subject: [PATCH] Fix #298 Add removeOrphanLicenseFiles param to AbstractDownloadLicensesMojo --- src/it/ISSUE-197/invoker.properties | 2 +- .../licenses-delete-orphans.expected.xml | 39 +++++++++++ src/it/download-licenses-configured/pom.xml | 19 ++++++ .../postbuild.groovy | 19 ++++++ .../licenses-config-delete-orphans.xml | 41 ++++++++++++ .../delete-orphans/licenses.xml | 51 +++++++++++++++ .../apache-license-2.0-license-2.0.txt | 1 + .../licenses/bsd-3-clause-asm-license.txt | 1 + .../licenses/foo-bar-license.txt | 1 + .../license/AbstractDownloadLicensesMojo.java | 64 +++++++++++++++++-- 10 files changed, 230 insertions(+), 8 deletions(-) create mode 100644 src/it/download-licenses-configured/licenses-delete-orphans.expected.xml create mode 100644 src/it/download-licenses-configured/src/license/licenses-config-delete-orphans.xml create mode 100644 src/it/download-licenses-configured/target-initial/delete-orphans/licenses.xml create mode 100644 src/it/download-licenses-configured/target-initial/delete-orphans/licenses/apache-license-2.0-license-2.0.txt create mode 100644 src/it/download-licenses-configured/target-initial/delete-orphans/licenses/bsd-3-clause-asm-license.txt create mode 100644 src/it/download-licenses-configured/target-initial/delete-orphans/licenses/foo-bar-license.txt diff --git a/src/it/ISSUE-197/invoker.properties b/src/it/ISSUE-197/invoker.properties index 457dd91ad..a8e497e83 100644 --- a/src/it/ISSUE-197/invoker.properties +++ b/src/it/ISSUE-197/invoker.properties @@ -1 +1 @@ -invoker.goals = license:download-licenses +invoker.goals = license:download-licenses -e diff --git a/src/it/download-licenses-configured/licenses-delete-orphans.expected.xml b/src/it/download-licenses-configured/licenses-delete-orphans.expected.xml new file mode 100644 index 000000000..6e759689b --- /dev/null +++ b/src/it/download-licenses-configured/licenses-delete-orphans.expected.xml @@ -0,0 +1,39 @@ + + + + + aopalliance + aopalliance + 1.0 + + + Public Domain + + + + + asm + asm + 3.1 + + + BSD 3-Clause ASM + https://gitlab.ow2.org/asm/asm/raw/ASM_3_1_MVN/LICENSE.txt + bsd-3-clause-asm-license.txt + + + + + commons-logging + commons-logging + 1.0 + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + apache-license-2.0-license-2.0.txt + + + + + diff --git a/src/it/download-licenses-configured/pom.xml b/src/it/download-licenses-configured/pom.xml index 39e94ee37..2e3584a21 100644 --- a/src/it/download-licenses-configured/pom.xml +++ b/src/it/download-licenses-configured/pom.xml @@ -108,6 +108,25 @@ + + delete-orphans + validate + + download-licenses + + + ${basedir}/src/license/licenses-config-delete-orphans.xml + ${project.build.directory}/delete-orphans/licenses + ${project.build.directory}/delete-orphans/licenses.xml + true + + + [\s-_]+ + - + + + + insert-versions validate diff --git a/src/it/download-licenses-configured/postbuild.groovy b/src/it/download-licenses-configured/postbuild.groovy index acecd2710..320264316 100644 --- a/src/it/download-licenses-configured/postbuild.groovy +++ b/src/it/download-licenses-configured/postbuild.groovy @@ -80,6 +80,25 @@ return { assert Files.exists(bsdAsm) assert bsdAsm.text.contains('Fake content') + final Path expectedLicensesXml = basePath.resolve('licenses-'+ id +'.expected.xml') + final Path licensesXml = outputBase.resolve('licenses.xml') + assert expectedLicensesXml.text.equals(licensesXml.text) + return true +}() && { + final String id = 'delete-orphans' + final Path outputBase = basePath.resolve('target/' + id) + + final Path asl2 = outputBase.resolve('licenses/apache-license-2.0-license-2.0.txt') + assert Files.exists(asl2) + assert asl2.text.contains('Fake content') + + final Path bsdAsm = outputBase.resolve('licenses/bsd-3-clause-asm-license.txt') + assert Files.exists(bsdAsm) + assert bsdAsm.text.contains('Fake content') + + final Path fooBar = outputBase.resolve('licenses/foo-bar-license.txt') + assert !Files.exists(fooBar) + final Path expectedLicensesXml = basePath.resolve('licenses-'+ id +'.expected.xml') final Path licensesXml = outputBase.resolve('licenses.xml') assert expectedLicensesXml.text.equals(licensesXml.text) diff --git a/src/it/download-licenses-configured/src/license/licenses-config-delete-orphans.xml b/src/it/download-licenses-configured/src/license/licenses-config-delete-orphans.xml new file mode 100644 index 000000000..f38518e52 --- /dev/null +++ b/src/it/download-licenses-configured/src/license/licenses-config-delete-orphans.xml @@ -0,0 +1,41 @@ + + + + + \Qcommons-logging + \Qcommons-logging + + + + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + \Qaopalliance\E + \Qaopalliance\E + + + \QPublic Domain\E + + + + + + \Qasm\E + \Qasm\E + + + + + + BSD 3-Clause ASM + https://gitlab.ow2.org/asm/asm/raw/ASM_3_1_MVN/LICENSE.txt + + + + + diff --git a/src/it/download-licenses-configured/target-initial/delete-orphans/licenses.xml b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses.xml new file mode 100644 index 000000000..e2981e2c0 --- /dev/null +++ b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses.xml @@ -0,0 +1,51 @@ + + + + + aopalliance + aopalliance + 1.0 + + + Public Domain + + + + + asm + asm + 3.1 + + + BSD 3-Clause ASM + https://gitlab.ow2.org/asm/asm/raw/ASM_3_1_MVN/LICENSE.txt + bsd-3-clause-asm-license.txt + + + + + foo + bar + 1.2.3 + + + The Foo Bar License v42 + https://foo.bar/LICENSE.txt + foo-bar-license.txt + + + + + commons-logging + commons-logging + 1.0 + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + apache-license-2.0-license-2.0.txt + + + + + diff --git a/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/apache-license-2.0-license-2.0.txt b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/apache-license-2.0-license-2.0.txt new file mode 100644 index 000000000..c5ad8e998 --- /dev/null +++ b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/apache-license-2.0-license-2.0.txt @@ -0,0 +1 @@ +Fake content that should not get overwritten without forceDownload=true \ No newline at end of file diff --git a/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/bsd-3-clause-asm-license.txt b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/bsd-3-clause-asm-license.txt new file mode 100644 index 000000000..c5ad8e998 --- /dev/null +++ b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/bsd-3-clause-asm-license.txt @@ -0,0 +1 @@ +Fake content that should not get overwritten without forceDownload=true \ No newline at end of file diff --git a/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/foo-bar-license.txt b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/foo-bar-license.txt new file mode 100644 index 000000000..eff553079 --- /dev/null +++ b/src/it/download-licenses-configured/target-initial/delete-orphans/licenses/foo-bar-license.txt @@ -0,0 +1 @@ +Should be deleted due to removeOrphanLicenseFiles=true diff --git a/src/main/java/org/codehaus/mojo/license/AbstractDownloadLicensesMojo.java b/src/main/java/org/codehaus/mojo/license/AbstractDownloadLicensesMojo.java index 839c2de86..5d135738a 100644 --- a/src/main/java/org/codehaus/mojo/license/AbstractDownloadLicensesMojo.java +++ b/src/main/java/org/codehaus/mojo/license/AbstractDownloadLicensesMojo.java @@ -56,6 +56,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -202,11 +203,29 @@ public abstract class AbstractDownloadLicensesMojo * {@code cleanLicensesOutputDirectory = true} is not implied by {@link #forceDownload} because users may have * other files there in {@link #licensesOutputDirectory} that were not downloaded by the plugin. * + * @see #removeOrphanLicenseFiles * @since 1.18 */ @Parameter( property = "license.cleanLicensesOutputDirectory", defaultValue = "false" ) private boolean cleanLicensesOutputDirectory; + /** + * If {@code true} the files referenced from {@link AbstractLicensesXmlMojo#licensesOutputFile} before executing + * the mojo but not referenced from {@link AbstractLicensesXmlMojo#licensesOutputFile} after executing + * the mojo will be deleted; otherwise neither before:after diffing nor any file deletions will happen. + *

+ * Compared to {@link #cleanLicensesOutputDirectory} that removes all files from {@link #licensesOutputDirectory} + * before downloading all licenses anew, the {@link #removeOrphanLicenseFiles} removes only files that + * are certainly not needed anymore, e.g. due to a removal of a dependency. {@link #removeOrphanLicenseFiles} thus + * allows to avoid downloading the license files of dependencies that were downloaded in the past and are still + * available in {@link #licensesOutputDirectory}. + * + * @see #cleanLicensesOutputDirectory + * @since 1.19 + */ + @Parameter( property = "license.removeOrphanLicenseFiles", defaultValue = "true" ) + private boolean removeOrphanLicenseFiles; + /** * A file containing dependencies whose licenses could not be downloaded for some reason. The format is similar to * {@link #licensesOutputFile} but the entries in {@link #licensesErrorsFile} have {@code } @@ -581,6 +600,7 @@ public abstract class AbstractDownloadLicensesMojo private int downloadErrorCount = 0; private ArtifactFilters artifactFilters; + private final Set orphanFileNames = new HashSet<>(); protected abstract boolean isSkip(); @@ -636,15 +656,19 @@ public void execute() for ( ProjectLicense lic : dep.getLicenses() ) { final String fileName = lic.getFile(); - final String url = lic.getUrl(); - if ( fileName != null && url != null ) + if ( fileName != null ) { - final File file = new File( licensesOutputDirectory, fileName ); - if ( file.exists() ) + orphanFileNames.add( fileName ); + final String url = lic.getUrl(); + if ( url != null ) { - final LicenseDownloadResult entry = - LicenseDownloadResult.success( file, FileUtil.sha1( file.toPath() ), false ); - cache.put( url, entry ); + final File file = new File( licensesOutputDirectory, fileName ); + if ( file.exists() ) + { + final LicenseDownloadResult entry = + LicenseDownloadResult.success( file, FileUtil.sha1( file.toPath() ), false ); + cache.put( url, entry ); + } } } } @@ -708,6 +732,8 @@ public void execute() { writeLicenseSummary( depProjectLicensesWithErrors, licensesErrorsFile, writeVersions ); } + + removeOrphanFiles( depProjectLicenses ); } catch ( Exception e ) { @@ -736,6 +762,30 @@ public void execute() } } + private void removeOrphanFiles( List deps ) + { + if ( removeOrphanLicenseFiles ) + { + for ( ProjectLicenseInfo dep : deps ) + { + for ( ProjectLicense lic : dep.getLicenses() ) + { + orphanFileNames.remove( lic.getFile() ); + } + } + + for ( String fileName : orphanFileNames ) + { + final File file = new File( licensesOutputDirectory, fileName ); + if ( file.exists() ) + { + getLog().info( "Removing orphan license file \"" + file + "\"" ); + file.delete(); + } + } + } + } + /** * Removes from the given {@code depProjectLicenses} those elements which have non-empty * {@link ProjectLicenseInfo#getDownloaderMessages()} and adds those to the resulting {@link List}.