From f1720ca884bc3fa9da1288ad955e46f165aa4168 Mon Sep 17 00:00:00 2001 From: James Moger Date: Wed, 1 Jun 2011 08:09:46 -0400 Subject: Unit testing. Disable links on first commit. Initial stats page. --- .gitignore | 1 + distrib/users.properties | 3 +- src/com/gitblit/utils/ByteFormat.java | 2 +- src/com/gitblit/utils/JGitUtils.java | 155 ++++++++++++++----- src/com/gitblit/utils/TimeUtils.java | 2 +- src/com/gitblit/wicket/GitBlitWebApp.java | 4 +- src/com/gitblit/wicket/WicketUtils.java | 65 ++++++++ src/com/gitblit/wicket/pages/CommitDiffPage.html | 2 +- src/com/gitblit/wicket/pages/CommitDiffPage.java | 3 +- src/com/gitblit/wicket/pages/CommitPage.java | 5 +- src/com/gitblit/wicket/pages/RepositoryPage.html | 2 +- src/com/gitblit/wicket/pages/RepositoryPage.java | 3 + src/com/gitblit/wicket/pages/StatsPage.html | 23 +++ src/com/gitblit/wicket/pages/StatsPage.java | 189 +++++++++++++++++++++++ src/com/gitblit/wicket/pages/SummaryPage.java | 50 +----- src/com/gitblit/wicket/panels/LogPanel.java | 2 +- src/com/gitblit/wicket/resources/gitblit.css | 2 +- tests/com/gitblit/tests/JGitUtilsTest.java | 59 +++++-- 18 files changed, 465 insertions(+), 107 deletions(-) create mode 100644 src/com/gitblit/wicket/pages/StatsPage.html create mode 100644 src/com/gitblit/wicket/pages/StatsPage.java diff --git a/.gitignore b/.gitignore index 4495e70a..87e1b32c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /users.properties /site /git +/target diff --git a/distrib/users.properties b/distrib/users.properties index d5529756..233e9f93 100644 --- a/distrib/users.properties +++ b/distrib/users.properties @@ -1,2 +1,3 @@ -# Gitblit realm file format: username=password,\#permission,repository1,repository2... +## Git:Blit realm file format: username=password,\#permission,repository1,repository2... +#Tue May 31 11:19:53 EDT 2011 admin=admin,\#admin diff --git a/src/com/gitblit/utils/ByteFormat.java b/src/com/gitblit/utils/ByteFormat.java index 97b77bde..ea198de0 100644 --- a/src/com/gitblit/utils/ByteFormat.java +++ b/src/com/gitblit/utils/ByteFormat.java @@ -28,7 +28,7 @@ public class ByteFormat extends Format { } public String format(long value) { - return format(new Long(value)); + return format(Long.valueOf(value)); } public StringBuffer format(Object obj, StringBuffer buf, FieldPosition pos) { diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index ecf12e7f..4c7f14f6 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -75,9 +75,9 @@ import org.slf4j.LoggerFactory; import com.gitblit.models.Metric; 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.PathModel.PathChangeModel; import com.gitblit.models.TicketModel.Comment; public class JGitUtils { @@ -100,11 +100,11 @@ public class JGitUtils { public static List getNestedRepositories(File repositoriesFolder, File folder, boolean exportAll, boolean readNested) { - String basefile = repositoriesFolder.getAbsolutePath(); 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 @@ -169,17 +169,15 @@ public class JGitUtils { } public static Date getFirstChange(Repository r, String branch) { - try { - RevCommit commit = getFirstCommit(r, branch); - if (commit == null) { - // fresh repository - return new Date(r.getDirectory().lastModified()); + RevCommit commit = getFirstCommit(r, branch); + if (commit == null) { + if (r == null || !r.getDirectory().exists()) { + return new Date(0); } - return getCommitDate(commit); - } catch (Throwable t) { - LOGGER.error("Failed to determine first change", t); + // fresh repository + return new Date(r.getDirectory().lastModified()); } - return null; + return getCommitDate(commit); } public static boolean hasCommits(Repository r) { @@ -375,30 +373,41 @@ public class JGitUtils { } try { final RevWalk rw = new RevWalk(r); - RevCommit parent = rw.parseCommit(commit.getParent(0).getId()); - RevTree parentTree = parent.getTree(); + RevTree commitTree = commit.getTree(); final TreeWalk walk = new TreeWalk(r); walk.reset(); walk.setRecursive(true); - walk.addTree(parentTree); - walk.addTree(commitTree); - walk.setFilter(TreeFilter.ANY_DIFF); - - RawTextComparator cmp = RawTextComparator.DEFAULT; - DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE); - df.setRepository(r); - df.setDiffComparator(cmp); - df.setDetectRenames(true); - List diffs = df.scan(parentTree, commitTree); - for (DiffEntry diff : diffs) { - if (diff.getChangeType().equals(ChangeType.DELETE)) { - list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff - .getNewMode().getBits(), commit.getId().getName(), diff.getChangeType())); - } else { - list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff - .getNewMode().getBits(), commit.getId().getName(), diff.getChangeType())); + 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)); + } + } else { + RevCommit parent = rw.parseCommit(commit.getParent(0).getId()); + RevTree parentTree = parent.getTree(); + walk.addTree(parentTree); + walk.addTree(commitTree); + walk.setFilter(TreeFilter.ANY_DIFF); + + RawTextComparator cmp = RawTextComparator.DEFAULT; + DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE); + df.setRepository(r); + df.setDiffComparator(cmp); + df.setDetectRenames(true); + List diffs = df.scan(parentTree, commitTree); + for (DiffEntry diff : diffs) { + if (diff.getChangeType().equals(ChangeType.DELETE)) { + list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff + .getNewMode().getBits(), commit.getId().getName(), diff + .getChangeType())); + } else { + list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff + .getNewMode().getBits(), commit.getId().getName(), diff + .getChangeType())); + } } } } catch (Throwable t) { @@ -511,10 +520,6 @@ public class JGitUtils { return "" + mode; } - public static boolean isTreeFromMode(int mode) { - return FileMode.TREE.equals(mode); - } - public static List getRevLog(Repository r, int maxCount) { return getRevLog(r, Constants.HEAD, 0, maxCount); } @@ -775,7 +780,45 @@ public class JGitUtils { return false; } - public static List getDateMetrics(Repository r) { + public static List getDateMetrics(Repository r, boolean includeTotal, String format) { + Metric total = new Metric("TOTAL"); + final Map metricMap = new HashMap(); + + if (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 = 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) { + 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(); @@ -832,9 +875,49 @@ public class JGitUtils { for (String key : keys) { metrics.add(metricMap.get(key)); } - metrics.add(0, total); + if (includeTotal) { + metrics.add(0, total); + } return metrics; } + + public static List getAuthorMetrics(Repository r) { + Metric total = new Metric("TOTAL"); + final Map metricMap = new HashMap(); + + if (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)) { + 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) { + 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)); + } + return metrics; + } + public static RefModel getTicketsBranch(Repository r) { RefModel ticgitBranch = null; diff --git a/src/com/gitblit/utils/TimeUtils.java b/src/com/gitblit/utils/TimeUtils.java index 805b44f5..ece87dd8 100644 --- a/src/com/gitblit/utils/TimeUtils.java +++ b/src/com/gitblit/utils/TimeUtils.java @@ -47,7 +47,7 @@ public class TimeUtils { return days + (days > 1 ? " days" : " day"); } else if (days < 365) { int rem = days % 30; - return (days / 30) + (rem >= 15 ? 1 : 0) + " months"; + return ((days / 30) + (rem >= 15 ? 1 : 0)) + " months"; } else { int years = days / 365; int rem = days % 365; diff --git a/src/com/gitblit/wicket/GitBlitWebApp.java b/src/com/gitblit/wicket/GitBlitWebApp.java index 1d251d9c..71f5aada 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.java +++ b/src/com/gitblit/wicket/GitBlitWebApp.java @@ -41,6 +41,7 @@ import com.gitblit.wicket.pages.PatchPage; import com.gitblit.wicket.pages.RawPage; import com.gitblit.wicket.pages.RepositoriesPage; import com.gitblit.wicket.pages.SearchPage; +import com.gitblit.wicket.pages.StatsPage; import com.gitblit.wicket.pages.SummaryPage; import com.gitblit.wicket.pages.TagPage; import com.gitblit.wicket.pages.TagsPage; @@ -83,7 +84,8 @@ public class GitBlitWebApp extends WebApplication { mount("/patch", PatchPage.class, "r", "h", "f"); mount("/history", HistoryPage.class, "r", "h", "f"); mount("/search", SearchPage.class); - + mount("/stats", StatsPage.class, "r"); + // setup ticket urls mount("/tickets", TicketsPage.class, "r"); mount("/ticket", TicketPage.class, "r", "h", "f"); diff --git a/src/com/gitblit/wicket/WicketUtils.java b/src/com/gitblit/wicket/WicketUtils.java index ac31488c..aef68eee 100644 --- a/src/com/gitblit/wicket/WicketUtils.java +++ b/src/com/gitblit/wicket/WicketUtils.java @@ -17,6 +17,7 @@ package com.gitblit.wicket; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.TimeZone; @@ -29,9 +30,12 @@ import org.apache.wicket.markup.html.image.ContextImage; import org.apache.wicket.resource.ContextRelativeResource; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.lib.Constants; +import org.wicketstuff.googlecharts.AbstractChartData; +import org.wicketstuff.googlecharts.IChartData; import com.gitblit.GitBlit; import com.gitblit.Keys; +import com.gitblit.models.Metric; import com.gitblit.utils.JGitUtils.SearchType; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; @@ -295,4 +299,65 @@ public class WicketUtils { WicketUtils.setHtmlTooltip(label, title); return label; } + + public static IChartData getChartData(Collection metrics) { + final double[] commits = new double[metrics.size()]; + final double[] tags = new double[metrics.size()]; + int i = 0; + double max = 0; + for (Metric m : metrics) { + commits[i] = m.count; + if (m.tag > 0) { + tags[i] = m.count; + } else { + tags[i] = -1d; + } + max = Math.max(max, m.count); + i++; + } + IChartData data = new AbstractChartData(max) { + private static final long serialVersionUID = 1L; + + public double[][] getData() { + return new double[][] { commits, tags }; + } + }; + return data; + } + + public static double maxValue(Collection metrics) { + double max = Double.MIN_VALUE; + for (Metric m : metrics) { + if (m.count > max) { + max = m.count; + } + } + return max; + } + + public static IChartData getScatterData(Collection metrics) { + final double[] y = new double[metrics.size()]; + final double[] x = new double[metrics.size()]; + int i = 0; + double max = 0; + for (Metric m : metrics) { + y[i] = m.count; + if (m.duration > 0) { + x[i] = m.duration; + } else { + x[i] = -1d; + } + max = Math.max(max, m.count); + i++; + } + IChartData data = new AbstractChartData(max) { + private static final long serialVersionUID = 1L; + + public double[][] getData() { + return new double[][] { x, y }; + } + }; + return data; + } + } diff --git a/src/com/gitblit/wicket/pages/CommitDiffPage.html b/src/com/gitblit/wicket/pages/CommitDiffPage.html index 50a88776..8f238a7a 100644 --- a/src/com/gitblit/wicket/pages/CommitDiffPage.html +++ b/src/com/gitblit/wicket/pages/CommitDiffPage.html @@ -16,7 +16,7 @@
[commit header]
-
+
diff --git a/src/com/gitblit/wicket/pages/CommitDiffPage.java b/src/com/gitblit/wicket/pages/CommitDiffPage.java index 1f492aca..e7af833d 100644 --- a/src/com/gitblit/wicket/pages/CommitDiffPage.java +++ b/src/com/gitblit/wicket/pages/CommitDiffPage.java @@ -24,6 +24,7 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; +import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -99,7 +100,7 @@ public class CommitDiffPage extends RepositoryPage { newPathParameter(entry.path))); item.add(new BookmarkablePageLink("blame", BlobPage.class).setEnabled(false)); item.add(new BookmarkablePageLink("history", HistoryPage.class, - newPathParameter(entry.path))); + newPathParameter(entry.path)).setEnabled(!entry.changeType.equals(ChangeType.ADD) && !entry.changeType.equals(ChangeType.DELETE))); WicketUtils.setAlternatingBackground(item, counter); counter++; diff --git a/src/com/gitblit/wicket/pages/CommitPage.java b/src/com/gitblit/wicket/pages/CommitPage.java index dc674a2e..bc0d8792 100644 --- a/src/com/gitblit/wicket/pages/CommitPage.java +++ b/src/com/gitblit/wicket/pages/CommitPage.java @@ -26,6 +26,7 @@ import org.apache.wicket.markup.repeater.Item; import org.apache.wicket.markup.repeater.data.DataView; import org.apache.wicket.markup.repeater.data.ListDataProvider; import org.apache.wicket.model.StringResourceModel; +import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -134,12 +135,12 @@ public class CommitPage extends RepositoryPage { } item.add(new BookmarkablePageLink("diff", BlobDiffPage.class, - newPathParameter(entry.path))); + newPathParameter(entry.path)).setEnabled(!entry.changeType.equals(ChangeType.ADD) && !entry.changeType.equals(ChangeType.DELETE))); item.add(new BookmarkablePageLink("view", BlobPage.class, newPathParameter(entry.path))); item.add(new BookmarkablePageLink("blame", BlobPage.class).setEnabled(false)); item.add(new BookmarkablePageLink("history", HistoryPage.class, - newPathParameter(entry.path))); + newPathParameter(entry.path)).setEnabled(!entry.changeType.equals(ChangeType.ADD))); WicketUtils.setAlternatingBackground(item, counter); counter++; diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.html b/src/com/gitblit/wicket/pages/RepositoryPage.html index 0e0ce476..0f245eff 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.html +++ b/src/com/gitblit/wicket/pages/RepositoryPage.html @@ -18,7 +18,7 @@
diff --git a/src/com/gitblit/wicket/pages/RepositoryPage.java b/src/com/gitblit/wicket/pages/RepositoryPage.java index 109c51a8..2610c4c6 100644 --- a/src/com/gitblit/wicket/pages/RepositoryPage.java +++ b/src/com/gitblit/wicket/pages/RepositoryPage.java @@ -75,6 +75,7 @@ public abstract class RepositoryPage extends BasePage { put("branches", "gb.branches"); put("tags", "gb.tags"); put("tree", "gb.tree"); + put("stats", "gb.stats"); put("tickets", "gb.tickets"); put("edit", "gb.edit"); } @@ -103,6 +104,8 @@ public abstract class RepositoryPage extends BasePage { WicketUtils.newRepositoryParameter(repositoryName))); add(new BookmarkablePageLink("tree", TreePage.class, WicketUtils.newRepositoryParameter(repositoryName))); + add(new BookmarkablePageLink("stats", StatsPage.class, + WicketUtils.newRepositoryParameter(repositoryName))); // per-repository extra page links List extraPageLinks = new ArrayList(); diff --git a/src/com/gitblit/wicket/pages/StatsPage.html b/src/com/gitblit/wicket/pages/StatsPage.html new file mode 100644 index 00000000..d6f23e01 --- /dev/null +++ b/src/com/gitblit/wicket/pages/StatsPage.html @@ -0,0 +1,23 @@ + + + + + +

