contrib/com/codecommit/wicket/LineStyle.java | ●●●●● patch | view | raw | blame | history | |
contrib/com/codecommit/wicket/MarkerType.java | ●●●●● patch | view | raw | blame | history | |
contrib/com/codecommit/wicket/ShapeMarker.java | ●●●●● patch | view | raw | blame | history | |
gitblit.properties | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/tests/JGitUtilsTest.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/utils/JGitUtils.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/utils/TimeUtils.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/GitBlitWebApp.properties | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/models/Metric.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/SummaryPage.html | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/pages/SummaryPage.java | ●●●●● patch | view | raw | blame | history |
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; 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"), 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; gitblit.properties
@@ -65,7 +65,7 @@ # 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 @@ # 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 src/com/gitblit/tests/JGitUtilsTest.java
@@ -50,6 +50,14 @@ 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(); src/com/gitblit/utils/JGitUtils.java
@@ -36,6 +36,7 @@ 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; @@ -99,6 +100,34 @@ } } 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) { @@ -525,7 +554,7 @@ } return null; } public String toString() { return name().toLowerCase(); } @@ -552,7 +581,7 @@ 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 static List<Metric> getDateMetrics(Repository r) { final List<RefModel> tags = getTags(r, -1); final Map<String, Metric> map = new HashMap<String, Metric>(); final Map<ObjectId, RefModel> tagMap = new HashMap<ObjectId, RefModel>(); for (RefModel tag : tags) { tagMap.put(tag.getCommitId(), tag); } Metric total = new Metric("TOTAL"); final Map<String, Metric> metricMap = new HashMap<String, Metric>(); 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<RevCommit> 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<String> keys = new ArrayList<String>(map.keySet()); List<String> keys = new ArrayList<String>(metricMap.keySet()); Collections.sort(keys); List<Metric> metrics = new ArrayList<Metric>(); for (String key : keys) { metrics.add(map.get(key)); metrics.add(metricMap.get(key)); } metrics.add(0, total); return metrics; } src/com/gitblit/utils/TimeUtils.java
@@ -23,6 +23,40 @@ 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); src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -54,4 +54,5 @@ gb.addition = addition gb.modification = modification gb.deletion = deletion gb.rename = rename gb.rename = rename gb.stats = stats src/com/gitblit/wicket/models/Metric.java
@@ -8,6 +8,8 @@ public String name; public double count; public double tag; public int duration; public Metric(String name) { this.name = name; src/com/gitblit/wicket/pages/SummaryPage.html
@@ -12,17 +12,18 @@ <div style="clear:both;"> <!-- Repository Activity Chart --> <div style="width:400px;float:right;"> <div style="float:right;"> <img class="activityGraph" wicket:id="commitsChart" /> </div> <!-- Repository info --> <div style="margin-right:410px;"> <div> <table class="plain"> <tr><th><wicket:message key="gb.description">description</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr> <tr><th><wicket:message key="gb.owner">owner</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr> <tr><th><wicket:message key="gb.lastChange">last change</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr> <tr><th><wicket:message key="gb.url">URL</wicket:message></th><td><span wicket:id="repositoryCloneUrl">[repository clone url]</span></td></tr> <tr><th><wicket:message key="gb.description">[description]</wicket:message></th><td><span wicket:id="repositoryDescription">[repository description]</span></td></tr> <tr><th><wicket:message key="gb.owner">[owner]</wicket:message></th><td><span wicket:id="repositoryOwner">[repository owner]</span></td></tr> <tr><th><wicket:message key="gb.lastChange">[last change]</wicket:message></th><td><span wicket:id="repositoryLastChange">[repository last change]</span></td></tr> <tr><th><wicket:message key="gb.stats">[stats]</wicket:message></th><td><span wicket:id="repositoryStats">[repository stats]</span></td></tr> <tr><th><wicket:message key="gb.url">[URL]</wicket:message></th><td><span wicket:id="repositoryCloneUrl">[repository clone url]</span></td></tr> </table> </div> </div> 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.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 @@ } Repository r = getRepository(); List<Metric> metrics = JGitUtils.getDateMetrics(r); long numberOfCommits = 0; for (Metric m : metrics) { numberOfCommits += m.count; List<Metric> 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 @@ 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 @@ 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 @@ 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 @@ } protected IChartData getChartData(List<Metric> 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;