Unit testing. Disable links on first commit. Initial stats page.
2 files added
16 files modified
| | |
| | | /users.properties |
| | | /site |
| | | /git |
| | | /target |
| | |
| | | # 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
|
| | |
| | | } |
| | | |
| | | public String format(long value) { |
| | | return format(new Long(value)); |
| | | return format(Long.valueOf(value)); |
| | | } |
| | | |
| | | public StringBuffer format(Object obj, StringBuffer buf, FieldPosition pos) { |
| | |
| | |
|
| | | 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 {
|
| | |
| | |
|
| | | public static List<String> getNestedRepositories(File repositoriesFolder, File folder,
|
| | | boolean exportAll, boolean readNested) {
|
| | | String basefile = repositoriesFolder.getAbsolutePath();
|
| | | List<String> list = new ArrayList<String>();
|
| | | 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
|
| | |
| | | }
|
| | |
|
| | | 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) {
|
| | |
| | | }
|
| | | 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);
|
| | | 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<DiffEntry> 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()));
|
| | | RawTextComparator cmp = RawTextComparator.DEFAULT;
|
| | | DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
|
| | | df.setRepository(r);
|
| | | df.setDiffComparator(cmp);
|
| | | df.setDetectRenames(true);
|
| | | List<DiffEntry> 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) {
|
| | |
| | | return "missing";
|
| | | }
|
| | | return "" + mode;
|
| | | }
|
| | |
|
| | | public static boolean isTreeFromMode(int mode) {
|
| | | return FileMode.TREE.equals(mode);
|
| | | }
|
| | |
|
| | | public static List<RevCommit> getRevLog(Repository r, int maxCount) {
|
| | |
| | | return false;
|
| | | }
|
| | |
|
| | | public static List<Metric> getDateMetrics(Repository r) {
|
| | | 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 (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 = 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<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 (includeTotal) {
|
| | | metrics.add(0, total);
|
| | | }
|
| | | return metrics;
|
| | | }
|
| | |
|
| | | public static List<Metric> getDateMetrics(Repository r, boolean includeTotal) {
|
| | | Metric total = new Metric("TOTAL");
|
| | | final Map<String, Metric> metricMap = new HashMap<String, Metric>();
|
| | |
|
| | |
| | | for (String key : keys) {
|
| | | metrics.add(metricMap.get(key));
|
| | | }
|
| | | metrics.add(0, total);
|
| | | if (includeTotal) {
|
| | | metrics.add(0, total);
|
| | | }
|
| | | return metrics;
|
| | | }
|
| | | |
| | | public static List<Metric> getAuthorMetrics(Repository r) {
|
| | | Metric total = new Metric("TOTAL");
|
| | | final Map<String, Metric> metricMap = new HashMap<String, Metric>();
|
| | |
|
| | | if (hasCommits(r)) {
|
| | | try {
|
| | | RevWalk walk = new RevWalk(r);
|
| | | ObjectId object = r.resolve(Constants.HEAD);
|
| | | RevCommit lastCommit = walk.parseCommit(object);
|
| | | walk.markStart(lastCommit);
|
| | |
|
| | | Iterable<RevCommit> 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<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));
|
| | | }
|
| | | return metrics;
|
| | | }
|
| | |
|
| | |
|
| | | public static RefModel getTicketsBranch(Repository r) {
|
| | | RefModel ticgitBranch = null;
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | 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");
|
| | |
| | |
|
| | | import java.text.DateFormat;
|
| | | import java.text.SimpleDateFormat;
|
| | | import java.util.Collection;
|
| | | import java.util.Date;
|
| | | import java.util.List;
|
| | | import java.util.TimeZone;
|
| | |
| | | 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;
|
| | |
| | | WicketUtils.setHtmlTooltip(label, title);
|
| | | return label;
|
| | | }
|
| | | |
| | | public static IChartData getChartData(Collection<Metric> 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<Metric> metrics) {
|
| | | double max = Double.MIN_VALUE;
|
| | | for (Metric m : metrics) {
|
| | | if (m.count > max) {
|
| | | max = m.count;
|
| | | }
|
| | | }
|
| | | return max;
|
| | | }
|
| | | |
| | | public static IChartData getScatterData(Collection<Metric> 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;
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | <div wicket:id="commitHeader">[commit header]</div>
|
| | |
|
| | | <!-- changed paths -->
|
| | | <div style="padding-top:15px;">
|
| | | <div style="padding-top:15px">
|
| | | <!-- commit legend -->
|
| | | <div style="text-align:right;" wicket:id="commitLegend"></div>
|
| | |
|
| | |
| | | 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;
|
| | |
|
| | |
| | | newPathParameter(entry.path)));
|
| | | item.add(new BookmarkablePageLink<Void>("blame", BlobPage.class).setEnabled(false));
|
| | | item.add(new BookmarkablePageLink<Void>("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++;
|
| | |
| | | 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;
|
| | |
|
| | |
| | | }
|
| | |
|
| | | item.add(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class,
|
| | | newPathParameter(entry.path)));
|
| | | newPathParameter(entry.path)).setEnabled(!entry.changeType.equals(ChangeType.ADD) && !entry.changeType.equals(ChangeType.DELETE)));
|
| | | item.add(new BookmarkablePageLink<Void>("view", BlobPage.class,
|
| | | newPathParameter(entry.path)));
|
| | | item.add(new BookmarkablePageLink<Void>("blame", BlobPage.class).setEnabled(false));
|
| | | item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class,
|
| | | newPathParameter(entry.path)));
|
| | | newPathParameter(entry.path)).setEnabled(!entry.changeType.equals(ChangeType.ADD)));
|
| | |
|
| | | WicketUtils.setAlternatingBackground(item, counter);
|
| | | counter++;
|
| | |
| | |
|
| | | <!-- page nav links -->
|
| | | <div class="page_nav">
|
| | | <a wicket:id="summary"><wicket:message key="gb.summary"></wicket:message></a> | <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="branches"><wicket:message key="gb.branches"></wicket:message></a> | <a wicket:id="tags"><wicket:message key="gb.tags"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> <span wicket:id="extra"><span wicket:id="extraSeparator"></span><span wicket:id="extraLink"></span></span>
|
| | | <a wicket:id="summary"><wicket:message key="gb.summary"></wicket:message></a> | <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="branches"><wicket:message key="gb.branches"></wicket:message></a> | <a wicket:id="tags"><wicket:message key="gb.tags"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="stats"><wicket:message key="gb.stats"></wicket:message></a> <span wicket:id="extra"><span wicket:id="extraSeparator"></span><span wicket:id="extraLink"></span></span>
|
| | | </div>
|
| | | </div>
|
| | |
|
| | |
| | | put("branches", "gb.branches");
|
| | | put("tags", "gb.tags");
|
| | | put("tree", "gb.tree");
|
| | | put("stats", "gb.stats");
|
| | | put("tickets", "gb.tickets");
|
| | | put("edit", "gb.edit");
|
| | | }
|
| | |
| | | WicketUtils.newRepositoryParameter(repositoryName)));
|
| | | add(new BookmarkablePageLink<Void>("tree", TreePage.class,
|
| | | WicketUtils.newRepositoryParameter(repositoryName)));
|
| | | add(new BookmarkablePageLink<Void>("stats", StatsPage.class,
|
| | | WicketUtils.newRepositoryParameter(repositoryName)));
|
| | |
|
| | | // per-repository extra page links
|
| | | List<String> extraPageLinks = new ArrayList<String>();
|
New file |
| | |
| | | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
| | | <html xmlns="http://www.w3.org/1999/xhtml" |
| | | xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" |
| | | xml:lang="en" |
| | | lang="en">
|
| | | |
| | | <body>
|
| | | <wicket:extend>
|
| | | <h2>Commit Activity</h2>
|
| | | <div><img wicket:id="commitsChart" /></div>
|
| | | |
| | | <h2>Commit Activity by Day of Week</h2>
|
| | | <div><img wicket:id="dayOfWeekChart" /></div>
|
| | | |
| | | <h2>Commit Activity by Time of Day</h2>
|
| | | <div><img wicket:id="timeOfDayChart" /></div>
|
| | |
|
| | | <h2>Most Prolific Authors</h2>
|
| | | <div><img wicket:id="authorsChart" /></div>
|
| | |
|
| | | </wicket:extend>
|
| | | </body>
|
| | | </html> |
New file |
| | |
| | | /*
|
| | | * 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<Metric> 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<Metric> 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<String> labels = new ArrayList<String>();
|
| | | 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<Metric> metrics) {
|
| | | if ((metrics != null) && (metrics.size() > 0)) {
|
| | | IChartData data = WicketUtils.getChartData(metrics);
|
| | | List<String> labels = new ArrayList<String>();
|
| | | 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<Metric> getDayOfWeekMetrics(Repository repository) {
|
| | | List<Metric> list = JGitUtils.getDateMetrics(repository, false, "E");
|
| | | SimpleDateFormat sdf = new SimpleDateFormat("E");
|
| | | Calendar cal = Calendar.getInstance();
|
| | |
|
| | | List<Metric> sorted = new ArrayList<Metric>(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<Metric> getTimeOfDayMetrics(Repository repository) {
|
| | | SimpleDateFormat ndf = new SimpleDateFormat("yyyy-MM-dd");
|
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
| | | List<Metric> 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<Metric> getAuthorMetrics(Repository repository) {
|
| | | List<Metric> authors = JGitUtils.getAuthorMetrics(repository);
|
| | | Collections.sort(authors, new Comparator<Metric>() {
|
| | | @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");
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | |
| | | List<Metric> 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);
|
| | | }
|
| | |
|
| | |
| | | private void insertActivityGraph(List<Metric> 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);
|
| | |
| | | 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) });
|
| | |
| | | } else {
|
| | | add(WicketUtils.newBlankImage("commitsChart"));
|
| | | }
|
| | | }
|
| | |
|
| | | protected IChartData getChartData(List<Metric> 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<Metric> 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<Metric> metrics) {
|
| | | double max = Double.MIN_VALUE;
|
| | | for (Metric m : metrics) {
|
| | | if (m.count > max) {
|
| | | max = m.count;
|
| | | }
|
| | | }
|
| | | return max;
|
| | | }
|
| | | }
|
| | |
| | | item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
|
| | | .newObjectParameter(repositoryName, entry.getName())));
|
| | | item.add(new BookmarkablePageLink<Void>("diff", CommitDiffPage.class, WicketUtils
|
| | | .newObjectParameter(repositoryName, entry.getName())));
|
| | | .newObjectParameter(repositoryName, entry.getName())).setEnabled(entry.getParentCount() > 0));
|
| | | item.add(new BookmarkablePageLink<Void>("tree", TreePage.class, WicketUtils
|
| | | .newObjectParameter(repositoryName, entry.getName())));
|
| | |
|
| | |
| | |
|
| | | div.commitLegend {
|
| | | float: right;
|
| | | padding: 0.4em;
|
| | | padding: 0.4em 0.4em 0.2em 0.4em;
|
| | | vertical-align:top;
|
| | | margin: 0px;
|
| | | }
|
| | |
| | | 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;
|
| | |
| | |
|
| | | public class JGitUtilsTest extends TestCase {
|
| | |
|
| | | private List<String> getRepositories() {
|
| | | return JGitUtils.getRepositoryList(GitBlitSuite.REPOSITORIES, true, true);
|
| | | }
|
| | |
|
| | | public void testFindRepositories() {
|
| | | List<String> list = getRepositories();
|
| | | List<String> 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);
|
| | | }
|
| | |
|
| | |
| | | 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);
|
| | |
| | | assertTrue("Incorrect first commit!",
|
| | | 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 {
|
| | |
| | |
|
| | | public void testMetrics() throws Exception {
|
| | | Repository repository = GitBlitSuite.getHelloworldRepository();
|
| | | List<Metric> metrics = JGitUtils.getDateMetrics(repository);
|
| | | List<Metric> metrics = JGitUtils.getDateMetrics(repository, true);
|
| | | repository.close();
|
| | | assertTrue("No metrics found!", metrics.size() > 0);
|
| | | }
|