From 357109c5a5518db5925f49a6700a87e7ed30ca14 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Wed, 28 Dec 2011 16:19:29 -0500
Subject: [PATCH] Unit testing. Documentation.
---
src/com/gitblit/utils/MetricUtils.java | 196 ++++++++++++++++++++++++++++++------------------
1 files changed, 123 insertions(+), 73 deletions(-)
diff --git a/src/com/gitblit/utils/MetricUtils.java b/src/com/gitblit/utils/MetricUtils.java
index b1da273..2919b15 100644
--- a/src/com/gitblit/utils/MetricUtils.java
+++ b/src/com/gitblit/utils/MetricUtils.java
@@ -16,6 +16,7 @@
package com.gitblit.utils;
import java.text.DateFormat;
+import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,7 +25,6 @@
import java.util.List;
import java.util.Map;
-import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -35,81 +35,103 @@
import com.gitblit.models.Metric;
import com.gitblit.models.RefModel;
+/**
+ * Utility class for collecting metrics on a branch, tag, or other ref within
+ * the repository.
+ *
+ * @author James Moger
+ *
+ */
public class MetricUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(MetricUtils.class);
- public static List<Metric> getDateMetrics(Repository r, boolean includeTotal, String format) {
- Metric total = new Metric("TOTAL");
- final Map<String, Metric> metricMap = new HashMap<String, Metric>();
-
- 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<RevCommit> 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);
+ /**
+ * Log an error message and exception.
+ *
+ * @param t
+ * @param repository
+ * if repository is not null it MUST be the {0} parameter in the
+ * pattern.
+ * @param pattern
+ * @param objects
+ */
+ private static void error(Throwable t, Repository repository, String pattern, Object... objects) {
+ List<Object> parameters = new ArrayList<Object>();
+ if (objects != null && objects.length > 0) {
+ for (Object o : objects) {
+ parameters.add(o);
}
}
- List<String> keys = new ArrayList<String>(metricMap.keySet());
- Collections.sort(keys);
- List<Metric> metrics = new ArrayList<Metric>();
- for (String key : keys) {
- metrics.add(metricMap.get(key));
+ if (repository != null) {
+ parameters.add(0, repository.getDirectory().getAbsolutePath());
}
- if (includeTotal) {
- metrics.add(0, total);
- }
- return metrics;
+ LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t);
}
- public static List<Metric> getDateMetrics(Repository r, boolean includeTotal) {
+ /**
+ * Returns the list of metrics for the specified commit reference, branch,
+ * or tag within the repository. If includeTotal is true, the total of all
+ * the metrics will be included as the first element in the returned list.
+ *
+ * If the dateformat is unspecified an attempt is made to determine an
+ * appropriate date format by determining the time difference between the
+ * first commit on the branch and the most recent commit. This assumes that
+ * the commits are linear.
+ *
+ * @param repository
+ * @param objectId
+ * if null or empty, HEAD is assumed.
+ * @param includeTotal
+ * @param dateFormat
+ * @return list of metrics
+ */
+ public static List<Metric> getDateMetrics(Repository repository, String objectId,
+ boolean includeTotal, String dateFormat) {
Metric total = new Metric("TOTAL");
final Map<String, Metric> metricMap = new HashMap<String, Metric>();
-
- if (JGitUtils.hasCommits(r)) {
- final List<RefModel> tags = JGitUtils.getTags(r, -1);
+
+ if (JGitUtils.hasCommits(repository)) {
+ final List<RefModel> tags = JGitUtils.getTags(repository, true, -1);
final Map<ObjectId, RefModel> tagMap = new HashMap<ObjectId, RefModel>();
for (RefModel tag : tags) {
- tagMap.put(tag.getCommitId(), tag);
+ tagMap.put(tag.getReferencedObjectId(), tag);
}
+ RevWalk revWalk = null;
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;
- 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)");
+ // resolve branch
+ ObjectId branchObject;
+ if (StringUtils.isEmpty(objectId)) {
+ branchObject = JGitUtils.getDefaultBranch(repository);
} else {
- // Months
- df = new SimpleDateFormat("yyyy-MM");
+ branchObject = repository.resolve(objectId);
}
- walk.markStart(lastCommit);
-
- Iterable<RevCommit> revlog = walk;
+
+ revWalk = new RevWalk(repository);
+ RevCommit lastCommit = revWalk.parseCommit(branchObject);
+ revWalk.markStart(lastCommit);
+
+ DateFormat df;
+ if (StringUtils.isEmpty(dateFormat)) {
+ // dynamically determine date format
+ RevCommit firstCommit = JGitUtils.getFirstCommit(repository,
+ branchObject.getName());
+ int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime())
+ / (60 * 60 * 24);
+ total.duration = diffDays;
+ if (diffDays <= 365) {
+ // Days
+ df = new SimpleDateFormat("yyyy-MM-dd");
+ } else {
+ // Months
+ df = new SimpleDateFormat("yyyy-MM");
+ }
+ } else {
+ // use specified date format
+ df = new SimpleDateFormat(dateFormat);
+ }
+
+ Iterable<RevCommit> revlog = revWalk;
for (RevCommit rev : revlog) {
Date d = JGitUtils.getCommitDate(rev);
String p = df.format(d);
@@ -125,7 +147,12 @@
}
}
} catch (Throwable t) {
- JGitUtils.LOGGER.error("Failed to mine log history for metrics", t);
+ error(t, repository, "{0} failed to mine log history for date metrics of {1}",
+ objectId);
+ } finally {
+ if (revWalk != null) {
+ revWalk.dispose();
+ }
}
}
List<String> keys = new ArrayList<String>(metricMap.keySet());
@@ -140,32 +167,55 @@
return metrics;
}
- public static List<Metric> getAuthorMetrics(Repository r) {
- Metric total = new Metric("TOTAL");
+ /**
+ * Returns a list of author metrics for the specified repository.
+ *
+ * @param repository
+ * @param objectId
+ * if null or empty, HEAD is assumed.
+ * @param byEmailAddress
+ * group metrics by author email address otherwise by author name
+ * @return list of metrics
+ */
+ public static List<Metric> getAuthorMetrics(Repository repository, String objectId,
+ boolean byEmailAddress) {
final Map<String, Metric> metricMap = new HashMap<String, Metric>();
-
- if (JGitUtils.hasCommits(r)) {
+ if (JGitUtils.hasCommits(repository)) {
try {
- RevWalk walk = new RevWalk(r);
- ObjectId object = r.resolve(Constants.HEAD);
- RevCommit lastCommit = walk.parseCommit(object);
+ RevWalk walk = new RevWalk(repository);
+ // resolve branch
+ ObjectId branchObject;
+ if (StringUtils.isEmpty(objectId)) {
+ branchObject = JGitUtils.getDefaultBranch(repository);
+ } else {
+ branchObject = repository.resolve(objectId);
+ }
+ RevCommit lastCommit = walk.parseCommit(branchObject);
walk.markStart(lastCommit);
-
+
Iterable<RevCommit> revlog = walk;
for (RevCommit rev : revlog) {
- String p = rev.getAuthorIdent().getName();
- if (StringUtils.isEmpty(p)) {
- p = rev.getAuthorIdent().getEmailAddress();
+ String p;
+ if (byEmailAddress) {
+ p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
+ if (StringUtils.isEmpty(p)) {
+ p = rev.getAuthorIdent().getName().toLowerCase();
+ }
+ } else {
+ p = rev.getAuthorIdent().getName().toLowerCase();
+ if (StringUtils.isEmpty(p)) {
+ p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
+ }
}
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);
+ error(t, repository, "{0} failed to mine log history for author metrics of {1}",
+ objectId);
}
}
List<String> keys = new ArrayList<String>(metricMap.keySet());
--
Gitblit v1.9.1