Commit Activity

+
+ +

Commit Activity by Day of Week

+
+ +

Commit Activity by Time of Day

+
+ +

Most Prolific Authors

+
+ +
+ + \ No newline at end of file diff --git a/src/com/gitblit/wicket/pages/StatsPage.java b/src/com/gitblit/wicket/pages/StatsPage.java new file mode 100644 index 00000000..0b16211e --- /dev/null +++ b/src/com/gitblit/wicket/pages/StatsPage.java @@ -0,0 +1,189 @@ +/* + * 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.wicket.pages; + +import java.awt.Color; +import java.awt.Dimension; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import org.apache.wicket.PageParameters; +import org.eclipse.jgit.lib.Repository; +import org.wicketstuff.googlecharts.Chart; +import org.wicketstuff.googlecharts.ChartAxis; +import org.wicketstuff.googlecharts.ChartAxisType; +import org.wicketstuff.googlecharts.ChartProvider; +import org.wicketstuff.googlecharts.ChartType; +import org.wicketstuff.googlecharts.IChartData; +import org.wicketstuff.googlecharts.LineStyle; +import org.wicketstuff.googlecharts.MarkerType; +import org.wicketstuff.googlecharts.ShapeMarker; + +import com.gitblit.models.Metric; +import com.gitblit.utils.JGitUtils; +import com.gitblit.wicket.WicketUtils; + +public class StatsPage extends RepositoryPage { + + public StatsPage(PageParameters params) { + super(params); + Repository r = getRepository(); + insertLinePlot("commitsChart", JGitUtils.getDateMetrics(r, false)); + insertBarPlot("dayOfWeekChart", getDayOfWeekMetrics(r)); + insertLinePlot("timeOfDayChart", getTimeOfDayMetrics(r)); + insertPieChart("authorsChart", getAuthorMetrics(r)); + } + + private void insertLinePlot(String wicketId, List metrics) { + if ((metrics != null) && (metrics.size() > 0)) { + IChartData data = WicketUtils.getChartData(metrics); + + 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); + + ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); + commitAxis.setLabels(new String[] { "", + String.valueOf((int) WicketUtils.maxValue(metrics)) }); + provider.addAxis(commitAxis); + + provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) }); + provider.addShapeMarker(new ShapeMarker(MarkerType.CIRCLE, Color.BLUE, 1, -1, 5)); + + add(new Chart(wicketId, provider)); + } else { + add(WicketUtils.newBlankImage(wicketId)); + } + } + + private void insertBarPlot(String wicketId, List metrics) { + if ((metrics != null) && (metrics.size() > 0)) { + IChartData data = WicketUtils.getChartData(metrics); + + ChartProvider provider = new ChartProvider(new Dimension(400, 100), + ChartType.BAR_VERTICAL_SET, data); + ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM); + List labels = new ArrayList(); + for (Metric metric : metrics) { + labels.add(metric.name); + } + dateAxis.setLabels(labels.toArray(new String[labels.size()])); + provider.addAxis(dateAxis); + + ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); + commitAxis.setLabels(new String[] { "", + String.valueOf((int) WicketUtils.maxValue(metrics)) }); + provider.addAxis(commitAxis); + + add(new Chart(wicketId, provider)); + } else { + add(WicketUtils.newBlankImage(wicketId)); + } + } + + private void insertPieChart(String wicketId, List metrics) { + if ((metrics != null) && (metrics.size() > 0)) { + IChartData data = WicketUtils.getChartData(metrics); + List labels = new ArrayList(); + for (Metric metric : metrics) { + labels.add(metric.name); + } + ChartProvider provider = new ChartProvider(new Dimension(400, 200), ChartType.PIE, data); + provider.setPieLabels(labels.toArray(new String[labels.size()])); + add(new Chart(wicketId, provider)); + } else { + add(WicketUtils.newBlankImage(wicketId)); + } + } + + private List getDayOfWeekMetrics(Repository repository) { + List list = JGitUtils.getDateMetrics(repository, false, "E"); + SimpleDateFormat sdf = new SimpleDateFormat("E"); + Calendar cal = Calendar.getInstance(); + + List sorted = new ArrayList(7); + int firstDayOfWeek = cal.getFirstDayOfWeek(); + int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); + + // rewind date to first day of week + cal.add(Calendar.DATE, firstDayOfWeek - dayOfWeek); + for (int i = 0; i < 7; i++) { + String day = sdf.format(cal.getTime()); + for (Metric metric : list) { + if (metric.name.equals(day)) { + sorted.add(i, metric); + list.remove(metric); + break; + } + } + cal.add(Calendar.DATE, 1); + } + return sorted; + } + + private List getTimeOfDayMetrics(Repository repository) { + SimpleDateFormat ndf = new SimpleDateFormat("yyyy-MM-dd"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + List list = JGitUtils.getDateMetrics(repository, false, "yyyy-MM-dd HH:mm"); + Calendar cal = Calendar.getInstance(); + + for (Metric metric : list) { + try { + Date date = sdf.parse(metric.name); + cal.setTime(date); + double y = cal.get(Calendar.HOUR_OF_DAY) + (cal.get(Calendar.MINUTE) / 60d); + metric.duration = (int) (date.getTime() / 60000L); + metric.count = y; + metric.name = ndf.format(date); + } catch (ParseException p) { + } + } + return list; + } + + private List getAuthorMetrics(Repository repository) { + List authors = JGitUtils.getAuthorMetrics(repository); + Collections.sort(authors, new Comparator() { + @Override + public int compare(Metric o1, Metric o2) { + if (o1.count > o2.count) { + return -1; + } else if (o1.count < o2.count) { + return 1; + } + return 0; + } + }); + if (authors.size() > 10) { + return authors.subList(0, 9); + } + return authors; + } + + @Override + protected String getPageName() { + return getString("gb.stats"); + } +} diff --git a/src/com/gitblit/wicket/pages/SummaryPage.java b/src/com/gitblit/wicket/pages/SummaryPage.java index 181de0da..1157d30c 100644 --- a/src/com/gitblit/wicket/pages/SummaryPage.java +++ b/src/com/gitblit/wicket/pages/SummaryPage.java @@ -27,7 +27,6 @@ import org.apache.wicket.PageParameters; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.protocol.http.WebRequest; import org.eclipse.jgit.lib.Repository; -import org.wicketstuff.googlecharts.AbstractChartData; import org.wicketstuff.googlecharts.Chart; import org.wicketstuff.googlecharts.ChartAxis; import org.wicketstuff.googlecharts.ChartAxisType; @@ -73,7 +72,7 @@ public class SummaryPage extends RepositoryPage { List metrics = null; Metric metricsTotal = null; if (GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) { - metrics = JGitUtils.getDateMetrics(r); + metrics = JGitUtils.getDateMetrics(r, true); metricsTotal = metrics.remove(0); } @@ -152,7 +151,7 @@ public class SummaryPage extends RepositoryPage { private void insertActivityGraph(List metrics) { if ((metrics != null) && (metrics.size() > 0) && GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) { - IChartData data = getChartData(metrics); + IChartData data = WicketUtils.getChartData(metrics); ChartProvider provider = new ChartProvider(new Dimension(400, 100), ChartType.LINE, data); @@ -162,7 +161,7 @@ public class SummaryPage extends RepositoryPage { provider.addAxis(dateAxis); ChartAxis commitAxis = new ChartAxis(ChartAxisType.LEFT); - commitAxis.setLabels(new String[] { "", String.valueOf((int) maxValue(metrics)) }); + commitAxis.setLabels(new String[] { "", String.valueOf((int) WicketUtils.maxValue(metrics)) }); provider.addAxis(commitAxis); provider.setLineStyles(new LineStyle[] { new LineStyle(2, 4, 0), new LineStyle(0, 4, 1) }); @@ -173,47 +172,4 @@ public class SummaryPage extends RepositoryPage { add(WicketUtils.newBlankImage("commitsChart")); } } - - protected IChartData getChartData(List metrics) { - final double[] commits = new double[metrics.size()]; - final double[] tags = new double[metrics.size()]; - int i = 0; - double max = 0; - for (Metric m : metrics) { - commits[i] = m.count; - if (m.tag > 0) { - tags[i] = m.count; - } else { - tags[i] = -1d; - } - max = Math.max(max, m.count); - i++; - } - IChartData data = new AbstractChartData(max) { - private static final long serialVersionUID = 1L; - - public double[][] getData() { - return new double[][] { commits, tags }; - } - }; - return data; - } - - protected String[] getNames(List results) { - String[] names = new String[results.size()]; - for (int i = 0; i < results.size(); i++) { - names[i] = results.get(i).name; - } - return names; - } - - protected double maxValue(List metrics) { - double max = Double.MIN_VALUE; - for (Metric m : metrics) { - if (m.count > max) { - max = m.count; - } - } - return max; - } } diff --git a/src/com/gitblit/wicket/panels/LogPanel.java b/src/com/gitblit/wicket/panels/LogPanel.java index c5ccac43..436c24f7 100644 --- a/src/com/gitblit/wicket/panels/LogPanel.java +++ b/src/com/gitblit/wicket/panels/LogPanel.java @@ -126,7 +126,7 @@ public class LogPanel extends BasePanel { item.add(new BookmarkablePageLink("view", CommitPage.class, WicketUtils .newObjectParameter(repositoryName, entry.getName()))); item.add(new BookmarkablePageLink("diff", CommitDiffPage.class, WicketUtils - .newObjectParameter(repositoryName, entry.getName()))); + .newObjectParameter(repositoryName, entry.getName())).setEnabled(entry.getParentCount() > 0)); item.add(new BookmarkablePageLink("tree", TreePage.class, WicketUtils .newObjectParameter(repositoryName, entry.getName()))); diff --git a/src/com/gitblit/wicket/resources/gitblit.css b/src/com/gitblit/wicket/resources/gitblit.css index 64484d27..c9356c3d 100644 --- a/src/com/gitblit/wicket/resources/gitblit.css +++ b/src/com/gitblit/wicket/resources/gitblit.css @@ -424,7 +424,7 @@ span.rename { div.commitLegend { float: right; - padding: 0.4em; + padding: 0.4em 0.4em 0.2em 0.4em; vertical-align:top; margin: 0px; } diff --git a/tests/com/gitblit/tests/JGitUtilsTest.java b/tests/com/gitblit/tests/JGitUtilsTest.java index d17ab5df..9007b42e 100644 --- a/tests/com/gitblit/tests/JGitUtilsTest.java +++ b/tests/com/gitblit/tests/JGitUtilsTest.java @@ -29,6 +29,7 @@ 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.models.Metric; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; @@ -38,12 +39,12 @@ import com.gitblit.utils.JGitUtils; public class JGitUtilsTest extends TestCase { - private List getRepositories() { - return JGitUtils.getRepositoryList(GitBlitSuite.REPOSITORIES, true, true); - } - public void testFindRepositories() { - List list = getRepositories(); + List list = JGitUtils.getRepositoryList(null, true, true); + assertTrue(list.size() == 0); + list.addAll(JGitUtils.getRepositoryList(new File("DoesNotExist"), true, true)); + assertTrue(list.size() == 0); + list.addAll(JGitUtils.getRepositoryList(GitBlitSuite.REPOSITORIES, true, true)); assertTrue("No repositories found in " + GitBlitSuite.REPOSITORIES, list.size() > 0); } @@ -53,14 +54,9 @@ public class JGitUtilsTest extends TestCase { assertTrue("Could not find repository!", repository != null); } - public void testLastChangeRepository() throws Exception { - Repository repository = GitBlitSuite.getHelloworldRepository(); - Date date = JGitUtils.getLastChange(repository); - repository.close(); - assertTrue("Could not get last repository change date!", date != null); - } - 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); @@ -70,6 +66,43 @@ 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); + repository.close(); + assertTrue("Could not get last repository change date!", date != null); + } + + + + public void testCreateRepository() throws Exception { + String[] repositories = { "NewTestRepository.git", "NewTestRepository" }; + for (String repositoryName : repositories) { + boolean isBare = repositoryName.endsWith(".git"); + Repository repository = JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, + repositoryName, isBare); + File folder; + if (isBare) { + 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.getCommit(repository, null) == null); + repository.close(); + assertTrue(GitBlit.self().deleteRepository(repositoryName)); + } + } public void testRefs() throws Exception { Repository repository = GitBlitSuite.getTicgitRepository(); @@ -151,7 +184,7 @@ public class JGitUtilsTest extends TestCase { public void testMetrics() throws Exception { Repository repository = GitBlitSuite.getHelloworldRepository(); - List metrics = JGitUtils.getDateMetrics(repository); + List metrics = JGitUtils.getDateMetrics(repository, true); repository.close(); assertTrue("No metrics found!", metrics.size() > 0); } -- cgit v1.2.3