diff --git a/config/findbugs-exclude.xml b/config/findbugs-exclude.xml
index 2e28ef6..22c62d1 100644
--- a/config/findbugs-exclude.xml
+++ b/config/findbugs-exclude.xml
@@ -1,9 +1,18 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/import-control.xml b/config/import-control.xml
index 2142bcb..37fde80 100644
--- a/config/import-control.xml
+++ b/config/import-control.xml
@@ -4,4 +4,9 @@
"http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 8a8addc..f23cd83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,18 @@
4.12
test
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.6
+ test
+
+
+ org.powermock
+ powermock-module-junit4
+ 1.6.6
+ test
+
org.apache.maven
maven-jxr
@@ -146,7 +158,8 @@
https://raw.githubusercontent.com/checkstyle/checkstyle/checkstyle-${checkstyle.version}/config/checkstyle_sevntu_checks.xml
- project.basedir=${project.basedir}
+ project.basedir=${project.basedir}
+
true
true
0
@@ -205,7 +218,7 @@
xml
html
-
+
@@ -254,6 +267,12 @@
0
0
+
+ com.github.checkstyle.regression.git.DiffParser
+
+ 50
+ 100
+
diff --git a/src/main/java/com/github/checkstyle/regression/git/DiffParser.java b/src/main/java/com/github/checkstyle/regression/git/DiffParser.java
new file mode 100644
index 0000000..42872d0
--- /dev/null
+++ b/src/main/java/com/github/checkstyle/regression/git/DiffParser.java
@@ -0,0 +1,104 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.github.checkstyle.regression.git;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+
+/**
+ * Git diff parser.
+ * @author LuoLiangchen
+ */
+public class DiffParser {
+ /** The path of checkstyle repository. */
+ private final String repositoryPath;
+
+ /**
+ * Creates a new {@code DiffParser} instance.
+ * @param repositoryPath the path of checkstyle repository
+ */
+ public DiffParser(String repositoryPath) {
+ this.repositoryPath = repositoryPath;
+ }
+
+ /**
+ * Parses the diff between a given branch and the master.
+ * @param branchName the name of the branch to be compared with master
+ * @return a list of {@code GitChange} to represent the changes
+ * @throws IOException JGit library exception
+ * @throws GitAPIException JGit library exception
+ */
+ public List parse(String branchName) throws IOException, GitAPIException {
+ final File gitDir = new File(repositoryPath, ".git");
+ try (Repository repository = new FileRepositoryBuilder().setGitDir(gitDir)
+ .readEnvironment().findGitDir().build()) {
+ try (Git git = new Git(repository)) {
+ final AbstractTreeIterator featureTreeParser =
+ prepareTreeParser(repository, Constants.R_HEADS + branchName);
+ final AbstractTreeIterator masterTreeParser =
+ prepareTreeParser(repository, Constants.R_HEADS + "master");
+ return git.diff()
+ .setOldTree(masterTreeParser)
+ .setNewTree(featureTreeParser)
+ .call()
+ .stream()
+ .map(GitChange::new)
+ .collect(Collectors.toList());
+ }
+ }
+ }
+
+ /**
+ * Creates a tree parser from a commit, to be used by diff command.
+ * @param repository the repository to parse diff
+ * @param ref the name of the ref to the commit; e.g., "refs/heads/master"
+ * @return the tree parser
+ * @throws IOException JGit library exception
+ */
+ private static AbstractTreeIterator prepareTreeParser(Repository repository, String ref)
+ throws IOException {
+ final Ref head = repository.exactRef(ref);
+ try (RevWalk walk = new RevWalk(repository)) {
+ final RevCommit commit = walk.parseCommit(head.getObjectId());
+ final RevTree tree = walk.parseTree(commit.getTree().getId());
+ final CanonicalTreeParser treeParser = new CanonicalTreeParser();
+ try (ObjectReader reader = repository.newObjectReader()) {
+ treeParser.reset(reader, tree.getId());
+ }
+ walk.dispose();
+ return treeParser;
+ }
+ }
+}
diff --git a/src/main/java/com/github/checkstyle/regression/git/GitChange.java b/src/main/java/com/github/checkstyle/regression/git/GitChange.java
new file mode 100644
index 0000000..cf2b884
--- /dev/null
+++ b/src/main/java/com/github/checkstyle/regression/git/GitChange.java
@@ -0,0 +1,47 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.github.checkstyle.regression.git;
+
+import org.eclipse.jgit.diff.DiffEntry;
+
+/**
+ * Represents git changes of a file.
+ * @author LuoLiangchen
+ */
+public class GitChange {
+ /** The path of the changed file. */
+ private final String path;
+
+ /**
+ * Creates a new {@code GitChange} instance from a {@code DiffEntry}.
+ * @param diff the {@code DiffEntry}
+ */
+ GitChange(DiffEntry diff) {
+ path = diff.getNewPath();
+ }
+
+ /**
+ * Gets the path of the changed file.
+ * @return the path of the changed file
+ */
+ public String getPath() {
+ return path;
+ }
+}
diff --git a/src/main/java/com/github/checkstyle/regression/git/package-info.java b/src/main/java/com/github/checkstyle/regression/git/package-info.java
new file mode 100644
index 0000000..ded4015
--- /dev/null
+++ b/src/main/java/com/github/checkstyle/regression/git/package-info.java
@@ -0,0 +1,23 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Contains git related classes.
+ */
+package com.github.checkstyle.regression.git;
diff --git a/src/test/java/com/github/checkstyle/regression/git/DiffParserTest.java b/src/test/java/com/github/checkstyle/regression/git/DiffParserTest.java
new file mode 100644
index 0000000..50cfe7a
--- /dev/null
+++ b/src/test/java/com/github/checkstyle/regression/git/DiffParserTest.java
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.github.checkstyle.regression.git;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
+
+import org.eclipse.jgit.lib.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.github.checkstyle.regression.internal.GitUtils;
+
+public class DiffParserTest {
+ private Repository repository;
+
+ @Before
+ public void setUp() throws Exception {
+ repository = GitUtils.newRepository();
+ final File helloWorld = GitUtils.addAnEmptyFileAndCommit(repository, "HelloWorld");
+ GitUtils.createNewBranchAndCheckout(repository, "foo");
+ Files.write(helloWorld.toPath(), "hello world!".getBytes(), StandardOpenOption.APPEND);
+ GitUtils.addAllAndCommit(repository, "append text to HelloWorld");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ repository.close();
+ }
+
+ @Test
+ public void testParse() throws Exception {
+ final DiffParser diffParser = new DiffParser(repository.getDirectory().getParent());
+ final List changes = diffParser.parse("foo");
+ assertEquals(1, changes.size());
+ assertEquals("HelloWorld", changes.iterator().next().getPath());
+ }
+}
diff --git a/src/test/java/com/github/checkstyle/regression/internal/GitUtils.java b/src/test/java/com/github/checkstyle/regression/internal/GitUtils.java
new file mode 100644
index 0000000..23750b2
--- /dev/null
+++ b/src/test/java/com/github/checkstyle/regression/internal/GitUtils.java
@@ -0,0 +1,82 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2017 the original author or authors.
+//
+// This library 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 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+////////////////////////////////////////////////////////////////////////////////
+
+package com.github.checkstyle.regression.internal;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+
+/**
+ * Contains utility methods for git component test.
+ * @author LuoLiangchen
+ */
+public final class GitUtils {
+ /** Prevents instantiation. */
+ private GitUtils() {
+ }
+
+ public static Repository newRepository() throws IOException {
+ final File repoDir = File.createTempFile("TestTempRepository", "");
+ if (!repoDir.delete()) {
+ throw new IOException("Could not delete temporary file " + repoDir);
+ }
+ final Repository repository = FileRepositoryBuilder.create(new File(repoDir, ".git"));
+ repository.create();
+ return repository;
+ }
+
+ public static void createNewBranchAndCheckout(Repository repository, String branchName)
+ throws GitAPIException {
+ try (Git git = new Git(repository)) {
+ if (git.branchList().call().stream()
+ .anyMatch(ref -> ref.getName().equals(Constants.R_HEADS + branchName))) {
+ git.branchDelete().setBranchNames(branchName).setForce(true).call();
+ }
+ git.branchCreate().setName(branchName).call();
+ git.checkout().setName(branchName).call();
+ }
+ }
+
+ public static File addAnEmptyFileAndCommit(Repository repository, String fileName)
+ throws IOException, GitAPIException {
+ try (Git git = new Git(repository)) {
+ final File file = new File(repository.getDirectory().getParent(), fileName);
+ if (!file.createNewFile()) {
+ throw new IOException("Could not create file " + file);
+ }
+ git.add().addFilepattern(fileName).call();
+ git.commit().setMessage("add " + fileName).call();
+ return file;
+ }
+ }
+
+ public static void addAllAndCommit(Repository repository, String message)
+ throws GitAPIException {
+ try (Git git = new Git(repository)) {
+ git.add().addFilepattern(".").call();
+ git.commit().setMessage(message).call();
+ }
+ }
+}