From a125cf6876e0edc5a2498df57a9df06d60b1f572 Mon Sep 17 00:00:00 2001 From: James Moger Date: Thu, 2 Jun 2011 22:40:23 -0400 Subject: [PATCH] Unit testing. Start of git-notes display feature. --- distrib/gitblit.properties | 7 +- distrib/users.properties | 2 +- src/com/gitblit/GitBlit.java | 2 +- src/com/gitblit/models/GitNote.java | 31 ++ src/com/gitblit/utils/DiffUtils.java | 15 +- src/com/gitblit/utils/JGitUtils.java | 456 ++++++++---------- src/com/gitblit/utils/MarkdownUtils.java | 21 +- src/com/gitblit/utils/MetricUtils.java | 98 ++-- src/com/gitblit/utils/StringUtils.java | 8 + src/com/gitblit/utils/TicgitUtils.java | 13 +- .../gitblit/wicket/pages/BlobDiffPage.java | 2 +- .../gitblit/wicket/pages/CommitDiffPage.java | 2 +- src/com/gitblit/wicket/pages/CommitPage.html | 8 + src/com/gitblit/wicket/pages/CommitPage.java | 24 + .../wicket/pages/EditRepositoryPage.java | 19 +- src/com/gitblit/wicket/pages/MetricsPage.java | 10 +- src/com/gitblit/wicket/pages/SummaryPage.java | 2 +- .../wicket/panels/CommitLegendPanel.java | 15 +- tests/com/gitblit/tests/DiffUtilsTest.java | 2 +- tests/com/gitblit/tests/GitBlitSuite.java | 48 +- tests/com/gitblit/tests/JGitUtilsTest.java | 202 ++++++-- .../com/gitblit/tests/MarkdownUtilsTest.java | 36 ++ tests/com/gitblit/tests/MetricUtilsTest.java | 13 +- tests/com/gitblit/tests/TicgitUtilsTest.java | 28 +- 24 files changed, 655 insertions(+), 409 deletions(-) create mode 100644 src/com/gitblit/models/GitNote.java create mode 100644 tests/com/gitblit/tests/MarkdownUtilsTest.java diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties index c17674ab..5c6603a0 100644 --- a/distrib/gitblit.properties +++ b/distrib/gitblit.properties @@ -17,9 +17,12 @@ git.repositoriesFolder = git # if false, each exported repository must have a .git/git-daemon-export-ok file git.exportAll = true -# Search repositories folder for nested repositories +# Search the repositories folder subfolders for other repositories. +# Repositories MAY NOT be nested (i.e. one repository within another) +# but they may be grouped together in subfolders. # e.g. c:/gitrepos/libraries/mylibrary.git -git.nestedRepositories = true +# c:/gitrepos/libraries/myotherlibrary.git +git.searchRepositoriesSubfolders = true # # Authentication Settings diff --git a/distrib/users.properties b/distrib/users.properties index 233e9f93..a7ebc678 100644 --- a/distrib/users.properties +++ b/distrib/users.properties @@ -1,3 +1,3 @@ ## Git:Blit realm file format: username=password,\#permission,repository1,repository2... -#Tue May 31 11:19:53 EDT 2011 +#Thu Jun 02 22:11:15 EDT 2011 admin=admin,\#admin diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 7182d9b7..595a5ee1 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -142,7 +142,7 @@ public class GitBlit implements ServletContextListener { public List getRepositoryList() { return JGitUtils.getRepositoryList(repositoriesFolder, exportAll, - storedSettings.getBoolean(Keys.git.nestedRepositories, true)); + storedSettings.getBoolean(Keys.git.searchRepositoriesSubfolders, true)); } public Repository getRepository(String repositoryName) { diff --git a/src/com/gitblit/models/GitNote.java b/src/com/gitblit/models/GitNote.java new file mode 100644 index 00000000..0083637c --- /dev/null +++ b/src/com/gitblit/models/GitNote.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011 gitblit.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.gitblit.models; + +import java.io.Serializable; + +public class GitNote implements Serializable { + + private static final long serialVersionUID = 1L; + + public String content; + public RefModel notesRef; + + public GitNote(RefModel notesRef, String text) { + this.notesRef = notesRef; + this.content = text; + } +} \ No newline at end of file diff --git a/src/com/gitblit/utils/DiffUtils.java b/src/com/gitblit/utils/DiffUtils.java index 969cb916..fab9f43b 100644 --- a/src/com/gitblit/utils/DiffUtils.java +++ b/src/com/gitblit/utils/DiffUtils.java @@ -30,12 +30,23 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.gitblit.utils.JGitUtils.DiffOutputType; - public class DiffUtils { private static final Logger LOGGER = LoggerFactory.getLogger(DiffUtils.class); + public static enum DiffOutputType { + PLAIN, GITWEB, GITBLIT; + + public static DiffOutputType forName(String name) { + for (DiffOutputType type : values()) { + if (type.name().equalsIgnoreCase(name)) { + return type; + } + } + return null; + } + } + public static String getCommitDiff(Repository r, RevCommit commit, DiffOutputType outputType) { return getDiff(r, null, commit, null, outputType); } diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index 32602b94..fd2eaf36 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; -import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,7 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -52,6 +50,7 @@ import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.RepositoryCache.FileKey; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; @@ -67,77 +66,69 @@ import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.jgit.treewalk.filter.PathSuffixFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.io.DisabledOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.gitblit.models.GitNote; import com.gitblit.models.PathModel; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; -import com.gitblit.models.TicketModel; -import com.gitblit.models.TicketModel.Comment; public class JGitUtils { static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class); + public static String getDisplayName(PersonIdent person) { + if (StringUtils.isEmpty(person.getEmailAddress())) { + return person.getName(); + } + final StringBuilder r = new StringBuilder(); + r.append(person.getName()); + r.append(" <"); + r.append(person.getEmailAddress()); + r.append('>'); + return r.toString().trim(); + } + public static Repository createRepository(File repositoriesFolder, String name, boolean bare) { Git git = Git.init().setDirectory(new File(repositoriesFolder, name)).setBare(bare).call(); return git.getRepository(); } public static List getRepositoryList(File repositoriesFolder, boolean exportAll, - boolean readNested) { + boolean searchSubfolders) { List list = new ArrayList(); - list.addAll(getNestedRepositories(repositoriesFolder, repositoriesFolder, exportAll, - readNested)); + if (repositoriesFolder == null || !repositoriesFolder.exists()) { + return list; + } + list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder, + exportAll, searchSubfolders)); Collections.sort(list); return list; } - public static List getNestedRepositories(File repositoriesFolder, File folder, - boolean exportAll, boolean readNested) { + private static List getRepositoryList(String basePath, File searchFolder, + boolean exportAll, boolean searchSubfolders) { List list = new ArrayList(); - if (folder == null || !folder.exists()) { - return list; - } - String basefile = repositoriesFolder.getAbsolutePath(); - for (File file : folder.listFiles()) { - if (file.isDirectory() && !file.getName().equalsIgnoreCase(Constants.DOT_GIT)) { - // if this is a git repository add it to the list - // - // first look for standard folder/.git structure - File gitFolder = new File(file, Constants.DOT_GIT); - boolean isGitRepository = gitFolder.exists() && gitFolder.isDirectory(); - - // then look for folder.git/HEAD or folder/HEAD and - // folder/config - if (!isGitRepository) { - if ((file.getName().endsWith(Constants.DOT_GIT_EXT) && new File(file, - Constants.HEAD).exists()) - || (new File(file, "config").exists() && new File(file, Constants.HEAD) - .exists())) { - gitFolder = file; - isGitRepository = true; - } - } - boolean exportRepository = isGitRepository - && (exportAll || new File(gitFolder, "git-daemon-export-ok").exists()); - - if (exportRepository) { - // determine repository name relative to repositories folder - String filename = file.getAbsolutePath(); - String repo = filename.substring(basefile.length()).replace('\\', '/'); - if (repo.charAt(0) == '/') { - repo = repo.substring(1); + for (File file : searchFolder.listFiles()) { + if (file.isDirectory()) { + File gitDir = FileKey.resolve(new File(searchFolder, file.getName()), FS.DETECTED); + if (gitDir != null) { + boolean exportRepository = exportAll + || new File(gitDir, "git-daemon-export-ok").exists(); + + if (!exportRepository) { + continue; } - list.add(repo); - } - - // look for nested repositories - if (readNested) { - list.addAll(getNestedRepositories(repositoriesFolder, file, exportAll, - readNested)); + // determine repository name relative to base path + String repository = StringUtils.getRelativePath(basePath, + file.getAbsolutePath()); + list.add(repository); + } else if (searchSubfolders) { + // look for repositories in subfolders + list.addAll(getRepositoryList(basePath, file, exportAll, searchSubfolders)); } } } @@ -151,18 +142,18 @@ public class JGitUtils { if (StringUtils.isEmpty(branch)) { branch = Constants.HEAD; } + RevCommit commit = null; try { RevWalk walk = new RevWalk(r); walk.sort(RevSort.REVERSE); RevCommit head = walk.parseCommit(r.resolve(branch)); walk.markStart(head); - RevCommit commit = walk.next(); + commit = walk.next(); walk.dispose(); - return commit; } catch (Throwable t) { LOGGER.error("Failed to determine first commit", t); } - return null; + return commit; } public static Date getFirstChange(Repository r, String branch) { @@ -197,13 +188,17 @@ public class JGitUtils { return getCommitDate(commit); } + public static Date getCommitDate(RevCommit commit) { + return new Date(commit.getCommitTime() * 1000L); + } + public static RevCommit getCommit(Repository r, String objectId) { - RevCommit commit = null; if (!hasCommits(r)) { return null; } + RevCommit commit = null; try { - if (objectId == null || objectId.trim().length() == 0) { + if (StringUtils.isEmpty(objectId)) { objectId = Constants.HEAD; } ObjectId object = r.resolve(objectId); @@ -231,22 +226,6 @@ public class JGitUtils { return refs; } - public static Map> getRefs(Repository r, String baseRef) { - Map> refs = new HashMap>(); - Map> allRefs = r.getAllRefsByPeeledObjectId(); - for (Entry> setRefs : allRefs.entrySet()) { - List list = new ArrayList(); - for (Ref setRef : setRefs.getValue()) { - String name = setRef.getName(); - if (name.startsWith(baseRef)) { - list.add(name); - } - } - refs.put(setRefs.getKey().toObjectId(), list); - } - return refs; - } - /** * Lookup an entry stored in a tree, failing if not present. * @@ -257,13 +236,17 @@ public class JGitUtils { * @return the parsed object entry at this path * @throws Exception */ - public static RevObject getRevObject(Repository r, final RevTree tree, final String path) { - RevObject ro = null; + public static byte[] getRawContent(Repository r, RevCommit commit, final String path) { RevWalk rw = new RevWalk(r); TreeWalk tw = new TreeWalk(r); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); + byte[] content = null; try { - tw.reset(tree); + if (commit == null) { + ObjectId object = r.resolve(Constants.HEAD); + commit = rw.parseCommit(object); + } + tw.reset(commit.getTree()); while (tw.next()) { if (tw.isSubtree() && !path.equals(tw.getPathString())) { tw.enterSubtree(); @@ -271,123 +254,104 @@ public class JGitUtils { } ObjectId entid = tw.getObjectId(0); FileMode entmode = tw.getFileMode(0); - ro = rw.lookupAny(entid, entmode.getObjectType()); + RevObject ro = rw.lookupAny(entid, entmode.getObjectType()); rw.parseBody(ro); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ObjectLoader ldr = r.open(ro.getId(), Constants.OBJ_BLOB); + byte[] tmp = new byte[4096]; + InputStream in = ldr.openStream(); + int n; + while ((n = in.read(tmp)) > 0) { + os.write(tmp, 0, n); + } + in.close(); + content = os.toByteArray(); } } catch (Throwable t) { - LOGGER.error("Can't find " + path + " in tree " + tree.name(), t); + LOGGER.error("Can't find " + path + " in tree " + commit.getTree().name(), t); } finally { - if (rw != null) { - rw.dispose(); - } - } - return ro; - } - - public static byte[] getRawContent(Repository r, RevBlob blob) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - ObjectLoader ldr = r.open(blob.getId(), Constants.OBJ_BLOB); - byte[] tmp = new byte[1024]; - InputStream in = ldr.openStream(); - int n; - while ((n = in.read(tmp)) > 0) { - os.write(tmp, 0, n); - } - in.close(); - } catch (Throwable t) { - LOGGER.error("Failed to read raw content", t); + rw.dispose(); + tw.release(); } - return os.toByteArray(); - } - - public static String getRawContentAsString(Repository r, RevBlob blob) { - byte[] content = getRawContent(r, blob); - return new String(content, Charset.forName(Constants.CHARACTER_ENCODING)); + return content; } public static String getRawContentAsString(Repository r, RevCommit commit, String blobPath) { - RevObject obj = getRevObject(r, commit.getTree(), blobPath); - byte[] content = getRawContent(r, (RevBlob) obj); + byte[] content = getRawContent(r, commit, blobPath); + if (content == null) { + return null; + } return new String(content, Charset.forName(Constants.CHARACTER_ENCODING)); } - public static List getFilesInPath(Repository r, String basePath, String objectId) { - RevCommit commit = getCommit(r, objectId); - return getFilesInPath(r, basePath, commit); - } - public static List getFilesInPath(Repository r, String basePath, RevCommit commit) { List list = new ArrayList(); - if (commit == null) { + if (!hasCommits(r)) { return list; } - final TreeWalk walk = new TreeWalk(r); + if (commit == null) { + commit = getCommit(r, Constants.HEAD); + } + final TreeWalk tw = new TreeWalk(r); try { - walk.addTree(commit.getTree()); - if (basePath != null && basePath.length() > 0) { + tw.addTree(commit.getTree()); + if (!StringUtils.isEmpty(basePath)) { PathFilter f = PathFilter.create(basePath); - walk.setFilter(f); - walk.setRecursive(false); + tw.setFilter(f); + tw.setRecursive(false); boolean foundFolder = false; - while (walk.next()) { - if (!foundFolder && walk.isSubtree()) { - walk.enterSubtree(); + while (tw.next()) { + if (!foundFolder && tw.isSubtree()) { + tw.enterSubtree(); } - if (walk.getPathString().equals(basePath)) { + if (tw.getPathString().equals(basePath)) { foundFolder = true; continue; } if (foundFolder) { - list.add(getPathModel(walk, basePath, commit)); + list.add(getPathModel(tw, basePath, commit)); } } } else { - walk.setRecursive(false); - while (walk.next()) { - list.add(getPathModel(walk, null, commit)); + tw.setRecursive(false); + while (tw.next()) { + list.add(getPathModel(tw, null, commit)); } } } catch (IOException e) { LOGGER.error("Failed to get files for commit " + commit.getName(), e); } finally { - walk.release(); + tw.release(); } Collections.sort(list); return list; } - public static List getFilesInCommit(Repository r, String commitId) { - RevCommit commit = getCommit(r, commitId); - return getFilesInCommit(r, commit); - } - public static List getFilesInCommit(Repository r, RevCommit commit) { List list = new ArrayList(); - if (commit == null) { - LOGGER.warn("getFilesInCommit for NULL commit"); - return list; - } + RevWalk rw = new RevWalk(r); + TreeWalk tw = new TreeWalk(r); try { - final RevWalk rw = new RevWalk(r); - + if (commit == null) { + ObjectId object = r.resolve(Constants.HEAD); + commit = rw.parseCommit(object); + } RevTree commitTree = commit.getTree(); - final TreeWalk walk = new TreeWalk(r); - walk.reset(); - walk.setRecursive(true); + tw.reset(); + tw.setRecursive(true); if (commit.getParentCount() == 0) { - walk.addTree(commitTree); - while (walk.next()) { - list.add(new PathChangeModel(walk.getPathString(), walk.getPathString(), 0, - walk.getRawMode(0), commit.getId().getName(), ChangeType.ADD)); + tw.addTree(commitTree); + while (tw.next()) { + list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw + .getRawMode(0), commit.getId().getName(), ChangeType.ADD)); } } else { RevCommit parent = rw.parseCommit(commit.getParent(0).getId()); RevTree parentTree = parent.getTree(); - walk.addTree(parentTree); - walk.addTree(commitTree); - walk.setFilter(TreeFilter.ANY_DIFF); + tw.addTree(parentTree); + tw.addTree(commitTree); + tw.setFilter(TreeFilter.ANY_DIFF); RawTextComparator cmp = RawTextComparator.DEFAULT; DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE); @@ -409,6 +373,9 @@ public class JGitUtils { } } catch (Throwable t) { LOGGER.error("failed to determine files in commit!", t); + } finally { + rw.dispose(); + tw.release(); } return list; } @@ -416,84 +383,51 @@ public class JGitUtils { public static List getDocuments(Repository r, List extensions) { List list = new ArrayList(); RevCommit commit = getCommit(r, Constants.HEAD); - final TreeWalk walk = new TreeWalk(r); + final TreeWalk tw = new TreeWalk(r); try { - walk.addTree(commit.getTree()); + tw.addTree(commit.getTree()); if (extensions != null && extensions.size() > 0) { Collection suffixFilters = new ArrayList(); for (String extension : extensions) { if (extension.charAt(0) == '.') { - suffixFilters.add(PathSuffixFilter.create(extension)); + suffixFilters.add(PathSuffixFilter.create("\\" + extension)); } else { // escape the . since this is a regexp filter suffixFilters.add(PathSuffixFilter.create("\\." + extension)); } } TreeFilter filter = OrTreeFilter.create(suffixFilters); - walk.setFilter(filter); - walk.setRecursive(true); - while (walk.next()) { - list.add(getPathModel(walk, null, commit)); - } - } else { - while (walk.next()) { - list.add(getPathModel(walk, null, commit)); - } + tw.setFilter(filter); + tw.setRecursive(true); + } + while (tw.next()) { + list.add(getPathModel(tw, null, commit)); } } catch (IOException e) { - LOGGER.error("Failed to get files for commit " + commit.getName(), e); + LOGGER.error("Failed to get documents for commit " + commit.getName(), e); } finally { - walk.release(); + tw.release(); } Collections.sort(list); return list; } - public static Map getChangedPathsStats(List paths) { - Map stats = new HashMap(); - for (PathChangeModel path : paths) { - if (!stats.containsKey(path.changeType)) { - stats.put(path.changeType, new AtomicInteger(0)); - } - stats.get(path.changeType).incrementAndGet(); - } - return stats; - } - - public static enum DiffOutputType { - PLAIN, GITWEB, GITBLIT; - - public static DiffOutputType forName(String name) { - for (DiffOutputType type : values()) { - if (type.name().equalsIgnoreCase(name)) { - return type; - } - } - return null; - } - } - - private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) { + private static PathModel getPathModel(TreeWalk tw, String basePath, RevCommit commit) { String name; long size = 0; - if (basePath == null) { - name = walk.getPathString(); + if (StringUtils.isEmpty(basePath)) { + name = tw.getPathString(); } else { - try { - name = walk.getPathString().substring(basePath.length() + 1); - } catch (Throwable t) { - name = walk.getPathString(); - } + name = tw.getPathString().substring(basePath.length() + 1); } try { - if (!walk.isSubtree()) { - size = walk.getObjectReader() - .getObjectSize(walk.getObjectId(0), Constants.OBJ_BLOB); + if (!tw.isSubtree()) { + size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB); } } catch (Throwable t) { LOGGER.error("Failed to retrieve blob size", t); } - return new PathModel(name, walk.getPathString(), size, walk.getFileMode(0).getBits(), + return new PathModel(name, tw.getPathString(), size, tw.getFileMode(0).getBits(), commit.getName()); } @@ -510,11 +444,9 @@ public class JGitUtils { } else if (FileMode.GITLINK.equals(mode)) { // FIXME gitlink permissions return "gitlink"; - } else if (FileMode.MISSING.equals(mode)) { - // FIXME missing permissions - return "missing"; } - return "" + mode; + // FIXME missing permissions + return "missing"; } public static List getRevLog(Repository r, int maxCount) { @@ -532,19 +464,19 @@ public class JGitUtils { return list; } try { - if (objectId == null || objectId.trim().length() == 0) { + if (StringUtils.isEmpty(objectId)) { objectId = Constants.HEAD; } - RevWalk walk = new RevWalk(r); + RevWalk rw = new RevWalk(r); ObjectId object = r.resolve(objectId); - walk.markStart(walk.parseCommit(object)); + rw.markStart(rw.parseCommit(object)); if (!StringUtils.isEmpty(path)) { TreeFilter filter = AndTreeFilter.create( PathFilterGroup.createFromStrings(Collections.singleton(path)), TreeFilter.ANY_DIFF); - walk.setTreeFilter(filter); + rw.setTreeFilter(filter); } - Iterable revlog = walk; + Iterable revlog = rw; if (offset > 0) { int count = 0; for (RevCommit rev : revlog) { @@ -564,9 +496,9 @@ public class JGitUtils { } } } - walk.dispose(); + rw.dispose(); } catch (Throwable t) { - LOGGER.error("Failed to determine last change", t); + LOGGER.error("Failed to get revlog", t); } return list; } @@ -580,9 +512,10 @@ public class JGitUtils { return type; } } - return null; + return COMMIT; } + @Override public String toString() { return name().toLowerCase(); } @@ -596,11 +529,11 @@ public class JGitUtils { return list; } try { - if (objectId == null || objectId.trim().length() == 0) { + if (StringUtils.isEmpty(objectId)) { objectId = Constants.HEAD; } - RevWalk walk = new RevWalk(r); - walk.setRevFilter(new RevFilter() { + RevWalk rw = new RevWalk(r); + rw.setRevFilter(new RevFilter() { @Override public RevFilter clone() { @@ -610,25 +543,30 @@ public class JGitUtils { @Override public boolean include(RevWalk walker, RevCommit commit) throws StopWalkException, MissingObjectException, IncorrectObjectTypeException, IOException { + boolean include = false; switch (type) { case AUTHOR: - return (commit.getAuthorIdent().getName().toLowerCase().indexOf(lcValue) > -1) + include = (commit.getAuthorIdent().getName().toLowerCase().indexOf(lcValue) > -1) || (commit.getAuthorIdent().getEmailAddress().toLowerCase() .indexOf(lcValue) > -1); + break; case COMMITTER: - return (commit.getCommitterIdent().getName().toLowerCase().indexOf(lcValue) > -1) + include = (commit.getCommitterIdent().getName().toLowerCase() + .indexOf(lcValue) > -1) || (commit.getCommitterIdent().getEmailAddress().toLowerCase() .indexOf(lcValue) > -1); + break; case COMMIT: - return commit.getFullMessage().toLowerCase().indexOf(lcValue) > -1; + include = commit.getFullMessage().toLowerCase().indexOf(lcValue) > -1; + break; } - return false; + return include; } }); ObjectId object = r.resolve(objectId); - walk.markStart(walk.parseCommit(object)); - Iterable revlog = walk; + rw.markStart(rw.parseCommit(object)); + Iterable revlog = rw; if (offset > 0) { int count = 0; for (RevCommit rev : revlog) { @@ -648,9 +586,9 @@ public class JGitUtils { } } } - walk.dispose(); + rw.dispose(); } catch (Throwable t) { - LOGGER.error("Failed to determine last change", t); + LOGGER.error("Failed to search revlogs", t); } return list; } @@ -667,7 +605,11 @@ public class JGitUtils { return getRefs(r, Constants.R_REMOTES, maxCount); } - public static List getRefs(Repository r, String refs, int maxCount) { + public static List getNotes(Repository r, int maxCount) { + return getRefs(r, Constants.R_NOTES, maxCount); + } + + private static List getRefs(Repository r, String refs, int maxCount) { List list = new ArrayList(); try { Map map = r.getRefDatabase().getRefs(refs); @@ -687,45 +629,32 @@ public class JGitUtils { return list; } - public static Ref getRef(Repository r, String id) { - // FIXME - try { - Map map = r.getRefDatabase().getRefs(id); - for (Entry entry : map.entrySet()) { - return entry.getValue(); + public static List getNotesOnCommit(Repository repository, RevCommit commit) { + List list = new ArrayList(); + List notesRefs = getNotes(repository, -1); + for (RefModel notesRef : notesRefs) { + RevCommit notes = JGitUtils.getCommit(repository, notesRef.getName()); + StringBuilder sb = new StringBuilder(commit.getName()); + sb.insert(2, '/'); + String text = getRawContentAsString(repository, notes, sb.toString()); + if (!StringUtils.isEmpty(text)) { + GitNote gitNote = new GitNote(notesRef, text); + list.add(gitNote); } - } catch (IOException e) { - LOGGER.error("Failed to retrieve ref " + id, e); } - return null; - } - - public static Date getCommitDate(RevCommit commit) { - return new Date(commit.getCommitTime() * 1000L); - } - - public static String getDisplayName(PersonIdent person) { - final StringBuilder r = new StringBuilder(); - r.append(person.getName()); - r.append(" <"); - r.append(person.getEmailAddress()); - r.append('>'); - return r.toString(); + return list; } public static StoredConfig readConfig(Repository r) { StoredConfig c = r.getConfig(); - if (c != null) { - try { - c.load(); - } catch (ConfigInvalidException cex) { - LOGGER.error("Repository configuration is invalid!", cex); - } catch (IOException cex) { - LOGGER.error("Could not open repository configuration!", cex); - } - return c; + try { + c.load(); + } catch (ConfigInvalidException cex) { + LOGGER.error("Repository configuration is invalid!", cex); + } catch (IOException cex) { + LOGGER.error("Could not open repository configuration!", cex); } - return null; + return c; } public static boolean zip(Repository r, String basePath, String objectId, OutputStream os) @@ -734,26 +663,27 @@ public class JGitUtils { if (commit == null) { return false; } - final RevWalk rw = new RevWalk(r); - final TreeWalk walk = new TreeWalk(r); + boolean success = false; + RevWalk rw = new RevWalk(r); + TreeWalk tw = new TreeWalk(r); try { - walk.addTree(commit.getTree()); + tw.addTree(commit.getTree()); ZipOutputStream zos = new ZipOutputStream(os); zos.setComment("Generated by Git:Blit"); - if (basePath != null && basePath.length() > 0) { + if (!StringUtils.isEmpty(basePath)) { PathFilter f = PathFilter.create(basePath); - walk.setFilter(f); + tw.setFilter(f); } - walk.setRecursive(true); - while (walk.next()) { - ZipEntry entry = new ZipEntry(walk.getPathString()); - entry.setSize(walk.getObjectReader().getObjectSize(walk.getObjectId(0), + tw.setRecursive(true); + while (tw.next()) { + ZipEntry entry = new ZipEntry(tw.getPathString()); + entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB)); entry.setComment(commit.getName()); zos.putNextEntry(entry); - ObjectId entid = walk.getObjectId(0); - FileMode entmode = walk.getFileMode(0); + ObjectId entid = tw.getObjectId(0); + FileMode entmode = tw.getFileMode(0); RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType()); rw.parseBody(blob); @@ -767,13 +697,13 @@ public class JGitUtils { in.close(); } zos.finish(); - return true; + success = true; } catch (IOException e) { LOGGER.error("Failed to zip files from commit " + commit.getName(), e); } finally { - walk.release(); + tw.release(); rw.dispose(); } - return false; + return success; } } diff --git a/src/com/gitblit/utils/MarkdownUtils.java b/src/com/gitblit/utils/MarkdownUtils.java index 15d59cfe..697fa99b 100644 --- a/src/com/gitblit/utils/MarkdownUtils.java +++ b/src/com/gitblit/utils/MarkdownUtils.java @@ -26,22 +26,10 @@ import org.tautua.markdownpapers.parser.ParseException; public class MarkdownUtils { public static String transformMarkdown(String markdown) throws java.text.ParseException { - // Read raw markdown content and transform it to html - StringReader reader = new StringReader(markdown); - StringWriter writer = new StringWriter(); try { - Markdown md = new Markdown(); - md.transform(reader, writer); - return writer.toString(); - } catch (ParseException p) { - throw new java.text.ParseException(p.getMessage(), 0); - } finally { - reader.close(); - try { - writer.close(); - } catch (IOException e) { - // IGNORE - } + return transformMarkdown(new StringReader(markdown)); + } catch (NullPointerException p) { + throw new java.text.ParseException("Markdown string is null!", 0); } } @@ -51,7 +39,7 @@ public class MarkdownUtils { try { Markdown md = new Markdown(); md.transform(markdownReader, writer); - return writer.toString(); + return writer.toString().trim(); } catch (ParseException p) { throw new java.text.ParseException(p.getMessage(), 0); } finally { @@ -67,5 +55,4 @@ public class MarkdownUtils { } } } - } diff --git a/src/com/gitblit/utils/MetricUtils.java b/src/com/gitblit/utils/MetricUtils.java index b1da2738..4ca9f36a 100644 --- a/src/com/gitblit/utils/MetricUtils.java +++ b/src/com/gitblit/utils/MetricUtils.java @@ -42,45 +42,7 @@ public class MetricUtils { public static List getDateMetrics(Repository r, boolean includeTotal, String format) { Metric total = new Metric("TOTAL"); final Map metricMap = new HashMap(); - - if (JGitUtils.hasCommits(r)) { - try { - RevWalk walk = new RevWalk(r); - ObjectId object = r.resolve(Constants.HEAD); - RevCommit lastCommit = walk.parseCommit(object); - walk.markStart(lastCommit); - SimpleDateFormat df = new SimpleDateFormat(format); - Iterable revlog = walk; - for (RevCommit rev : revlog) { - Date d = JGitUtils.getCommitDate(rev); - String p = df.format(d); - if (!metricMap.containsKey(p)) { - metricMap.put(p, new Metric(p)); - } - Metric m = metricMap.get(p); - m.count++; - total.count++; - } - } catch (Throwable t) { - JGitUtils.LOGGER.error("Failed to mine log history for metrics", t); - } - } - List keys = new ArrayList(metricMap.keySet()); - Collections.sort(keys); - List metrics = new ArrayList(); - for (String key : keys) { - metrics.add(metricMap.get(key)); - } - if (includeTotal) { - metrics.add(0, total); - } - return metrics; - } - public static List getDateMetrics(Repository r, boolean includeTotal) { - Metric total = new Metric("TOTAL"); - final Map metricMap = new HashMap(); - if (JGitUtils.hasCommits(r)) { final List tags = JGitUtils.getTags(r, -1); final Map tagMap = new HashMap(); @@ -90,25 +52,31 @@ public class MetricUtils { try { RevWalk walk = new RevWalk(r); ObjectId object = r.resolve(Constants.HEAD); - - RevCommit firstCommit = JGitUtils.getFirstCommit(r, Constants.HEAD); RevCommit lastCommit = walk.parseCommit(object); - int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime()) - / (60 * 60 * 24); - total.duration = diffDays; + walk.markStart(lastCommit); + DateFormat df; - if (diffDays <= 90) { - // Days - df = new SimpleDateFormat("yyyy-MM-dd"); - } else if (diffDays > 90 && diffDays < 365) { - // Weeks - df = new SimpleDateFormat("yyyy-MM (w)"); + if (StringUtils.isEmpty(format)) { + // dynamically determine date format + RevCommit firstCommit = JGitUtils.getFirstCommit(r, Constants.HEAD); + int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime()) + / (60 * 60 * 24); + total.duration = diffDays; + if (diffDays <= 90) { + // Days + df = new SimpleDateFormat("yyyy-MM-dd"); + } else if (diffDays > 90 && diffDays < 365) { + // Weeks + df = new SimpleDateFormat("yyyy-MM (w)"); + } else { + // Months + df = new SimpleDateFormat("yyyy-MM"); + } } else { - // Months - df = new SimpleDateFormat("yyyy-MM"); + // use specified date format + df = new SimpleDateFormat(format); } - walk.markStart(lastCommit); - + Iterable revlog = walk; for (RevCommit rev : revlog) { Date d = JGitUtils.getCommitDate(rev); @@ -125,7 +93,7 @@ public class MetricUtils { } } } catch (Throwable t) { - JGitUtils.LOGGER.error("Failed to mine log history for metrics", t); + LOGGER.error("Failed to mine log history for date metrics", t); } } List keys = new ArrayList(metricMap.keySet()); @@ -140,32 +108,38 @@ public class MetricUtils { return metrics; } - public static List getAuthorMetrics(Repository r) { - Metric total = new Metric("TOTAL"); + public static List getAuthorMetrics(Repository r, boolean byEmail) { final Map metricMap = new HashMap(); - + if (JGitUtils.hasCommits(r)) { try { RevWalk walk = new RevWalk(r); ObjectId object = r.resolve(Constants.HEAD); RevCommit lastCommit = walk.parseCommit(object); walk.markStart(lastCommit); - + Iterable revlog = walk; for (RevCommit rev : revlog) { - String p = rev.getAuthorIdent().getName(); - if (StringUtils.isEmpty(p)) { + String p; + if (byEmail) { p = rev.getAuthorIdent().getEmailAddress(); + if (StringUtils.isEmpty(p)) { + p = rev.getAuthorIdent().getName(); + } + } else { + p = rev.getAuthorIdent().getName(); + if (StringUtils.isEmpty(p)) { + p = rev.getAuthorIdent().getEmailAddress(); + } } if (!metricMap.containsKey(p)) { metricMap.put(p, new Metric(p)); } Metric m = metricMap.get(p); m.count++; - total.count++; } } catch (Throwable t) { - JGitUtils.LOGGER.error("Failed to mine log history for metrics", t); + LOGGER.error("Failed to mine log history for author metrics", t); } } List keys = new ArrayList(metricMap.keySet()); diff --git a/src/com/gitblit/utils/StringUtils.java b/src/com/gitblit/utils/StringUtils.java index fd6ca98b..2a10a59a 100644 --- a/src/com/gitblit/utils/StringUtils.java +++ b/src/com/gitblit/utils/StringUtils.java @@ -134,4 +134,12 @@ public class StringUtils { } return ""; } + + public static String getRelativePath(String basePath, String fullPath) { + String relativePath = fullPath.substring(basePath.length()).replace('\\', '/'); + if (relativePath.charAt(0) == '/') { + relativePath = relativePath.substring(1); + } + return relativePath; + } } diff --git a/src/com/gitblit/utils/TicgitUtils.java b/src/com/gitblit/utils/TicgitUtils.java index 914b8139..576de349 100644 --- a/src/com/gitblit/utils/TicgitUtils.java +++ b/src/com/gitblit/utils/TicgitUtils.java @@ -61,6 +61,9 @@ public class TicgitUtils { public static List getTickets(Repository r) { RefModel ticgitBranch = getTicketsBranch(r); + if (ticgitBranch == null) { + return null; + } List paths = JGitUtils.getFilesInPath(r, null, ticgitBranch.commit); List tickets = new ArrayList(); for (PathModel ticketFolder : paths) { @@ -112,7 +115,7 @@ public class TicgitUtils { Comment c = new Comment(file.name, content); ticket.comments.add(c); } catch (ParseException e) { - e.printStackTrace(); + LOGGER.error("Failed to parse ticket comment", e); } } else if (chunks[0].equals("TAG")) { if (content.startsWith("TAG_")) { @@ -127,12 +130,4 @@ public class TicgitUtils { } Collections.sort(ticket.comments); } - - public static String getTicketContent(Repository r, String filePath) { - RefModel ticketsBranch = getTicketsBranch(r); - if (ticketsBranch != null) { - return JGitUtils.getRawContentAsString(r, ticketsBranch.commit, filePath); - } - return ""; - } } diff --git a/src/com/gitblit/wicket/pages/BlobDiffPage.java b/src/com/gitblit/wicket/pages/BlobDiffPage.java index b94da011..a8f8b3c1 100644 --- a/src/com/gitblit/wicket/pages/BlobDiffPage.java +++ b/src/com/gitblit/wicket/pages/BlobDiffPage.java @@ -24,8 +24,8 @@ import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.utils.DiffUtils; +import com.gitblit.utils.DiffUtils.DiffOutputType; import com.gitblit.utils.JGitUtils; -import com.gitblit.utils.JGitUtils.DiffOutputType; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; diff --git a/src/com/gitblit/wicket/pages/CommitDiffPage.java b/src/com/gitblit/wicket/pages/CommitDiffPage.java index e7af833d..4815b2c7 100644 --- a/src/com/gitblit/wicket/pages/CommitDiffPage.java +++ b/src/com/gitblit/wicket/pages/CommitDiffPage.java @@ -32,8 +32,8 @@ import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.utils.DiffUtils; +import com.gitblit.utils.DiffUtils.DiffOutputType; import com.gitblit.utils.JGitUtils; -import com.gitblit.utils.JGitUtils.DiffOutputType; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; import com.gitblit.wicket.panels.CommitLegendPanel; diff --git a/src/com/gitblit/wicket/pages/CommitPage.html b/src/com/gitblit/wicket/pages/CommitPage.html index 1b5fffed..bd317b7a 100644 --- a/src/com/gitblit/wicket/pages/CommitPage.html +++ b/src/com/gitblit/wicket/pages/CommitPage.html @@ -44,6 +44,14 @@
[commit message]
+ + + + + + +


