diff --git a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProvider.java b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProvider.java new file mode 100644 index 000000000..fa8435f37 --- /dev/null +++ b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProvider.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 Mycila (mathieu.carbou@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mycila.maven.plugin.license.git; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import com.mycila.maven.plugin.license.AbstractLicenseMojo; +import com.mycila.maven.plugin.license.PropertiesProvider; +import com.mycila.maven.plugin.license.document.Document; + +/** + * An implementation of {@link PropertiesProvider} that adds {@value #COPYRIGHT_CREATION_AUTHOR_NAME_KEY} and + * {@value #COPYRIGHT_CREATION_AUTHOR_EMAIL_KEY} values - see + * {@link #getAdditionalProperties(AbstractLicenseMojo, Properties, Document)}. + * + * @author masakimu + */ +public class CopyrightAuthorProvider extends GitPropertiesProvider implements PropertiesProvider { + + public static final String COPYRIGHT_CREATION_AUTHOR_NAME_KEY= "license.git.CreationAuthorName"; + public static final String COPYRIGHT_CREATION_AUTHOR_EMAIL_KEY="license.git.CreationAuthorEmail"; + + + public CopyrightAuthorProvider() { + super(); + } + + /** + * Returns an unmodifiable map containing the two entries {@value #COPYRIGHT_CREATION_AUTHOR_NAME_KEY} and {@value #COPYRIGHT_CREATION_AUTHOR_EMAIL_KEY}, + * , whose values are set based on inspecting git history. + * + * + * + */ + public Map getAdditionalProperties(AbstractLicenseMojo mojo, Properties properties, + Document document) { + + try { + Map result = new HashMap(3); + GitLookup gitLookup = getGitLookup(document.getFile(), properties); + + result.put(COPYRIGHT_CREATION_AUTHOR_NAME_KEY, gitLookup.getAuthorNameOfCreation(document.getFile()) ); + result.put(COPYRIGHT_CREATION_AUTHOR_EMAIL_KEY, gitLookup.getAuthorEmailOfCreation(document.getFile()) ); + return Collections.unmodifiableMap(result); + } catch (Exception e) { + throw new RuntimeException("Could not compute the year of the last git commit for file " + + document.getFile().getAbsolutePath(), e); + } + } + + + +} diff --git a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightRangeProvider.java b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightRangeProvider.java index f831dc213..0f24de6b5 100644 --- a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightRangeProvider.java +++ b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/CopyrightRangeProvider.java @@ -15,19 +15,14 @@ */ package com.mycila.maven.plugin.license.git; -import java.io.File; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.Properties; -import java.util.TimeZone; import com.mycila.maven.plugin.license.AbstractLicenseMojo; import com.mycila.maven.plugin.license.PropertiesProvider; import com.mycila.maven.plugin.license.document.Document; -import com.mycila.maven.plugin.license.git.GitLookup.DateSource; /** * An implementation of {@link PropertiesProvider} that adds {@value #COPYRIGHT_LAST_YEAR_KEY} and @@ -36,17 +31,13 @@ * * @author Peter Palaga */ -public class CopyrightRangeProvider implements PropertiesProvider { +public class CopyrightRangeProvider extends GitPropertiesProvider implements PropertiesProvider { public static final String COPYRIGHT_LAST_YEAR_KEY = "license.git.copyrightLastYear"; public static final String COPYRIGHT_CREATION_YEAR_KEY = "license.git.copyrightCreationYear"; - public static final String COPYRIGHT_LAST_YEAR_MAX_COMMITS_LOOKUP_KEY = "license.git.copyrightLastYearMaxCommitsLookup"; - public static final String COPYRIGHT_LAST_YEAR_SOURCE_KEY = "license.git.copyrightLastYearSource"; - public static final String COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY = "license.git.copyrightLastYearTimeZone"; public static final String COPYRIGHT_YEARS_KEY = "license.git.copyrightYears"; public static final String INCEPTION_YEAR_KEY = "project.inceptionYear"; - - private volatile GitLookup gitLookup; + public CopyrightRangeProvider() { super(); @@ -84,7 +75,7 @@ public Map getAdditionalProperties(AbstractLicenseMojo mojo, Pro + document.getFile().getAbsolutePath()); } try { - Map result = new HashMap(3); + Map result = new HashMap(4); GitLookup gitLookup = getGitLookup(document.getFile(), properties); int copyrightEnd = gitLookup.getYearOfLastChange(document.getFile()); result.put(COPYRIGHT_LAST_YEAR_KEY, Integer.toString(copyrightEnd)); @@ -104,50 +95,4 @@ public Map getAdditionalProperties(AbstractLicenseMojo mojo, Pro + document.getFile().getAbsolutePath(), e); } } - - /** - * Lazily initializes #gitLookup assuming that all subsequent calls to this method will be related to the same - * git repository. - * - * @param file - * @return - * @throws IOException - */ - private GitLookup getGitLookup(File file, Properties props) throws IOException { - if (gitLookup == null) { - synchronized (this) { - if (gitLookup == null) { - String dateSourceString = props.getProperty(COPYRIGHT_LAST_YEAR_SOURCE_KEY, - DateSource.AUTHOR.name()); - DateSource dateSource = DateSource.valueOf(dateSourceString.toUpperCase(Locale.US)); - String checkCommitsCountString = props.getProperty(COPYRIGHT_LAST_YEAR_MAX_COMMITS_LOOKUP_KEY); - int checkCommitsCount = GitLookup.DEFAULT_COMMITS_COUNT; - if (checkCommitsCountString != null) { - checkCommitsCountString = checkCommitsCountString.trim(); - checkCommitsCount = Integer.parseInt(checkCommitsCountString); - } - final TimeZone timeZone; - String tzString = props.getProperty(COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY); - switch (dateSource) { - case COMMITER: - timeZone = tzString == null ? GitLookup.DEFAULT_ZONE : TimeZone.getTimeZone(tzString); - break; - case AUTHOR: - if (tzString != null) { - throw new RuntimeException(COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY + " must not be set with " - + COPYRIGHT_LAST_YEAR_SOURCE_KEY + " = " + DateSource.AUTHOR.name() - + " because git author name already contrains time zone information."); - } - timeZone = null; - break; - default: - throw new IllegalStateException("Unexpected " + DateSource.class.getName() + " " + dateSource); - } - gitLookup = new GitLookup(file, dateSource, timeZone, checkCommitsCount); - } - } - } - return gitLookup; - } - } diff --git a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitLookup.java b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitLookup.java index b694393ba..b73636645 100644 --- a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitLookup.java +++ b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitLookup.java @@ -159,6 +159,32 @@ int getYearOfCreation(File file) throws IOException, GitAPIException { walk.dispose(); return commitYear; } + + String getAuthorNameOfCreation(File file) throws IOException, GitAPIException { + String repoRelativePath = pathResolver.relativize(file); + String authorName = ""; + RevWalk walk = getGitRevWalk(repoRelativePath, true); + Iterator iterator = walk.iterator(); + if (iterator.hasNext()) { + RevCommit commit = iterator.next(); + authorName = getAuthorNameFromCommit(commit); + } + walk.dispose(); + return authorName; + } + + String getAuthorEmailOfCreation(File file) throws IOException, GitAPIException { + String repoRelativePath = pathResolver.relativize(file); + String authorEmail = ""; + RevWalk walk = getGitRevWalk(repoRelativePath, true); + Iterator iterator = walk.iterator(); + if (iterator.hasNext()) { + RevCommit commit = iterator.next(); + authorEmail = getAuthorEmailFromCommit(commit); + } + walk.dispose(); + return authorEmail; + } private boolean isFileModifiedOrUnstaged(String repoRelativePath) throws GitAPIException { Status status = new Git(repository).status().addPath(repoRelativePath).call(); @@ -206,4 +232,14 @@ private static int toYear(long epochMilliseconds, TimeZone timeZone) { result.setTimeInMillis(epochMilliseconds); return result.get(Calendar.YEAR); } + + private String getAuthorNameFromCommit(RevCommit commit){ + PersonIdent id = commit.getAuthorIdent(); + return id.getName(); + } + + private String getAuthorEmailFromCommit(RevCommit commit){ + PersonIdent id = commit.getAuthorIdent(); + return id.getEmailAddress(); + } } diff --git a/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitPropertiesProvider.java b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitPropertiesProvider.java new file mode 100644 index 000000000..0a55e4754 --- /dev/null +++ b/license-maven-plugin-git/src/main/java/com/mycila/maven/plugin/license/git/GitPropertiesProvider.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008 Mycila (mathieu.carbou@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mycila.maven.plugin.license.git; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import java.util.Properties; +import java.util.TimeZone; + +/** + * + * @author Peter Palaga + */ +public class GitPropertiesProvider { + + private GitLookup gitLookup; + public static final String COPYRIGHT_LAST_YEAR_MAX_COMMITS_LOOKUP_KEY = "license.git.copyrightLastYearMaxCommitsLookup"; + public static final String COPYRIGHT_LAST_YEAR_SOURCE_KEY = "license.git.copyrightLastYearSource"; + public static final String COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY = "license.git.copyrightLastYearTimeZone"; + + public GitPropertiesProvider(){}; + + /** + * Lazily initializes #gitLookup assuming that all subsequent calls to this method will be related to the same + * git repository. + * + * @param file + * @return + * @throws IOException + */ + GitLookup getGitLookup(File file, Properties props) throws IOException { + if (gitLookup == null) { + synchronized (this) { + if (gitLookup == null) { + String dateSourceString = props.getProperty(COPYRIGHT_LAST_YEAR_SOURCE_KEY, + GitLookup.DateSource.AUTHOR.name()); + GitLookup.DateSource dateSource = GitLookup.DateSource.valueOf(dateSourceString.toUpperCase(Locale.US)); + String checkCommitsCountString = props.getProperty(COPYRIGHT_LAST_YEAR_MAX_COMMITS_LOOKUP_KEY); + int checkCommitsCount = GitLookup.DEFAULT_COMMITS_COUNT; + if (checkCommitsCountString != null) { + checkCommitsCountString = checkCommitsCountString.trim(); + checkCommitsCount = Integer.parseInt(checkCommitsCountString); + } + final TimeZone timeZone; + String tzString = props.getProperty(COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY); + switch (dateSource) { + case COMMITER: + timeZone = tzString == null ? GitLookup.DEFAULT_ZONE : TimeZone.getTimeZone(tzString); + break; + case AUTHOR: + if (tzString != null) { + throw new RuntimeException(COPYRIGHT_LAST_YEAR_TIME_ZONE_KEY + " must not be set with " + + COPYRIGHT_LAST_YEAR_SOURCE_KEY + " = " + GitLookup.DateSource.AUTHOR.name() + + " because git author name already contrains time zone information."); + } + timeZone = null; + break; + default: + throw new IllegalStateException("Unexpected " + GitLookup.DateSource.class.getName() + " " + dateSource); + } + gitLookup = new GitLookup(file, dateSource, timeZone, checkCommitsCount); + } + } + } + return gitLookup; + } +} diff --git a/license-maven-plugin-git/src/main/resources/META-INF/services/com.mycila.maven.plugin.license.PropertiesProvider b/license-maven-plugin-git/src/main/resources/META-INF/services/com.mycila.maven.plugin.license.PropertiesProvider index 88334b22c..36ecb356d 100644 --- a/license-maven-plugin-git/src/main/resources/META-INF/services/com.mycila.maven.plugin.license.PropertiesProvider +++ b/license-maven-plugin-git/src/main/resources/META-INF/services/com.mycila.maven.plugin.license.PropertiesProvider @@ -1 +1,2 @@ -com.mycila.maven.plugin.license.git.CopyrightRangeProvider \ No newline at end of file +com.mycila.maven.plugin.license.git.CopyrightRangeProvider +com.mycila.maven.plugin.license.git.CopyrightAuthorProvider \ No newline at end of file diff --git a/license-maven-plugin-git/src/test/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProviderTest.java b/license-maven-plugin-git/src/test/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProviderTest.java new file mode 100644 index 000000000..27c97cb33 --- /dev/null +++ b/license-maven-plugin-git/src/test/java/com/mycila/maven/plugin/license/git/CopyrightAuthorProviderTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 Mycila (mathieu.carbou@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mycila.maven.plugin.license.git; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import com.mycila.maven.plugin.license.document.Document; + +/** + * @author Peter Palaga + */ +public class CopyrightAuthorProviderTest { + + private static File gitRepoRoot; + private static TemporaryFolder tempFolder; + + @Test + public void copyrightAuthor() { + CopyrightAuthorProvider provider = new CopyrightAuthorProvider(); + + assertAuthor(provider, "dir1/file1.txt", "Peter Palaga", "ppalaga@redhat.com"); + } + + private void assertAuthor(CopyrightAuthorProvider provider, String path, String copyrightAuthorName, String copyrightAuthorEmail) { + Properties props = new Properties(); + + Document document = newDocument(path); + Map actual = provider.getAdditionalProperties(null, props, document); + + HashMap expected = new HashMap(); + expected.put(CopyrightAuthorProvider.COPYRIGHT_CREATION_AUTHOR_NAME_KEY, copyrightAuthorName); + expected.put(CopyrightAuthorProvider.COPYRIGHT_CREATION_AUTHOR_EMAIL_KEY, copyrightAuthorEmail); + Assert.assertEquals("for file '" + path + "': ", expected, actual); + + } + + private static Document newDocument(String relativePath) { + File file = new File(gitRepoRoot.getAbsolutePath() + File.separatorChar + + relativePath.replace('/', File.separatorChar)); + return new Document(file, null, "utf-8", new String[0], null); + } + + @BeforeClass + public static void beforeClass() throws IOException { + tempFolder = new TemporaryFolder(); + tempFolder.create(); + + URL url = GitLookupTest.class.getResource("git-test-repo.zip"); + File unzipDestination = tempFolder.getRoot(); + gitRepoRoot = new File(unzipDestination, "git-test-repo"); + + GitLookupTest.unzip(url, unzipDestination); + } + + @AfterClass + public static void afterClass() { + tempFolder.delete(); + } + +}