r1755 - in trunk/src: it it/add-third-party it/add-third-party/no-deps it/add-third-party/with-deps main/java/org/nuiton/license/plugin site/apt
Author: tchemit Date: 2010-04-16 13:56:15 +0200 (Fri, 16 Apr 2010) New Revision: 1755 Log: - Evolution #532: Uniformize add-third-party mojo to update-project-license - Evolution #533: Use apt documentation rather than rst one to avoid cyclic dependencies Added: trunk/src/it/add-third-party/ trunk/src/it/add-third-party/no-deps/ trunk/src/it/add-third-party/no-deps/invoker.properties trunk/src/it/add-third-party/no-deps/pom.xml trunk/src/it/add-third-party/no-deps/verify.groovy trunk/src/it/add-third-party/with-deps/ trunk/src/it/add-third-party/with-deps/invoker.properties trunk/src/it/add-third-party/with-deps/pom.xml trunk/src/it/add-third-party/with-deps/verify.groovy trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java Removed: trunk/src/it/add-third-party-file/ Modified: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyFileMojo.java trunk/src/main/java/org/nuiton/license/plugin/UpdateFileHeaderMojo.java trunk/src/site/apt/descriptor.apt trunk/src/site/apt/header.apt Added: trunk/src/it/add-third-party/no-deps/invoker.properties =================================================================== --- trunk/src/it/add-third-party/no-deps/invoker.properties (rev 0) +++ trunk/src/it/add-third-party/no-deps/invoker.properties 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,21 @@ +# A comma or space separated list of goals/phases to execute, may +# specify an empty list to execute the default goal of the IT project +invoker.goals=clean compile + +# Optionally, a list of goals to run during further invocations of Maven +#invoker.goals.2=${project.groupId}:${project.artifactId}:${project.version}:run + +# A comma or space separated list of profiles to activate +#invoker.profiles=run-all run-once + +# The value for the environment variable MAVEN_OPTS +#invoker.mavenOpts=-Dfile.encoding=UTF-16 -Xms32m -Xmx256m + +# Possible values are "fail-fast" (default), "fail-at-end" and "fail-never" +invoker.failureBehavior=fail-at-end + +# The expected result of the build, possible values are "success" (default) and "failure" +#invoker.buildResult=success + +# A boolean value controlling the -N flag, defaults to "false" +#invoker.nonRecursive=false Property changes on: trunk/src/it/add-third-party/no-deps/invoker.properties ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/it/add-third-party/no-deps/pom.xml =================================================================== --- trunk/src/it/add-third-party/no-deps/pom.xml (rev 0) +++ trunk/src/it/add-third-party/no-deps/pom.xml 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <groupId>org.nuiton.license.test</groupId> + <artifactId>test-add-third-party</artifactId> + <version>@pom.version@</version> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>License Test :: add-third-party</name> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <license.generateBundle>true</license.generateBundle> + <license.verbose>true</license.verbose> + </properties> + <build> + + <plugins> + + <plugin> + <groupId>org.nuiton</groupId> + <artifactId>maven-license-plugin</artifactId> + <version>@pom.version@</version> + <executions> + <execution> + <goals> + <goal>add-third-party</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> + + Property changes on: trunk/src/it/add-third-party/no-deps/pom.xml ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/it/add-third-party/no-deps/verify.groovy =================================================================== --- trunk/src/it/add-third-party/no-deps/verify.groovy (rev 0) +++ trunk/src/it/add-third-party/no-deps/verify.groovy 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,24 @@ + +file = new File(basedir, 'target/generated-sources/license/THIRD-PARTY.txt'); +assert file.exists(); +content = file.text; +assert content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/generated-sources/license/META-INF/test-add-third-party-THIRD-PARTY.txt'); +assert file.exists(); +content = file.text; +assert content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/classes/THIRD-PARTY.txt'); +assert file.exists(); + +content = file.text; +assert content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/classes/META-INF/test-add-third-party-THIRD-PARTY.txt'); +assert file.exists(); + +content = file.text; +assert content.contains( 'the project has no dependencies.' ); + +return true; Property changes on: trunk/src/it/add-third-party/no-deps/verify.groovy ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/it/add-third-party/with-deps/invoker.properties =================================================================== --- trunk/src/it/add-third-party/with-deps/invoker.properties (rev 0) +++ trunk/src/it/add-third-party/with-deps/invoker.properties 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,21 @@ +# A comma or space separated list of goals/phases to execute, may +# specify an empty list to execute the default goal of the IT project +invoker.goals=clean compile + +# Optionally, a list of goals to run during further invocations of Maven +#invoker.goals.2=${project.groupId}:${project.artifactId}:${project.version}:run + +# A comma or space separated list of profiles to activate +#invoker.profiles=run-all run-once + +# The value for the environment variable MAVEN_OPTS +#invoker.mavenOpts=-Dfile.encoding=UTF-16 -Xms32m -Xmx256m + +# Possible values are "fail-fast" (default), "fail-at-end" and "fail-never" +invoker.failureBehavior=fail-at-end + +# The expected result of the build, possible values are "success" (default) and "failure" +#invoker.buildResult=success + +# A boolean value controlling the -N flag, defaults to "false" +#invoker.nonRecursive=false Property changes on: trunk/src/it/add-third-party/with-deps/invoker.properties ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/it/add-third-party/with-deps/pom.xml =================================================================== --- trunk/src/it/add-third-party/with-deps/pom.xml (rev 0) +++ trunk/src/it/add-third-party/with-deps/pom.xml 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <groupId>org.nuiton.license.test</groupId> + <artifactId>test-add-third-party</artifactId> + <version>@pom.version@</version> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + + <name>License Test :: add-third-party</name> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + + <packaging>jar</packaging> + + <properties> + + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <license.thirdPartyFilename>third.txt</license.thirdPartyFilename> + <license.bundleThirdPartyPath>test/third.txt</license.bundleThirdPartyPath> + <license.generateBundle>true</license.generateBundle> + <license.verbose>true</license.verbose> + </properties> + + <dependencies> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.1.1</version> + </dependency> + </dependencies> + <build> + + <plugins> + + <plugin> + <groupId>org.nuiton</groupId> + <artifactId>maven-license-plugin</artifactId> + <version>@pom.version@</version> + <executions> + <execution> + <goals> + <goal>add-third-party</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> + + Property changes on: trunk/src/it/add-third-party/with-deps/pom.xml ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Added: trunk/src/it/add-third-party/with-deps/verify.groovy =================================================================== --- trunk/src/it/add-third-party/with-deps/verify.groovy (rev 0) +++ trunk/src/it/add-third-party/with-deps/verify.groovy 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,22 @@ + +file = new File(basedir, 'target/generated-sources/license/third.txt'); +assert file.exists(); +content = file.text; +assert !content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/generated-sources/license/test/third.txt'); +assert file.exists(); +content = file.text; +assert !content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/classes/third.txt'); +assert file.exists(); +content = file.text; +assert !content.contains( 'the project has no dependencies.' ); + +file = new File(basedir, 'target/classes/test/third.txt'); +assert file.exists(); +content = file.text; +assert !content.contains( 'the project has no dependencies.' ); + +return true; Property changes on: trunk/src/it/add-third-party/with-deps/verify.groovy ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Modified: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyFileMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyFileMojo.java 2010-04-16 10:47:43 UTC (rev 1754) +++ trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyFileMojo.java 2010-04-16 11:56:15 UTC (rev 1755) @@ -25,394 +25,11 @@ package org.nuiton.license.plugin; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.factory.ArtifactFactory; -import org.apache.maven.artifact.metadata.ArtifactMetadataSource; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactCollector; -import org.apache.maven.artifact.resolver.filter.ArtifactFilter; -import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; -import org.apache.maven.model.License; -import org.apache.maven.project.MavenProject; -import org.apache.maven.project.MavenProjectBuilder; -import org.apache.maven.project.ProjectBuildingException; -import org.apache.maven.shared.dependency.tree.DependencyNode; -import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; -import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; -import org.nuiton.plugin.PluginHelper; - -import java.io.File; -import java.util.List; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; - /** - * Le goal pour copier le fichier THIRD-PARTY.txt (contenant les licenses de - * toutes les dependances du projet) dans le classpath (et le generer s'il - * n'existe pas). - * * @author tchemit <chemit@codelutin.com> - * @goal add-third-party - * @phase generate-resources - * @requiresDependencyResolution test - * @requiresProject true + * @deprecated since 2.2, use instead the {@link AddThirdPartyMojo} class. */ -public class AddThirdPartyFileMojo extends AbstractLicenseMojo { +@Deprecated +public class AddThirdPartyFileMojo extends AddThirdPartyMojo { - private static final String unknownLicenseMessage = "Unknown license"; - - /** - * Fichier ou ecrire les licences des dependances. - * - * @parameter expression="${license.thirdPartyFilename}" - * default-value="THIRD-PARTY.txt" - * @required - * @since 1.0.0 - */ - protected String thirdPartyFilename; - - /** - * Repertoire de sortie des classes (classpath). - * - * @parameter expression="${license.outputDirectory}" default-value="target/generated-sources/license" - * @required - * @since 1.0.0 - */ - protected File outputDirectory; - - /** - * Un flag pour forcer la generation. - * - * @parameter expression="${license.force}" default-value="false" - * @since 1.0.0 - */ - protected boolean force; - - /** - * Un flag pour conserver un backup des fichiers modifies. - * - * @parameter expression="${license.keepBackup}" default-value="false" - * @since 1.0.0 - */ - protected boolean keepBackup; - - /** - * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de - * l'artifact). - * - * @parameter expression="${license.generateBundle}" default-value="false" - * @since 1.0.0 - * @deprecated since 2.2 (use instead {@code generateBundle} - */ - @Deprecated - protected boolean copyToMETA_INF; - - /** - * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de - * l'artifact). - * - * @parameter expression="${license.generateBundle}" default-value="false" - * @since 1.0.0 - */ - protected boolean generateBundle; - - /** - * Local Repository. - * - * @parameter expression="${localRepository}" - * @required - * @readonly - * @since 1.0.0 - */ - protected ArtifactRepository localRepository; - - /** - * Remote repositories used for the project. - * - * @parameter expression="${project.remoteArtifactRepositories}" - * @required - * @readonly - * @since 1.0.0 - */ - protected List<?> remoteRepositories; - - /** - * Dependency tree builder component. - * - * @component - */ - protected DependencyTreeBuilder dependencyTreeBuilder; - - /** - * Artifact Factory component. - * - * @component - */ - protected ArtifactFactory factory; - - /** - * Artifact metadata source component. - * - * @component - */ - protected ArtifactMetadataSource artifactMetadataSource; - - /** - * Artifact collector component. - * - * @component - */ - protected ArtifactCollector collector; - - /** - * Maven Project Builder component. - * - * @component - */ - protected MavenProjectBuilder mavenProjectBuilder; - - /** - * content of third party file (only computed if {@link #force} is active or - * the {@link #thirdPartyFile} does not exist, or is not up-to-date. - */ - protected String thirdPartyFileContent; - - protected File thirdPartyFile; - - @Override - protected boolean checkPackaging() { - return rejectPackaging(Packaging.pom); - } - - boolean doGenerate; - - @Override - protected void init() throws Exception { - if (getLog().isDebugEnabled()) { - - // always be verbose in debug mode - setVerbose(true); - } - - if (copyToMETA_INF) { - generateBundle = true; - } - - doGenerate = true; - thirdPartyFile = new File(outputDirectory, thirdPartyFilename); - - if (!force) { - // regenerate only if file exists and is newer than pom file - doGenerate = !isFileNewerThanPomFile(thirdPartyFile); - } - - if (doGenerate) { - - // prepare thirdPartyFileContent - - DependencyNode dependencyTreeNode = resolveProject(); - - LicenseMap licenseMap = new LicenseMap(); - - for (Object o : dependencyTreeNode.getChildren()) { - - buildLicenseMap((DependencyNode) o, licenseMap); - } - - thirdPartyFileContent = buildGroupedLicenses(licenseMap); - - // log dependencies with no license - SortedSet<String> dependenciesWithNoLicense = - licenseMap.get(unknownLicenseMessage); - if (dependenciesWithNoLicense != null) { - for (String dep : dependenciesWithNoLicense) { - // no license found for the dependency - getLog().warn("no license found for dependency " + dep); - } - } - } else { - thirdPartyFileContent = PluginHelper.readAsString(thirdPartyFile, getEncoding()); - } - } - - @Override - protected void doAction() throws Exception { - if (doGenerate) { - if (isVerbose()) { - getLog().info("writing third-party file : " + thirdPartyFile); - } - if (keepBackup && thirdPartyFile.exists()) { - if (isVerbose()) { - getLog().info("backup " + thirdPartyFile); - } - backupFile(thirdPartyFile); - } - writeFile(thirdPartyFile, thirdPartyFileContent, getEncoding()); - } - if (generateBundle) { - copyFile(thirdPartyFile, new File( - outputDirectory, - "META-INF" + File.separator + getProject().getArtifactId() + - "-" + thirdPartyFile.getName()) - ); - } - addResourceDir(outputDirectory, "**/*.txt"); - } - - /** @return resolve the dependency tree */ - protected DependencyNode resolveProject() { - try { - ArtifactFilter artifactFilter = - new ScopeArtifactFilter(Artifact.SCOPE_TEST); - return dependencyTreeBuilder.buildDependencyTree( - getProject(), - localRepository, - factory, - artifactMetadataSource, - artifactFilter, - collector - ); - } catch (DependencyTreeBuilderException e) { - getLog().error("Unable to build dependency tree.", e); - return null; - } - } - - protected void buildLicenseMap(DependencyNode node, LicenseMap licenseMap) { - if (node.getState() != DependencyNode.INCLUDED) { - // this dependency is not included, so do not treate it - if (isVerbose()) { - getLog().info("do not include this dependency " + - node.toNodeString()); - } - return; - } - Artifact artifact = node.getArtifact(); - - if (isVerbose() && getLog().isDebugEnabled()) { - getLog().debug("treate node " + node.toNodeString()); - } - - if (!Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) { - try { - MavenProject artifactProject = - getMavenProjectFromRepository(artifact); - String artifactName = getArtifactName(artifactProject); - - List<?> licenses = artifactProject.getLicenses(); - - if (licenses.isEmpty()) { - // no license found for the dependency - licenseMap.put(unknownLicenseMessage, artifactName); - - } else { - for (Object o : licenses) { - if (o == null) { - getLog().warn("could not acquire the license for " - + artifactName); - continue; - } - License license = (License) o; - String licenseKey = license.getName(); - if (license.getName() == null) { - licenseKey = license.getUrl(); - } - licenseMap.put(licenseKey, artifactName); - } - } - } catch (ProjectBuildingException e) { - getLog().error("ProjectBuildingException error : ", e); - } - } - if (!node.getChildren().isEmpty()) { - for (Object o : node.getChildren()) { - buildLicenseMap((DependencyNode) o, licenseMap); - } - } - } - - protected String buildGroupedLicenses(LicenseMap licenseMap) { - StringBuilder sb = new StringBuilder(); - sb.append("List of third-party dependencies grouped by " + - "their license type."); - for (String licenseName : licenseMap.keySet()) { - sb.append("\n\n").append(licenseName).append(" : "); - - SortedSet<String> projects = licenseMap.get(licenseName); - - for (String projectName : projects) { - sb.append("\n * ").append(projectName); - } - } - return sb.toString(); - } - - protected String getArtifactName(MavenProject artifactProject) { - StringBuilder sb = new StringBuilder(); - - sb.append(artifactProject.getName()); - sb.append(" ("); - sb.append(artifactProject.getGroupId()); - sb.append(":"); - sb.append(artifactProject.getArtifactId()); - sb.append(":"); - sb.append(artifactProject.getVersion()); - sb.append(" - "); - String url = artifactProject.getUrl(); - sb.append(url == null ? "no url defined" : url); - sb.append(")"); - - return sb.toString(); - } - - /** - * Get the <code>Maven project</code> from the repository depending the - * <code>Artifact</code> given. - * - * @param artifact an artifact - * @return the Maven project for the given artifact - * @throws ProjectBuildingException if any - */ - protected MavenProject getMavenProjectFromRepository(Artifact artifact) - throws ProjectBuildingException { - - boolean allowStubModel = false; - - if (!"pom".equals(artifact.getType())) { - artifact = factory.createProjectArtifact( - artifact.getGroupId(), - artifact.getArtifactId(), - artifact.getVersion(), - artifact.getScope() - ); - allowStubModel = true; - } - - // TODO: we should use the MavenMetadataSource instead - return mavenProjectBuilder.buildFromRepository( - artifact, - remoteRepositories, - localRepository, - allowStubModel - ); - } - - protected class LicenseMap extends TreeMap<String, SortedSet<String>> { - - private static final long serialVersionUID = 864199843545688069L; - - public SortedSet<String> put(String key, String value) { - // handle multiple values as a set to avoid duplicates - SortedSet<String> valueList = get(key); - if (valueList == null) { - valueList = new TreeSet<String>(); - } - if (getLog().isDebugEnabled()) { - getLog().debug("key:" + key + ",value: " + value); - } - valueList.add(value); - return put(key, valueList); - } - } } Added: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java (rev 0) +++ trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java 2010-04-16 11:56:15 UTC (rev 1755) @@ -0,0 +1,515 @@ +/* + * #%L + * Maven License Plugin + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.license.plugin; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactCollector; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; +import org.apache.maven.model.License; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectBuilder; +import org.apache.maven.project.ProjectBuildingException; +import org.apache.maven.shared.dependency.tree.DependencyNode; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; +import org.nuiton.plugin.PluginHelper; + +import java.io.File; +import java.util.*; + +/** + * Le goal pour copier le fichier THIRD-PARTY.txt (contenant les licenses de + * toutes les dependances du projet) dans le classpath (et le generer s'il + * n'existe pas). + * + * @author tchemit <chemit@codelutin.com> + * @goal add-third-party + * @phase generate-resources + * @requiresDependencyResolution test + * @requiresProject true + * @since 2.2 (was previously {@code AddThirdPartyFileMojo}). + */ +public class AddThirdPartyMojo extends AbstractLicenseMojo { + + private static final String unknownLicenseMessage = "Unknown license"; + + /** + * Repertoire de sortie des classes (classpath). + * + * @parameter expression="${license.outputDirectory}" default-value="target/generated-sources/license" + * @required + * @since 1.0.0 + */ + protected File outputDirectory; + + /** + * Fichier ou ecrire les licences des dependances. + * + * @parameter expression="${license.thirdPartyFilename}" + * default-value="THIRD-PARTY.txt" + * @required + * @since 1.0.0 + */ + protected String thirdPartyFilename; + + /** + * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de + * l'artifact). + * + * @parameter expression="${license.generateBundle}" default-value="false" + * @since 1.0.0 + */ + protected boolean generateBundle; + + /** + * The path of the bundled third party file to produce when + * {@link #generateBundle} is on. + * <p/> + * <b>Note:</b> This option is not available for {@code pom} module types. + * + * @parameter expression="${license.bundleThirdPartyPath}" default-value="META-INF/${project.artifactId}-THIRD-PARTY.txt" + * @since 2.2 + */ + protected String bundleThirdPartyPath; + + /** + * Un flag pour forcer la generation. + * + * @parameter expression="${license.force}" default-value="false" + * @since 1.0.0 + */ + protected boolean force; + + /** + * Un flag pour conserver un backup des fichiers modifies. + * + * @parameter expression="${license.keepBackup}" default-value="false" + * @since 1.0.0 + */ + protected boolean keepBackup; + + /** + * Un flag pour faire une copie nommé dans META-INF (prefixe avec le nom de + * l'artifact). + * + * @parameter expression="${license.generateBundle}" default-value="false" + * @since 1.0.0 + * @deprecated since 2.2 (use instead {@code generateBundle}). + */ + @Deprecated + protected boolean copyToMETA_INF; + + /** + * Local Repository. + * + * @parameter expression="${localRepository}" + * @required + * @readonly + * @since 1.0.0 + */ + protected ArtifactRepository localRepository; + + /** + * Remote repositories used for the project. + * + * @parameter expression="${project.remoteArtifactRepositories}" + * @required + * @readonly + * @since 1.0.0 + */ + protected List<?> remoteRepositories; + + /** + * Dependency tree builder component. + * + * @component + */ + protected DependencyTreeBuilder dependencyTreeBuilder; + + /** + * Artifact Factory component. + * + * @component + */ + protected ArtifactFactory factory; + + /** + * Artifact metadata source component. + * + * @component + */ + protected ArtifactMetadataSource artifactMetadataSource; + + /** + * Artifact collector component. + * + * @component + */ + protected ArtifactCollector collector; + + /** + * Maven Project Builder component. + * + * @component + */ + protected MavenProjectBuilder mavenProjectBuilder; + + /** + * content of third party file (only computed if {@link #force} is active or + * the {@link #thirdPartyFile} does not exist, or is not up-to-date. + */ + protected String thirdPartyFileContent; + + protected File thirdPartyFile; + + boolean doGenerate; + + public static final String NO_DEPENDENCIES_MESSAGE = "the project has no dependencies."; + + @Override + protected boolean checkPackaging() { + return rejectPackaging(Packaging.pom); + } + + @Override + protected void init() throws Exception { + if (getLog().isDebugEnabled()) { + + // always be verbose in debug mode + setVerbose(true); + } + + if (copyToMETA_INF) { + getLog().warn("\\n copyToMETA_INF is deprecated, prefer" + + " use the generateBundle parameter\n\n"); + setGenerateBundle(true); + } + + File file = new File(getOutputDirectory(), getThirdPartyFilename()); + + setThirdPartyFile(file); + + setDoGenerate(isForce() || !file.exists() || !isFileNewerThanPomFile(file)); + + String content; + if (isDoGenerate()) { + + if (isVerbose()) { + getLog().info("will generate third-party content..."); + } + + // build thirdPartyFileContent + content = buildThirdPartyFilecontent(); + + } else { + // read it from existing third party file + content = PluginHelper.readAsString(getThirdPartyFile(), getEncoding()); + } + + setThirdPartyFileContent(content); + } + + @Override + protected void doAction() throws Exception { + + File target = getThirdPartyFile(); + if (isDoGenerate()) { + if (isVerbose()) { + getLog().info("writing third-party file : " + target); + } + if (isKeepBackup() && target.exists()) { + if (isVerbose()) { + getLog().info("backup " + target); + } + backupFile(target); + } + writeFile(target, getThirdPartyFileContent(), getEncoding()); + } + File output = getOutputDirectory(); + if (isGenerateBundle()) { + + // creates the bundled license file + File bundleTarget = + PluginHelper.getFile(output, getBundleThirdPartyPath()); + copyFile(target, bundleTarget); + } + addResourceDir(output, "**/*.txt"); + } + + protected String buildThirdPartyFilecontent() throws DependencyTreeBuilderException { + DependencyNode dependencyTreeNode; + ArtifactFilter artifactFilter = + new ScopeArtifactFilter(Artifact.SCOPE_TEST); + dependencyTreeNode = dependencyTreeBuilder.buildDependencyTree( + getProject(), + localRepository, + factory, + artifactMetadataSource, + artifactFilter, + collector + ); + + LicenseMap licenseMap = new LicenseMap(); + + for (Object o : dependencyTreeNode.getChildren()) { + + buildLicenseMap((DependencyNode) o, licenseMap); + } + + // log dependencies with no license + Set<String> unsafeDependencies = + licenseMap.get(getUnknownLicenseMessage()); + + if (unsafeDependencies != null) { + for (String dep : unsafeDependencies) { + // no license found for the dependency + getLog().warn("no license found for dependency " + dep); + } + } + StringBuilder sb = new StringBuilder(); + if (licenseMap.isEmpty()) { + sb.append(NO_DEPENDENCIES_MESSAGE); + } else { + sb.append("List of third-party dependencies grouped by " + + "their license type."); + for (String licenseName : licenseMap.keySet()) { + sb.append("\n\n").append(licenseName).append(" : "); + + SortedSet<String> projects = licenseMap.get(licenseName); + + for (String projectName : projects) { + sb.append("\n * ").append(projectName); + } + } + } + String content = sb.toString(); + if (getLog().isDebugEnabled()) { + getLog().debug("third-party file content :\n" + content); + } + return content; + } + + protected void buildLicenseMap(DependencyNode node, LicenseMap licenseMap) { + if (node.getState() != DependencyNode.INCLUDED) { + // this dependency is not included, so do not treate it + if (isVerbose()) { + getLog().info("do not include this dependency " + + node.toNodeString()); + } + return; + } + Artifact artifact = node.getArtifact(); + + if (isVerbose() && getLog().isDebugEnabled()) { + getLog().debug("treate node " + node.toNodeString()); + } + + if (!Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) { + try { + MavenProject artifactProject = + getMavenProjectFromRepository(artifact); + String artifactName = getArtifactName(artifactProject); + + List<?> licenses = artifactProject.getLicenses(); + + if (licenses.isEmpty()) { + // no license found for the dependency + licenseMap.put(getUnknownLicenseMessage(), artifactName); + + } else { + for (Object o : licenses) { + if (o == null) { + getLog().warn("could not acquire the license for " + + artifactName); + continue; + } + License license = (License) o; + String licenseKey = license.getName(); + if (license.getName() == null) { + licenseKey = license.getUrl(); + } + licenseMap.put(licenseKey, artifactName); + } + } + } catch (ProjectBuildingException e) { + getLog().error("ProjectBuildingException error : ", e); + } + } + if (!node.getChildren().isEmpty()) { + for (Object o : node.getChildren()) { + buildLicenseMap((DependencyNode) o, licenseMap); + } + } + } + + protected String getArtifactName(MavenProject artifactProject) { + StringBuilder sb = new StringBuilder(); + + sb.append(artifactProject.getName()); + sb.append(" ("); + sb.append(artifactProject.getGroupId()); + sb.append(":"); + sb.append(artifactProject.getArtifactId()); + sb.append(":"); + sb.append(artifactProject.getVersion()); + sb.append(" - "); + String url = artifactProject.getUrl(); + sb.append(url == null ? "no url defined" : url); + sb.append(")"); + + return sb.toString(); + } + + /** + * Get the <code>Maven project</code> from the repository depending the + * <code>Artifact</code> given. + * + * @param artifact an artifact + * @return the Maven project for the given artifact + * @throws ProjectBuildingException if any + */ + protected MavenProject getMavenProjectFromRepository(Artifact artifact) + throws ProjectBuildingException { + + boolean allowStubModel = false; + + if (!"pom".equals(artifact.getType())) { + artifact = factory.createProjectArtifact( + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getVersion(), + artifact.getScope() + ); + allowStubModel = true; + } + + // TODO: we should use the MavenMetadataSource instead + return mavenProjectBuilder.buildFromRepository( + artifact, + remoteRepositories, + localRepository, + allowStubModel + ); + } + + public static String getUnknownLicenseMessage() { + return unknownLicenseMessage; + } + + public String getThirdPartyFilename() { + return thirdPartyFilename; + } + + public File getOutputDirectory() { + return outputDirectory; + } + + public boolean isForce() { + return force; + } + + public boolean isKeepBackup() { + return keepBackup; + } + + public boolean isGenerateBundle() { + return generateBundle; + } + + public boolean isDoGenerate() { + return doGenerate; + } + + public String getBundleThirdPartyPath() { + return bundleThirdPartyPath; + } + + public File getThirdPartyFile() { + return thirdPartyFile; + } + + public String getThirdPartyFileContent() { + return thirdPartyFileContent; + } + + public void setThirdPartyFilename(String thirdPartyFilename) { + this.thirdPartyFilename = thirdPartyFilename; + } + + public void setForce(boolean force) { + this.force = force; + } + + public void setOutputDirectory(File outputDirectory) { + this.outputDirectory = outputDirectory; + } + + public void setKeepBackup(boolean keepBackup) { + this.keepBackup = keepBackup; + } + + public void setGenerateBundle(boolean generateBundle) { + this.generateBundle = generateBundle; + } + + public void setBundleThirdPartyPath(String bundleThirdPartyPath) { + this.bundleThirdPartyPath = bundleThirdPartyPath; + } + + public void setThirdPartyFileContent(String thirdPartyFileContent) { + this.thirdPartyFileContent = thirdPartyFileContent; + } + + public void setDoGenerate(boolean doGenerate) { + this.doGenerate = doGenerate; + } + + public void setThirdPartyFile(File thirdPartyFile) { + this.thirdPartyFile = thirdPartyFile; + } + + protected class LicenseMap extends TreeMap<String, SortedSet<String>> { + + private static final long serialVersionUID = 864199843545688069L; + + public SortedSet<String> put(String key, String value) { + // handle multiple values as a set to avoid duplicates + SortedSet<String> valueList = get(key); + if (valueList == null) { + valueList = new TreeSet<String>(); + } + if (getLog().isDebugEnabled()) { + getLog().debug("key:" + key + ",value: " + value); + } + valueList.add(value); + return put(key, valueList); + } + } +} \ No newline at end of file Property changes on: trunk/src/main/java/org/nuiton/license/plugin/AddThirdPartyMojo.java ___________________________________________________________________ Added: svn:keywords + "Author Date Id Revision HeadURL Modified: trunk/src/main/java/org/nuiton/license/plugin/UpdateFileHeaderMojo.java =================================================================== --- trunk/src/main/java/org/nuiton/license/plugin/UpdateFileHeaderMojo.java 2010-04-16 10:47:43 UTC (rev 1754) +++ trunk/src/main/java/org/nuiton/license/plugin/UpdateFileHeaderMojo.java 2010-04-16 11:56:15 UTC (rev 1755) @@ -38,8 +38,8 @@ import java.util.*; /** - * The goal to update (or add) the licence header on some files and also update - * (or add) the project license file. + * The goal to update (or add) the header on some files described in + * {@link #descriptor} file. * <p/> * This goal replace the {@code update-header} goal which can not deal with * Copyright. Modified: trunk/src/site/apt/descriptor.apt =================================================================== --- trunk/src/site/apt/descriptor.apt 2010-04-16 10:47:43 UTC (rev 1754) +++ trunk/src/site/apt/descriptor.apt 2010-04-16 11:56:15 UTC (rev 1755) @@ -43,7 +43,7 @@ xsd - This file is ruled by a {{{./licenseProjectDescriptor-1.0.0.xsd}xsd file}}_. + This file is ruled by a {{{./licenseProjectDescriptor-1.0.0.xsd}xsd file}}. Example Modified: trunk/src/site/apt/header.apt =================================================================== --- trunk/src/site/apt/header.apt 2010-04-16 10:47:43 UTC (rev 1754) +++ trunk/src/site/apt/header.apt 2010-04-16 11:56:15 UTC (rev 1755) @@ -51,11 +51,17 @@ -------------------------------------------------------------------------------- * (1) the start process tag used to detect begin of header (NEVER suppress it). + * (2) Project description section + * (3) Header section delimiter + * (4) Copyright section of the file (see next section for detail) + * (5) Header section delimiter + * (6) License section + * (7) the end process tag used to detect end of header (NEVER suppress it). * Configuration @@ -63,7 +69,9 @@ You can configure those things : * start process tag + * header section delimiter + * end process tag * Copyright model @@ -135,12 +143,12 @@ Ignore a header - If you don't want `update-file-header` goal to treate a specific file, you can - use a specific tag in your class : + If you don't want {{{./update-file-header-mojo.html}update-file-header}} + goal to treate a specific file, you can use a specific tag in your class : -------------------------------------------------------------------------------- %%License-Ignore -------------------------------------------------------------------------------- - You can change it with **ignoreTag** property. \ No newline at end of file + You can change it with <<ignoreTag>> property. \ No newline at end of file
participants (1)
-
tchemit@users.nuiton.org