+
diff --git a/src/com/gitblit/wicket/pages/CommitPage.java b/src/com/gitblit/wicket/pages/CommitPage.java index bc0d8792..3af9cf1d 100644 --- a/src/com/gitblit/wicket/pages/CommitPage.java +++ b/src/com/gitblit/wicket/pages/CommitPage.java @@ -18,6 +18,7 @@ package com.gitblit.wicket.pages; import java.util.ArrayList; import java.util.List; +import org.apache.wicket.Component; import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; @@ -33,8 +34,10 @@ import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.DownloadZipServlet; import com.gitblit.GitBlit; import com.gitblit.Keys; +import com.gitblit.models.GitNote; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.StringUtils; import com.gitblit.utils.JGitUtils.SearchType; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.panels.CommitHeaderPanel; @@ -112,6 +115,27 @@ public class CommitPage extends RepositoryPage { addFullText("fullMessage", c.getFullMessage(), true); + // git notes + List notes = JGitUtils.getNotesOnCommit(r, c); + ListDataProvider notesDp = new ListDataProvider(notes); + DataView notesView = new DataView("notes", notesDp) { + private static final long serialVersionUID = 1L; + + public void populateItem(final Item item) { + GitNote entry = item.getModelObject(); + Component c = new LinkPanel("refName", null, entry.notesRef.displayName, + CommitPage.class, newCommitParameter(entry.notesRef.commit.getName())); + WicketUtils.setCssClass(c, "headRef"); + item.add(c); + item.add(createPersonPanel("authorName", entry.notesRef.commit.getAuthorIdent(), SearchType.AUTHOR)); + item.add(WicketUtils.createTimestampLabel("authorDate", + entry.notesRef.commit.getAuthorIdent().getWhen(), getTimeZone())); + item.add(new Label("noteContent", StringUtils.breakLinesForHtml(entry.content)).setEscapeModelStrings(false)); + } + }; + add(notesView.setVisible(notes.size() > 0)); + + // changed paths list List paths = JGitUtils.getFilesInCommit(r, c); add(new CommitLegendPanel("commitLegend", paths)); diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java index eb2a8e64..e5496a1a 100644 --- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java +++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java @@ -19,7 +19,6 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -104,6 +103,22 @@ public class EditRepositoryPage extends BasePage { // automatically convert backslashes to forward slashes repositoryModel.name = repositoryModel.name.replace('\\', '/'); + // Automatically replace // with / + repositoryModel.name = repositoryModel.name.replace("//", "/"); + + // prohibit folder paths + if (repositoryModel.name.startsWith("/")) { + error("Leading root folder references (/) are prohibited."); + return; + } + if (repositoryModel.name.startsWith("../")) { + error("Relative folder references (../) are prohibited."); + return; + } + if (repositoryModel.name.contains("/../")) { + error("Relative folder references (../) are prohibited."); + return; + } // confirm valid characters in repository name char[] validChars = { '/', '.', '_', '-' }; @@ -120,7 +135,7 @@ public class EditRepositoryPage extends BasePage { } } } - + // confirm access restriction selection if (repositoryModel.accessRestriction == null) { error("Please select access restriction!"); diff --git a/src/com/gitblit/wicket/pages/MetricsPage.java b/src/com/gitblit/wicket/pages/MetricsPage.java index 2186ae37..c6231e9d 100644 --- a/src/com/gitblit/wicket/pages/MetricsPage.java +++ b/src/com/gitblit/wicket/pages/MetricsPage.java @@ -47,7 +47,7 @@ public class MetricsPage extends RepositoryPage { public MetricsPage(PageParameters params) { super(params); Repository r = getRepository(); - insertLinePlot("commitsChart", MetricUtils.getDateMetrics(r, false)); + insertLinePlot("commitsChart", MetricUtils.getDateMetrics(r, false, null)); insertBarPlot("dayOfWeekChart", getDayOfWeekMetrics(r)); insertLinePlot("timeOfDayChart", getTimeOfDayMetrics(r)); insertPieChart("authorsChart", getAuthorMetrics(r)); @@ -57,7 +57,7 @@ public class MetricsPage extends RepositoryPage { if ((metrics != null) && (metrics.size() > 0)) { IChartData data = WicketUtils.getChartData(metrics); - ChartProvider provider = new ChartProvider(new Dimension(400, 100), ChartType.LINE, + ChartProvider provider = new ChartProvider(new Dimension(500, 100), ChartType.LINE, data); ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); dateAxis.setLabels(new String[] { metrics.get(0).name, @@ -82,7 +82,7 @@ public class MetricsPage extends RepositoryPage { if ((metrics != null) && (metrics.size() > 0)) { IChartData data = WicketUtils.getChartData(metrics); - ChartProvider provider = new ChartProvider(new Dimension(400, 100), + ChartProvider provider = new ChartProvider(new Dimension(500, 100), ChartType.BAR_VERTICAL_SET, data); ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); List labels = new ArrayList(); @@ -110,7 +110,7 @@ public class MetricsPage extends RepositoryPage { for (Metric metric : metrics) { labels.add(metric.name); } - ChartProvider provider = new ChartProvider(new Dimension(400, 200), ChartType.PIE, data); + ChartProvider provider = new ChartProvider(new Dimension(500, 200), ChartType.PIE, data); provider.setPieLabels(labels.toArray(new String[labels.size()])); add(new Chart(wicketId, provider)); } else { @@ -164,7 +164,7 @@ public class MetricsPage extends RepositoryPage { } private List getAuthorMetrics(Repository repository) { - List authors = MetricUtils.getAuthorMetrics(repository); + List authors = MetricUtils.getAuthorMetrics(repository, true); Collections.sort(authors, new Comparator() { @Override public int compare(Metric o1, Metric o2) { diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java index c054fcca..a2d36d2e 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/com/gitblit/wicket/pages/SummaryPage.java @@ -77,7 +77,7 @@ public class SummaryPage extends RepositoryPage { List metrics = null; Metric metricsTotal = null; if (GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) { - metrics = MetricUtils.getDateMetrics(r, true); + metrics = MetricUtils.getDateMetrics(r, true, null); metricsTotal = metrics.remove(0); } diff --git a/src/com/gitblit/wicket/panels/CommitLegendPanel.java b/src/com/gitblit/wicket/panels/CommitLegendPanel.java index bbfa1855..d875233a 100644 --- a/src/com/gitblit/wicket/panels/CommitLegendPanel.java +++ b/src/com/gitblit/wicket/panels/CommitLegendPanel.java @@ -17,6 +17,7 @@ package com.gitblit.wicket.panels; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -29,7 +30,6 @@ import org.apache.wicket.markup.repeater.data.ListDataProvider; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import com.gitblit.models.PathModel.PathChangeModel; -import com.gitblit.utils.JGitUtils; import com.gitblit.wicket.WicketUtils; public class CommitLegendPanel extends Panel { @@ -38,7 +38,7 @@ public class CommitLegendPanel extends Panel { public CommitLegendPanel(String id, List paths) { super(id); - final Map stats = JGitUtils.getChangedPathsStats(paths); + final Map stats = getChangedPathsStats(paths); ListDataProvider legendDp = new ListDataProvider( new ArrayList(stats.keySet())); DataView legendsView = new DataView("legend", legendDp) { @@ -74,4 +74,15 @@ public class CommitLegendPanel extends Panel { }; add(legendsView); } + + protected Map getChangedPathsStats(List paths) { + Map stats = new HashMap(); + for (PathChangeModel path : paths) { + if (!stats.containsKey(path.changeType)) { + stats.put(path.changeType, new AtomicInteger(0)); + } + stats.get(path.changeType).incrementAndGet(); + } + return stats; + } } \ No newline at end of file diff --git a/tests/com/gitblit/tests/DiffUtilsTest.java b/tests/com/gitblit/tests/DiffUtilsTest.java index 34cb8533..e60a2a4e 100644 --- a/tests/com/gitblit/tests/DiffUtilsTest.java +++ b/tests/com/gitblit/tests/DiffUtilsTest.java @@ -21,8 +21,8 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.utils.DiffUtils; +import com.gitblit.utils.DiffUtils.DiffOutputType; import com.gitblit.utils.JGitUtils; -import com.gitblit.utils.JGitUtils.DiffOutputType; public class DiffUtilsTest extends TestCase { diff --git a/tests/com/gitblit/tests/GitBlitSuite.java b/tests/com/gitblit/tests/GitBlitSuite.java index fcb57239..97e46c9c 100644 --- a/tests/com/gitblit/tests/GitBlitSuite.java +++ b/tests/com/gitblit/tests/GitBlitSuite.java @@ -28,7 +28,9 @@ import org.eclipse.jgit.storage.file.FileRepository; import com.gitblit.FileSettings; import com.gitblit.GitBlit; +import com.gitblit.GitBlitException; import com.gitblit.JettyLoginService; +import com.gitblit.models.RepositoryModel; public class GitBlitSuite extends TestSetup { public static final File REPOSITORIES = new File("git"); @@ -42,6 +44,7 @@ public class GitBlitSuite extends TestSetup { suite.addTestSuite(TimeUtilsTest.class); suite.addTestSuite(StringUtilsTest.class); suite.addTestSuite(ByteFormatTest.class); + suite.addTestSuite(MarkdownUtilsTest.class); suite.addTestSuite(JGitUtilsTest.class); suite.addTestSuite(DiffUtilsTest.class); suite.addTestSuite(MetricUtilsTest.class); @@ -60,16 +63,21 @@ public class GitBlitSuite extends TestSetup { @Override protected void setUp() throws Exception { - if (REPOSITORIES.exists() || REPOSITORIES.mkdirs()) { - cloneOrFetch("helloworld.git", "https://github.com/git/hello-world.git", true); - cloneOrFetch("nested/helloworld.git", "https://github.com/git/hello-world.git", true); - cloneOrFetch("ticgit.git", "https://github.com/jeffWelling/ticgit.git", true); - } FileSettings settings = new FileSettings("distrib/gitblit.properties"); GitBlit.self().configureContext(settings); JettyLoginService loginService = new JettyLoginService(new File("distrib/users.properties")); loginService.loadUsers(); GitBlit.self().setLoginService(loginService); + + if (REPOSITORIES.exists() || REPOSITORIES.mkdirs()) { + cloneOrFetch("helloworld.git", "https://github.com/git/hello-world.git", true); + cloneOrFetch("nested/helloworld.git", "https://github.com/git/hello-world.git", true); + cloneOrFetch("ticgit.git", "https://github.com/jeffWelling/ticgit.git", true); + + enableTickets("ticgit.git"); + enableDocs("ticgit.git"); + showRemoteBranches("ticgit.git"); + } } private void cloneOrFetch(String toFolder, String fromUrl, boolean bare) throws Exception { @@ -92,4 +100,34 @@ public class GitBlitSuite extends TestSetup { System.out.println("done."); } } + + private void enableTickets(String repositoryName) { + try { + RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName); + model.useTickets = true; + GitBlit.self().editRepositoryModel(model.name, model, false); + } catch (GitBlitException g) { + g.printStackTrace(); + } + } + + private void enableDocs(String repositoryName) { + try { + RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName); + model.useDocs = true; + GitBlit.self().editRepositoryModel(model.name, model, false); + } catch (GitBlitException g) { + g.printStackTrace(); + } + } + + private void showRemoteBranches(String repositoryName) { + try { + RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName); + model.showRemoteBranches = true; + GitBlit.self().editRepositoryModel(model.name, model, false); + } catch (GitBlitException g) { + g.printStackTrace(); + } + } } diff --git a/tests/com/gitblit/tests/JGitUtilsTest.java b/tests/com/gitblit/tests/JGitUtilsTest.java index f1dcaac4..6afa38b2 100644 --- a/tests/com/gitblit/tests/JGitUtilsTest.java +++ b/tests/com/gitblit/tests/JGitUtilsTest.java @@ -17,25 +17,41 @@ package com.gitblit.tests; import java.io.File; import java.io.FileOutputStream; +import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Map; import junit.framework.TestCase; +import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.revwalk.RevObject; -import org.eclipse.jgit.revwalk.RevTree; import com.gitblit.GitBlit; +import com.gitblit.Keys; +import com.gitblit.models.PathModel; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.JGitUtils.SearchType; public class JGitUtilsTest extends TestCase { + public void testDisplayName() throws Exception { + assertTrue(JGitUtils.getDisplayName(new PersonIdent("Napoleon Bonaparte", "")).equals( + "Napoleon Bonaparte")); + assertTrue(JGitUtils.getDisplayName(new PersonIdent("", "someone@somewhere.com")).equals( + "")); + assertTrue(JGitUtils.getDisplayName( + new PersonIdent("Napoleon Bonaparte", "someone@somewhere.com")).equals( + "Napoleon Bonaparte ")); + } + public void testFindRepositories() { List list = JGitUtils.getRepositoryList(null, true, true); assertTrue(list.size() == 0); @@ -53,7 +69,7 @@ public class JGitUtilsTest extends TestCase { public void testFirstCommit() throws Exception { assertTrue(JGitUtils.getFirstChange(null, null).equals(new Date(0))); - + Repository repository = GitBlitSuite.getHelloworldRepository(); RevCommit commit = JGitUtils.getFirstCommit(repository, null); Date firstChange = JGitUtils.getFirstChange(repository, null); @@ -63,10 +79,10 @@ public class JGitUtilsTest extends TestCase { commit.getName().equals("f554664a346629dc2b839f7292d06bad2db4aece")); assertTrue(firstChange.equals(new Date(commit.getCommitTime() * 1000L))); } - + public void testLastCommit() throws Exception { assertTrue(JGitUtils.getLastChange(null).equals(new Date(0))); - + Repository repository = GitBlitSuite.getHelloworldRepository(); assertTrue(JGitUtils.getCommit(repository, null) != null); Date date = JGitUtils.getLastChange(repository); @@ -74,8 +90,6 @@ public class JGitUtilsTest extends TestCase { assertTrue("Could not get last repository change date!", date != null); } - - public void testCreateRepository() throws Exception { String[] repositories = { "NewTestRepository.git", "NewTestRepository" }; for (String repositoryName : repositories) { @@ -84,17 +98,16 @@ public class JGitUtilsTest extends TestCase { repositoryName, isBare); File folder; if (isBare) { - folder = new File(GitBlitSuite.REPOSITORIES, repositoryName); + folder = new File(GitBlitSuite.REPOSITORIES, repositoryName); } else { folder = new File(GitBlitSuite.REPOSITORIES, repositoryName + "/.git"); - } + } assertTrue(repository != null); assertFalse(JGitUtils.hasCommits(repository)); assertTrue(JGitUtils.getFirstCommit(repository, null) == null); assertTrue(JGitUtils.getFirstChange(repository, null).getTime() == folder .lastModified()); - assertTrue(JGitUtils.getLastChange(repository).getTime() == folder - .lastModified()); + assertTrue(JGitUtils.getLastChange(repository).getTime() == folder.lastModified()); assertTrue(JGitUtils.getCommit(repository, null) == null); repository.close(); assertTrue(GitBlit.self().deleteRepository(repositoryName)); @@ -102,6 +115,13 @@ public class JGitUtilsTest extends TestCase { } public void testRefs() throws Exception { + Repository repository = GitBlitSuite.getTicgitRepository(); + Map> map = JGitUtils.getAllRefs(repository); + repository.close(); + assertTrue(map.size() > 0); + } + + public void testBranches() throws Exception { Repository repository = GitBlitSuite.getTicgitRepository(); for (RefModel model : JGitUtils.getLocalBranches(repository, -1)) { assertTrue(model.getName().startsWith(Constants.R_HEADS)); @@ -119,6 +139,12 @@ public class JGitUtilsTest extends TestCase { + model.getName().hashCode()); assertTrue(model.getShortLog().equals(model.commit.getShortMessage())); } + assertTrue(JGitUtils.getRemoteBranches(repository, 10).size() == 10); + repository.close(); + } + + public void testTags() throws Exception { + Repository repository = GitBlitSuite.getTicgitRepository(); for (RefModel model : JGitUtils.getTags(repository, -1)) { if (model.getObjectId().getName().equals("283035e4848054ff1803cb0e690270787dc92399")) { assertTrue("Not an annotated tag!", model.isAnnotatedTag()); @@ -133,23 +159,26 @@ public class JGitUtilsTest extends TestCase { repository.close(); } - public void testRetrieveRevObject() throws Exception { - Repository repository = GitBlitSuite.getHelloworldRepository(); - RevCommit commit = JGitUtils.getCommit(repository, Constants.HEAD); - RevTree tree = commit.getTree(); - RevObject object = JGitUtils.getRevObject(repository, tree, "java.java"); - repository.close(); - assertTrue("Object is null!", object != null); + public void testCommitNotes() throws Exception { +// Repository repository = new FileRepository(new File("c:/projects/git/jgit.git/.git")); +// RevCommit commit = JGitUtils.getCommit(repository, +// "ada903085d1b4ef8c79e3e2d91f49fee7e188f53"); +// List list = JGitUtils.getNotesOnCommit(repository, commit); +// repository.close(); +// assertTrue(list.size() > 0); } - public void testRetrieveStringContent() throws Exception { + public void testStringContent() throws Exception { Repository repository = GitBlitSuite.getHelloworldRepository(); + String contentA = JGitUtils.getRawContentAsString(repository, null, "java.java"); RevCommit commit = JGitUtils.getCommit(repository, Constants.HEAD); - RevTree tree = commit.getTree(); - RevBlob blob = (RevBlob) JGitUtils.getRevObject(repository, tree, "java.java"); - String content = JGitUtils.getRawContentAsString(repository, blob); + String contentB = JGitUtils.getRawContentAsString(repository, commit, "java.java"); + String contentC = JGitUtils.getRawContentAsString(repository, commit, "missing.txt"); repository.close(); - assertTrue("Content is null!", content != null && content.length() > 0); + assertTrue("ContentA is null!", contentA != null && contentA.length() > 0); + assertTrue("ContentB is null!", contentB != null && contentB.length() > 0); + assertTrue(contentA.equals(contentB)); + assertTrue(contentC == null); } public void testFilesInCommit() throws Exception { @@ -157,6 +186,15 @@ public class JGitUtilsTest extends TestCase { RevCommit commit = JGitUtils.getCommit(repository, "1d0c2933a4ae69c362f76797d42d6bd182d05176"); List paths = JGitUtils.getFilesInCommit(repository, commit); + + commit = JGitUtils.getCommit(repository, "af0e9b2891fda85afc119f04a69acf7348922830"); + List deletions = JGitUtils.getFilesInCommit(repository, commit); + + commit = JGitUtils.getFirstCommit(repository, null); + List additions = JGitUtils.getFilesInCommit(repository, commit); + + List latestChanges = JGitUtils.getFilesInCommit(repository, null); + repository.close(); assertTrue("No changed paths found!", paths.size() == 1); for (PathChangeModel path : paths) { @@ -165,17 +203,119 @@ public class JGitUtilsTest extends TestCase { assertTrue("PathChangeModel equals itself failed!", path.equals(path)); assertFalse("PathChangeModel equals string failed!", path.equals("")); } + assertTrue(deletions.get(0).changeType.equals(ChangeType.DELETE)); + assertTrue(additions.get(0).changeType.equals(ChangeType.ADD)); + assertTrue(latestChanges.size() > 0); + } + + public void testFilesInPath() throws Exception { + assertTrue(JGitUtils.getFilesInPath(null, null, null).size() == 0); + Repository repository = GitBlitSuite.getHelloworldRepository(); + List files = JGitUtils.getFilesInPath(repository, null, null); + repository.close(); + assertTrue(files.size() > 10); + } + + public void testDocuments() throws Exception { + Repository repository = GitBlitSuite.getTicgitRepository(); + List extensions = GitBlit.getStrings(Keys.web.markdownExtensions); + List markdownDocs = JGitUtils.getDocuments(repository, extensions); + List markdownDocs2 = JGitUtils.getDocuments(repository, + Arrays.asList(new String[] { ".mkd", ".md" })); + List allFiles = JGitUtils.getDocuments(repository, null); + repository.close(); + assertTrue(markdownDocs.size() > 0); + assertTrue(markdownDocs2.size() > 0); + assertTrue(allFiles.size() > markdownDocs.size()); + } + + public void testFileModes() throws Exception { + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.TREE.getBits()).equals("drwxr-xr-x")); + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.REGULAR_FILE.getBits()).equals( + "-rw-r--r--")); + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.EXECUTABLE_FILE.getBits()).equals( + "-rwxr-xr-x")); + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.SYMLINK.getBits()).equals("symlink")); + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.GITLINK.getBits()).equals("gitlink")); + assertTrue(JGitUtils.getPermissionsFromMode(FileMode.MISSING.getBits()).equals("missing")); + } + + public void testRevlog() throws Exception { + List commits = JGitUtils.getRevLog(null, 10); + assertTrue(commits.size() == 0); + + Repository repository = GitBlitSuite.getHelloworldRepository(); + // get most recent 10 commits + commits = JGitUtils.getRevLog(repository, 10); + assertTrue(commits.size() == 10); + + // test paging and offset by getting the 10th most recent commit + RevCommit lastCommit = JGitUtils.getRevLog(repository, null, 9, 1).get(0); + assertTrue(commits.get(9).equals(lastCommit)); + + // grab the two most recent commits to java.java + commits = JGitUtils.getRevLog(repository, null, "java.java", 0, 2); + assertTrue(commits.size() == 2); + repository.close(); + } + + public void testSearchTypes() throws Exception { + assertTrue(SearchType.forName("commit").equals(SearchType.COMMIT)); + assertTrue(SearchType.forName("committer").equals(SearchType.COMMITTER)); + assertTrue(SearchType.forName("author").equals(SearchType.AUTHOR)); + assertTrue(SearchType.forName("unknown").equals(SearchType.COMMIT)); + + assertTrue(SearchType.COMMIT.toString().equals("commit")); + assertTrue(SearchType.COMMITTER.toString().equals("committer")); + assertTrue(SearchType.AUTHOR.toString().equals("author")); + } + + public void testSearchRevlogs() throws Exception { + List results = JGitUtils.searchRevlogs(null, null, "java", SearchType.COMMIT, 0, + 3); + assertTrue(results.size() == 0); + + // test commit message search + Repository repository = GitBlitSuite.getHelloworldRepository(); + results = JGitUtils.searchRevlogs(repository, null, "java", SearchType.COMMIT, 0, 3); + assertTrue(results.size() == 3); + + // test author search + results = JGitUtils.searchRevlogs(repository, null, "timothy", SearchType.AUTHOR, 0, -1); + assertTrue(results.size() == 1); + + // test committer search + results = JGitUtils.searchRevlogs(repository, null, "mike", SearchType.COMMITTER, 0, 10); + assertTrue(results.size() == 10); + + // test paging and offset + RevCommit commit = JGitUtils.searchRevlogs(repository, null, "mike", SearchType.COMMITTER, + 9, 1).get(0); + assertTrue(results.get(9).equals(commit)); + + repository.close(); } public void testZip() throws Exception { + assertFalse(JGitUtils.zip(null, null, null, null)); Repository repository = GitBlitSuite.getHelloworldRepository(); - File zipFile = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip"); - FileOutputStream fos = new FileOutputStream(zipFile); - boolean success = JGitUtils.zip(repository, null, Constants.HEAD, fos); - assertTrue("Failed to generate zip file!", success); - assertTrue(zipFile.length() > 0); - fos.close(); - zipFile.delete(); + File zipFileA = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip"); + FileOutputStream fosA = new FileOutputStream(zipFileA); + boolean successA = JGitUtils.zip(repository, null, Constants.HEAD, fosA); + fosA.close(); + + File zipFileB = new File(GitBlitSuite.REPOSITORIES, "helloworld-java.zip"); + FileOutputStream fosB = new FileOutputStream(zipFileB); + boolean successB = JGitUtils.zip(repository, "java.java", Constants.HEAD, fosB); + fosB.close(); + repository.close(); + assertTrue("Failed to generate zip file!", successA); + assertTrue(zipFileA.length() > 0); + zipFileA.delete(); + + assertTrue("Failed to generate zip file!", successB); + assertTrue(zipFileB.length() > 0); + zipFileB.delete(); } } \ No newline at end of file diff --git a/tests/com/gitblit/tests/MarkdownUtilsTest.java b/tests/com/gitblit/tests/MarkdownUtilsTest.java new file mode 100644 index 00000000..2034bda3 --- /dev/null +++ b/tests/com/gitblit/tests/MarkdownUtilsTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2011 gitblit.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.gitblit.tests; + +import java.text.ParseException; + +import junit.framework.TestCase; + +import com.gitblit.utils.MarkdownUtils; + +public class MarkdownUtilsTest extends TestCase { + + public void testMarkdown() throws Exception { + assertTrue(MarkdownUtils.transformMarkdown("# H1").equals("

H1

")); + assertTrue(MarkdownUtils.transformMarkdown("## H2").equals("

H2

")); + try { + MarkdownUtils.transformMarkdown((String) null); + assertTrue(false); + } catch (ParseException p) { + assertTrue(p != null); + } + } +} \ No newline at end of file diff --git a/tests/com/gitblit/tests/MetricUtilsTest.java b/tests/com/gitblit/tests/MetricUtilsTest.java index 77f43a16..07cd6060 100644 --- a/tests/com/gitblit/tests/MetricUtilsTest.java +++ b/tests/com/gitblit/tests/MetricUtilsTest.java @@ -28,8 +28,17 @@ public class MetricUtilsTest extends TestCase { public void testMetrics() throws Exception { Repository repository = GitBlitSuite.getHelloworldRepository(); - List metrics = MetricUtils.getDateMetrics(repository, true); + List metrics = MetricUtils.getDateMetrics(repository, true, null); repository.close(); - assertTrue("No metrics found!", metrics.size() > 0); + assertTrue("No date metrics found!", metrics.size() > 0); + } + + public void testAuthorMetrics() throws Exception { + Repository repository = GitBlitSuite.getHelloworldRepository(); + List byEmail = MetricUtils.getAuthorMetrics(repository, true); + List byName = MetricUtils.getAuthorMetrics(repository, false); + repository.close(); + assertTrue("No author metrics found!", byEmail.size() == 9); + assertTrue("No author metrics found!", byName.size() == 8); } } \ No newline at end of file diff --git a/tests/com/gitblit/tests/TicgitUtilsTest.java b/tests/com/gitblit/tests/TicgitUtilsTest.java index 25dba2c6..792c4269 100644 --- a/tests/com/gitblit/tests/TicgitUtilsTest.java +++ b/tests/com/gitblit/tests/TicgitUtilsTest.java @@ -28,10 +28,20 @@ import com.gitblit.utils.TicgitUtils; public class TicgitUtilsTest extends TestCase { - public void testTicGit() throws Exception { + public void testTicgitBranch() throws Exception { Repository repository = GitBlitSuite.getTicgitRepository(); RefModel branch = TicgitUtils.getTicketsBranch(repository); + repository.close(); assertTrue("Ticgit branch does not exist!", branch != null); + + repository = GitBlitSuite.getHelloworldRepository(); + branch = TicgitUtils.getTicketsBranch(repository); + repository.close(); + assertTrue("Ticgit branch exists!", branch == null); + } + + public void testRetrieveTickets() throws Exception { + Repository repository = GitBlitSuite.getTicgitRepository(); List ticketsA = TicgitUtils.getTickets(repository); List ticketsB = TicgitUtils.getTickets(repository); repository.close(); @@ -50,5 +60,21 @@ public class TicgitUtilsTest extends TestCase { assertTrue(commentA.hashCode() == commentA.text.hashCode()); } } + + repository = GitBlitSuite.getHelloworldRepository(); + List ticketsC = TicgitUtils.getTickets(repository); + repository.close(); + assertTrue(ticketsC == null); + } + + public void testReadTicket() throws Exception { + Repository repository = GitBlitSuite.getTicgitRepository(); + List tickets = TicgitUtils.getTickets(repository); + TicketModel ticket = TicgitUtils + .getTicket(repository, tickets.get(tickets.size() - 1).name); + repository.close(); + assertTrue(ticket != null); + assertTrue(ticket.name + .equals("1254123752_comments-on-ticgits-longer-than-5-lines-can-t-be-viewed-entirely_266")); } } \ No newline at end of file -- 2.39.5