From: James Moger Date: Wed, 20 Apr 2011 11:53:15 +0000 (-0400) Subject: Tag diamonds and sliding date scale on activity graph. X-Git-Tag: v0.5.0~72 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=45c0d6ed8c9c3afc4d09200358ee2d53f06023e2;p=gitblit.git Tag diamonds and sliding date scale on activity graph. --- diff --git a/contrib/com/codecommit/wicket/LineStyle.java b/contrib/com/codecommit/wicket/LineStyle.java index 0b1eade7..ef53c5b7 100644 --- a/contrib/com/codecommit/wicket/LineStyle.java +++ b/contrib/com/codecommit/wicket/LineStyle.java @@ -3,10 +3,15 @@ */ package com.codecommit.wicket; +import java.io.Serializable; + /** * @author Daniel Spiewak */ -public class LineStyle implements ILineStyle { +public class LineStyle implements ILineStyle, Serializable { + + private static final long serialVersionUID = 1L; + private int blankLength = -1; private int segmentLength = -1; private int thickness = -1; diff --git a/contrib/com/codecommit/wicket/MarkerType.java b/contrib/com/codecommit/wicket/MarkerType.java index d14ff543..2b227949 100644 --- a/contrib/com/codecommit/wicket/MarkerType.java +++ b/contrib/com/codecommit/wicket/MarkerType.java @@ -3,10 +3,12 @@ */ package com.codecommit.wicket; +import java.io.Serializable; + /** * @author Daniel Spiewak */ -public enum MarkerType { +public enum MarkerType implements Serializable { ARROW("a"), CROSS("c"), DIAMOND("d"), diff --git a/contrib/com/codecommit/wicket/ShapeMarker.java b/contrib/com/codecommit/wicket/ShapeMarker.java index 88d1aa14..3b42cfb2 100644 --- a/contrib/com/codecommit/wicket/ShapeMarker.java +++ b/contrib/com/codecommit/wicket/ShapeMarker.java @@ -4,11 +4,15 @@ package com.codecommit.wicket; import java.awt.Color; +import java.io.Serializable; /** * @author Daniel Spiewak */ -public class ShapeMarker implements IShapeMarker { +public class ShapeMarker implements IShapeMarker, Serializable { + + private static final long serialVersionUID = 1L; + private Color color; private int index = -1; private double point = -1; diff --git a/gitblit.properties b/gitblit.properties index a81e5f61..27a9fff9 100644 --- a/gitblit.properties +++ b/gitblit.properties @@ -65,7 +65,7 @@ web.generateActivityGraph = true # The number of commits to display on the summary page # Value must exceed 0 else default of 20 is used -web.summaryCommitCount = 20 +web.summaryCommitCount = 16 # The number of tags/heads to display on the summary page # Value must exceed 0 else default of 5 is used @@ -130,11 +130,11 @@ server.httpsPort = 443 # Specify the interface for Jetty to bind the standard connector. # You may specify an ip or an empty value to bind to all interfaces. -server.httpBindInterface = +server.httpBindInterface = localhost # Specify the interface for Jetty to bind the secure connector. # You may specify an ip or an empty value to bind to all interfaces. -server.httpsBindInterface = +server.httpsBindInterface = localhost # Password for SSL keystore (keystore password and certificate password must match) server.storePassword = dosomegit diff --git a/src/com/gitblit/tests/JGitUtilsTest.java b/src/com/gitblit/tests/JGitUtilsTest.java index 0ebcd71e..f3c798f1 100644 --- a/src/com/gitblit/tests/JGitUtilsTest.java +++ b/src/com/gitblit/tests/JGitUtilsTest.java @@ -50,6 +50,14 @@ public class JGitUtilsTest extends TestCase { r.close(); assertTrue("Could not get last repository change date!", date != null); } + + public void testFirstCommit() throws Exception { + Repository r = getRepository(); + RevCommit commit = JGitUtils.getFirstCommit(r, null); + r.close(); + assertTrue("Could not get first commit!", commit != null); + System.out.println(commit.getName() + " " + commit.getShortMessage()); + } public void testRetrieveRevObject() throws Exception { Repository r = getRepository(); diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index b1267685..daeb6389 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -36,6 +36,7 @@ import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.RevFilter; @@ -101,6 +102,34 @@ public class JGitUtils { return list; } + public static RevCommit getFirstCommit(Repository r, String branch) { + if (StringUtils.isEmpty(branch)) { + branch = Constants.HEAD; + } + try { + RevWalk walk = new RevWalk(r); + walk.sort(RevSort.REVERSE); + RevCommit head = walk.parseCommit(r.resolve(branch)); + walk.markStart(head); + RevCommit commit = walk.next(); + walk.dispose(); + return commit; + } catch (Throwable t) { + LOGGER.error("Failed to determine first commit", t); + } + return null; + } + + public static Date getFirstChange(Repository r, String branch) { + try { + RevCommit commit = getFirstCommit(r, branch); + return getCommitDate(commit); + } catch (Throwable t) { + LOGGER.error("Failed to determine first change", t); + } + return null; + } + public static Date getLastChange(Repository r) { RevCommit commit = getCommit(r, Constants.HEAD); return getCommitDate(commit); @@ -525,7 +554,7 @@ public class JGitUtils { } return null; } - + public String toString() { return name().toLowerCase(); } @@ -552,7 +581,7 @@ public class JGitUtils { case AUTHOR: return (commit.getAuthorIdent().getName().toLowerCase().indexOf(lcValue) > -1) || (commit.getAuthorIdent().getEmailAddress().toLowerCase().indexOf(lcValue) > -1); case COMMITTER: - return (commit.getCommitterIdent().getName().toLowerCase().indexOf(lcValue) > -1)|| (commit.getCommitterIdent().getEmailAddress().toLowerCase().indexOf(lcValue) > -1); + return (commit.getCommitterIdent().getName().toLowerCase().indexOf(lcValue) > -1) || (commit.getCommitterIdent().getEmailAddress().toLowerCase().indexOf(lcValue) > -1); case COMMIT: return commit.getFullMessage().toLowerCase().indexOf(lcValue) > -1; } @@ -695,29 +724,57 @@ public class JGitUtils { public static List getDateMetrics(Repository r) { final List tags = getTags(r, -1); - final Map map = new HashMap(); + final Map tagMap = new HashMap(); + for (RefModel tag : tags) { + tagMap.put(tag.getCommitId(), tag); + } + Metric total = new Metric("TOTAL"); + final Map metricMap = new HashMap(); try { - DateFormat df = new SimpleDateFormat("yyyy-MM"); RevWalk walk = new RevWalk(r); ObjectId object = r.resolve(Constants.HEAD); - walk.markStart(walk.parseCommit(object)); + + RevCommit firstCommit = 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)"); + } else { + // Months + df = new SimpleDateFormat("yyyy-MM"); + } + walk.markStart(lastCommit); + Iterable revlog = walk; for (RevCommit rev : revlog) { Date d = getCommitDate(rev); String p = df.format(d); - if (!map.containsKey(p)) - map.put(p, new Metric(p)); - map.get(p).count++; - } + if (!metricMap.containsKey(p)) + metricMap.put(p, new Metric(p)); + Metric m = metricMap.get(p); + m.count++; + total.count++; + if (tagMap.containsKey(rev.getId())) { + m.tag++; + total.tag++; + } + } } catch (Throwable t) { LOGGER.error("Failed to mine log history for metrics", t); } - List keys = new ArrayList(map.keySet()); + List keys = new ArrayList(metricMap.keySet()); Collections.sort(keys); List metrics = new ArrayList(); for (String key : keys) { - metrics.add(map.get(key)); + metrics.add(metricMap.get(key)); } + metrics.add(0, total); return metrics; } diff --git a/src/com/gitblit/utils/TimeUtils.java b/src/com/gitblit/utils/TimeUtils.java index 60b525b7..c4e5b593 100644 --- a/src/com/gitblit/utils/TimeUtils.java +++ b/src/com/gitblit/utils/TimeUtils.java @@ -23,6 +23,40 @@ public class TimeUtils { return now.getDate() == (date.getDate() + 1) && now.getMonth() == date.getMonth() && now.getYear() == date.getYear(); } + public static String duration(int days) { + if (days <= 60) { + return days + (days > 1 ? " days" : " day"); + } else if (days <= 365) { + int rem = days % 30; + return (days / 30) + " months, " + rem + (rem > 1 ? " days" : " day"); + } else { + int years = days / 365; + int rem = days % 365; + String yearsString = years + (years > 1 ? " years" : " year"); + if (rem < 30) { + if (rem == 0) { + return yearsString; + } else { + return yearsString + ", " + rem + (rem > 1 ? " days" : " day"); + } + } else { + int months = rem / 30; + int remDays = (rem % 30); + String monthsString; + if (months == 0) { + monthsString = yearsString; + } else { + monthsString = yearsString + ", " + months + (months > 1 ? " months" : " month"); + } + if (remDays == 0) { + return monthsString; + } else { + return monthsString + ", " + remDays + (remDays > 1 ? " days":" day"); + } + } + } + } + public static int minutesAgo(Date date, long endTime, boolean roundup) { long diff = endTime - date.getTime(); int mins = (int) (diff / min); diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index b8d31ae5..f0638586 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -54,4 +54,5 @@ gb.searchForCommitter = Search for commits committed by gb.addition = addition gb.modification = modification gb.deletion = deletion -gb.rename = rename \ No newline at end of file +gb.rename = rename +gb.stats = stats \ No newline at end of file diff --git a/src/com/gitblit/wicket/models/Metric.java b/src/com/gitblit/wicket/models/Metric.java index a5efb139..194e2659 100644 --- a/src/com/gitblit/wicket/models/Metric.java +++ b/src/com/gitblit/wicket/models/Metric.java @@ -8,6 +8,8 @@ public class Metric implements Serializable { public String name; public double count; + public double tag; + public int duration; public Metric(String name) { this.name = name; diff --git a/src/com/gitblit/wicket/pages/SummaryPage.html b/src/com/gitblit/wicket/pages/SummaryPage.html index 47c10b31..6abef548 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.html +++ b/src/com/gitblit/wicket/pages/SummaryPage.html @@ -12,17 +12,18 @@
-
+
-
+
- - - - + + + + +
description[repository description]
owner[repository owner]
last change[repository last change]
URL[repository clone url]
[description][repository description]
[owner][repository owner]
[last change][repository last change]
[stats][repository stats]
[URL][repository clone url]
diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java index 6d28df6e..53a684b5 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/com/gitblit/wicket/pages/SummaryPage.java @@ -1,6 +1,8 @@ package com.gitblit.wicket.pages; +import java.awt.Color; import java.awt.Dimension; +import java.text.MessageFormat; import java.util.List; import org.apache.wicket.PageParameters; @@ -15,9 +17,13 @@ import com.codecommit.wicket.ChartAxisType; import com.codecommit.wicket.ChartProvider; import com.codecommit.wicket.ChartType; import com.codecommit.wicket.IChartData; +import com.codecommit.wicket.LineStyle; +import com.codecommit.wicket.MarkerType; +import com.codecommit.wicket.ShapeMarker; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.utils.JGitUtils; +import com.gitblit.utils.TimeUtils; import com.gitblit.wicket.RepositoryPage; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.models.Metric; @@ -44,11 +50,11 @@ public class SummaryPage extends RepositoryPage { } Repository r = getRepository(); - List metrics = JGitUtils.getDateMetrics(r); - - long numberOfCommits = 0; - for (Metric m : metrics) { - numberOfCommits += m.count; + List metrics = null; + Metric metricsTotal = null; + if (GitBlit.self().settings().getBoolean(Keys.web.generateActivityGraph, true)) { + metrics = JGitUtils.getDateMetrics(r); + metricsTotal = metrics.remove(0); } // repository description @@ -56,6 +62,11 @@ public class SummaryPage extends RepositoryPage { add(new Label("repositoryOwner", JGitUtils.getRepositoryOwner(r))); add(WicketUtils.createTimestampLabel("repositoryLastChange", JGitUtils.getLastChange(r), getTimeZone())); + if (metricsTotal == null) { + add(new Label("repositoryStats", "")); + } else { + add(new Label("repositoryStats", MessageFormat.format("{0} commits and {1} tags in {2}", metricsTotal.count, metricsTotal.tag, TimeUtils.duration(metricsTotal.duration)))); + } add(new Label("repositoryCloneUrl", GitBlit.self().getCloneUrl(repositoryName))); add(new LogPanel("commitsPanel", repositoryName, null, r, numberCommits, 0)); @@ -75,7 +86,7 @@ public class SummaryPage extends RepositoryPage { if (GitBlit.self().settings().getBoolean(Keys.web.generateActivityGraph, true)) { IChartData data = getChartData(metrics); - ChartProvider provider = new ChartProvider(new Dimension(400, 80), ChartType.LINE, data); + ChartProvider provider = new ChartProvider(new Dimension(400, 100), ChartType.LINE, data); ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); dateAxis.setLabels(new String[] { metrics.get(0).name, metrics.get(metrics.size() / 2).name, metrics.get(metrics.size() - 1).name }); provider.addAxis(dateAxis); @@ -84,6 +95,9 @@ public class SummaryPage extends RepositoryPage { commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) }); provider.addAxis(commitAxis); + provider.setLineStyles(new LineStyle[] {new LineStyle(2, 4, 0), new LineStyle(0, 4, 1)}); + provider.addShapeMarker(new ShapeMarker(MarkerType.DIAMOND, Color.BLUE, 1, -1, 5)); + add(new Chart("commitsChart", provider)); } else { add(new ContextImage("commitsChart", "blank.png")); @@ -91,23 +105,25 @@ public class SummaryPage extends RepositoryPage { } protected IChartData getChartData(List metrics) { - final double[] counts = new double[metrics.size()]; + final double[] commits = new double[metrics.size()]; + final double[] tags = new double[metrics.size()]; int i = 0; double max = 0; for (Metric m : metrics) { - counts[i++] = m.count; + commits[i] = m.count; + if (m.tag > 0) { + tags[i] = m.count; + } else { + tags[i] = -1d; + } max = Math.max(max, m.count); + i++; } - final double dmax = max; - IChartData data = new AbstractChartData() { + IChartData data = new AbstractChartData(max) { private static final long serialVersionUID = 1L; public double[][] getData() { - return new double[][] { counts }; - } - - public double getMax() { - return dmax; + return new double[][] { commits, tags }; } }; return data;