Change-Id: Idb7de272589e086da9b2b3a241dcd082c1c8f27btags/v1.4.0
@@ -1,148 +0,0 @@ | |||
/* | |||
* 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.utils; | |||
import java.text.ParseException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.eclipse.jgit.revwalk.RevCommit; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import com.gitblit.models.PathModel; | |||
import com.gitblit.models.RefModel; | |||
import com.gitblit.models.TicketModel; | |||
import com.gitblit.models.TicketModel.Comment; | |||
/** | |||
* Utility class for reading Ticgit issues. | |||
* | |||
* @author James Moger | |||
* | |||
*/ | |||
public class TicgitUtils { | |||
static final Logger LOGGER = LoggerFactory.getLogger(TicgitUtils.class); | |||
/** | |||
* Returns a RefModel for the Ticgit branch in the repository. If the branch | |||
* can not be found, null is returned. | |||
* | |||
* @param repository | |||
* @return a refmodel for the ticgit branch or null | |||
*/ | |||
public static RefModel getTicketsBranch(Repository repository) { | |||
return JGitUtils.getBranch(repository, "ticgit"); | |||
} | |||
/** | |||
* Returns a list of all tickets in the ticgit branch of the repository. | |||
* | |||
* @param repository | |||
* @return list of tickets | |||
*/ | |||
public static List<TicketModel> getTickets(Repository repository) { | |||
RefModel ticgitBranch = getTicketsBranch(repository); | |||
if (ticgitBranch == null) { | |||
return null; | |||
} | |||
RevCommit commit = (RevCommit) ticgitBranch.referencedObject; | |||
List<PathModel> paths = JGitUtils.getFilesInPath(repository, null, commit); | |||
List<TicketModel> tickets = new ArrayList<TicketModel>(); | |||
for (PathModel ticketFolder : paths) { | |||
if (ticketFolder.isTree()) { | |||
try { | |||
TicketModel t = new TicketModel(ticketFolder.name); | |||
loadTicketContents(repository, ticgitBranch, t); | |||
tickets.add(t); | |||
} catch (Throwable t) { | |||
LOGGER.error("Failed to get a ticket!", t); | |||
} | |||
} | |||
} | |||
Collections.sort(tickets); | |||
Collections.reverse(tickets); | |||
return tickets; | |||
} | |||
/** | |||
* Returns a TicketModel for the specified ticgit ticket. Returns null if | |||
* the ticket does not exist or some other error occurs. | |||
* | |||
* @param repository | |||
* @param ticketFolder | |||
* @return a ticket | |||
*/ | |||
public static TicketModel getTicket(Repository repository, String ticketFolder) { | |||
RefModel ticketsBranch = getTicketsBranch(repository); | |||
if (ticketsBranch != null) { | |||
try { | |||
TicketModel ticket = new TicketModel(ticketFolder); | |||
loadTicketContents(repository, ticketsBranch, ticket); | |||
return ticket; | |||
} catch (Throwable t) { | |||
LOGGER.error("Failed to get ticket " + ticketFolder, t); | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Loads the contents of the ticket. | |||
* | |||
* @param repository | |||
* @param ticketsBranch | |||
* @param ticket | |||
*/ | |||
private static void loadTicketContents(Repository repository, RefModel ticketsBranch, | |||
TicketModel ticket) { | |||
RevCommit commit = (RevCommit) ticketsBranch.referencedObject; | |||
List<PathModel> ticketFiles = JGitUtils.getFilesInPath(repository, ticket.name, commit); | |||
for (PathModel file : ticketFiles) { | |||
String content = JGitUtils.getStringContent(repository, commit.getTree(), file.path) | |||
.trim(); | |||
if (file.name.equals("TICKET_ID")) { | |||
ticket.id = content; | |||
} else if (file.name.equals("TITLE")) { | |||
ticket.title = content; | |||
} else { | |||
String[] chunks = file.name.split("_"); | |||
if (chunks[0].equals("ASSIGNED")) { | |||
ticket.handler = content; | |||
} else if (chunks[0].equals("COMMENT")) { | |||
try { | |||
Comment c = new Comment(file.name, content); | |||
ticket.comments.add(c); | |||
} catch (ParseException e) { | |||
LOGGER.error("Failed to parse ticket comment", e); | |||
} | |||
} else if (chunks[0].equals("TAG")) { | |||
if (content.startsWith("TAG_")) { | |||
ticket.tags.add(content.substring(4)); | |||
} else { | |||
ticket.tags.add(content); | |||
} | |||
} else if (chunks[0].equals("STATE")) { | |||
ticket.state = content; | |||
} | |||
} | |||
} | |||
Collections.sort(ticket.comments); | |||
} | |||
} |
@@ -63,8 +63,6 @@ import com.gitblit.wicket.pages.ReviewProposalPage; | |||
import com.gitblit.wicket.pages.SummaryPage; | |||
import com.gitblit.wicket.pages.TagPage; | |||
import com.gitblit.wicket.pages.TagsPage; | |||
import com.gitblit.wicket.pages.TicketPage; | |||
import com.gitblit.wicket.pages.TicketsPage; | |||
import com.gitblit.wicket.pages.TreePage; | |||
import com.gitblit.wicket.pages.UserPage; | |||
import com.gitblit.wicket.pages.UsersPage; | |||
@@ -72,9 +70,9 @@ import com.gitblit.wicket.pages.UsersPage; | |||
public class GitBlitWebApp extends WebApplication { | |||
public final static Class<? extends BasePage> HOME_PAGE_CLASS = MyDashboardPage.class; | |||
private final Map<String, CacheControl> cacheablePages = new HashMap<String, CacheControl>(); | |||
@Override | |||
public void init() { | |||
super.init(); | |||
@@ -123,10 +121,6 @@ public class GitBlitWebApp extends WebApplication { | |||
mount("/users", UsersPage.class); | |||
mount("/logout", LogoutPage.class); | |||
// setup ticket urls | |||
mount("/tickets", TicketsPage.class, "r"); | |||
mount("/ticket", TicketPage.class, "r", "f"); | |||
// setup the markdown urls | |||
mount("/docs", DocsPage.class, "r"); | |||
mount("/markdown", MarkdownPage.class, "r", "h", "f"); | |||
@@ -153,8 +147,8 @@ public class GitBlitWebApp extends WebApplication { | |||
parameters = new String[] {}; | |||
} | |||
mount(new GitblitParamUrlCodingStrategy(location, clazz, parameters)); | |||
// map the mount point to the cache control definition | |||
// map the mount point to the cache control definition | |||
if (clazz.isAnnotationPresent(CacheControl.class)) { | |||
CacheControl cacheControl = clazz.getAnnotation(CacheControl.class); | |||
cacheablePages.put(location.substring(1), cacheControl); | |||
@@ -165,7 +159,7 @@ public class GitBlitWebApp extends WebApplication { | |||
public Class<? extends Page> getHomePage() { | |||
return HOME_PAGE_CLASS; | |||
} | |||
public boolean isCacheablePage(String mountPoint) { | |||
return cacheablePages.containsKey(mountPoint); | |||
} |
@@ -63,7 +63,6 @@ import com.gitblit.utils.DeepCopier; | |||
import com.gitblit.utils.JGitUtils; | |||
import com.gitblit.utils.RefLogUtils; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TicgitUtils; | |||
import com.gitblit.wicket.CacheControl; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.PageRegistration; | |||
@@ -75,25 +74,25 @@ import com.gitblit.wicket.panels.NavigationPanel; | |||
import com.gitblit.wicket.panels.RefsPanel; | |||
public abstract class RepositoryPage extends RootPage { | |||
private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
private final String PARAM_STAR = "star"; | |||
protected final String projectName; | |||
protected final String repositoryName; | |||
protected final String objectId; | |||
private transient Repository r; | |||
private RepositoryModel m; | |||
private Map<String, SubmoduleModel> submodules; | |||
private final Map<String, PageRegistration> registeredPages; | |||
private boolean showAdmin; | |||
private boolean isOwner; | |||
public RepositoryPage(PageParameters params) { | |||
super(params); | |||
repositoryName = WicketUtils.getRepositoryName(params); | |||
@@ -104,7 +103,7 @@ public abstract class RepositoryPage extends RootPage { | |||
projectName = root; | |||
} | |||
objectId = WicketUtils.getObject(params); | |||
if (StringUtils.isEmpty(repositoryName)) { | |||
error(MessageFormat.format(getString("gb.repositoryNotSpecifiedFor"), getPageName()), true); | |||
} | |||
@@ -112,11 +111,11 @@ public abstract class RepositoryPage extends RootPage { | |||
if (!getRepositoryModel().hasCommits) { | |||
setResponsePage(EmptyRepositoryPage.class, params); | |||
} | |||
if (getRepositoryModel().isCollectingGarbage) { | |||
error(MessageFormat.format(getString("gb.busyCollectingGarbage"), getRepositoryModel().name), true); | |||
} | |||
if (objectId != null) { | |||
RefModel branch = null; | |||
if ((branch = JGitUtils.getBranch(getRepository(), objectId)) != null) { | |||
@@ -132,7 +131,7 @@ public abstract class RepositoryPage extends RootPage { | |||
} | |||
} | |||
} | |||
if (params.containsKey(PARAM_STAR)) { | |||
// set starred state | |||
boolean star = params.getBoolean(PARAM_STAR); | |||
@@ -168,7 +167,7 @@ public abstract class RepositoryPage extends RootPage { | |||
// set stateless page preference | |||
setStatelessHint(true); | |||
} | |||
@Override | |||
protected Class<? extends BasePage> getRootNavPageClass() { | |||
return RepositoriesPage.class; | |||
@@ -177,7 +176,7 @@ public abstract class RepositoryPage extends RootPage { | |||
protected Class<? extends BasePage> getRepoNavPageClass() { | |||
return getClass(); | |||
} | |||
private Map<String, PageRegistration> registerPages() { | |||
PageParameters params = null; | |||
if (!StringUtils.isEmpty(repositoryName)) { | |||
@@ -195,7 +194,7 @@ public abstract class RepositoryPage extends RootPage { | |||
pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params)); | |||
// pages.put("overview", new PageRegistration("gb.overview", OverviewPage.class, params)); | |||
pages.put("reflog", new PageRegistration("gb.reflog", ReflogPage.class, params)); | |||
} | |||
} | |||
pages.put("commits", new PageRegistration("gb.commits", LogPage.class, params)); | |||
pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params)); | |||
pages.put("compare", new PageRegistration("gb.compare", ComparePage.class, params, true)); | |||
@@ -205,9 +204,6 @@ public abstract class RepositoryPage extends RootPage { | |||
// conditional links | |||
// per-repository extra page links | |||
if (model.useTickets && TicgitUtils.getTicketsBranch(r) != null) { | |||
pages.put("tickets", new PageRegistration("gb.tickets", TicketsPage.class, params, true)); | |||
} | |||
if (model.showReadme || model.useDocs) { | |||
pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params, true)); | |||
} | |||
@@ -230,7 +226,7 @@ public abstract class RepositoryPage extends RootPage { | |||
.getUsername())); | |||
return pages; | |||
} | |||
protected boolean allowForkControls() { | |||
return GitBlit.getBoolean(Keys.web.allowForking, true); | |||
} | |||
@@ -248,7 +244,7 @@ public abstract class RepositoryPage extends RootPage { | |||
add(new LinkPanel("projectTitle", null, project.name, | |||
ProjectPage.class, WicketUtils.newProjectParameter(project.name))); | |||
} | |||
String name = StringUtils.stripDotGit(repositoryName); | |||
if (!StringUtils.isEmpty(projectName) && name.startsWith(projectName)) { | |||
name = name.substring(projectName.length() + 1); | |||
@@ -256,7 +252,7 @@ public abstract class RepositoryPage extends RootPage { | |||
add(new LinkPanel("repositoryName", null, name, SummaryPage.class, | |||
WicketUtils.newRepositoryParameter(repositoryName))); | |||
add(new Label("pageName", pageName).setRenderBodyOnly(true)); | |||
UserModel user = GitBlitWebSession.get().getUser(); | |||
if (user == null) { | |||
user = UserModel.ANONYMOUS; | |||
@@ -279,12 +275,12 @@ public abstract class RepositoryPage extends RootPage { | |||
} else { | |||
// link to origin repository | |||
Fragment forkFrag = new Fragment("originRepository", "originFragment", this); | |||
forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository), | |||
forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(model.originRepository), | |||
SummaryPage.class, WicketUtils.newRepositoryParameter(model.originRepository))); | |||
add(forkFrag); | |||
} | |||
} | |||
// (un)star link allows a user to star a repository | |||
if (user.isAuthenticated) { | |||
PageParameters starParams = DeepCopier.copy(getPageParameters()); | |||
@@ -318,7 +314,7 @@ public abstract class RepositoryPage extends RootPage { | |||
if (hasFork || !canFork) { | |||
// user not allowed to fork or fork already exists or repo forbids forking | |||
add(new ExternalLink("forkLink", "").setVisible(false)); | |||
if (hasFork && !fork.equals(model.name)) { | |||
// user has fork, view my fork link | |||
String url = getRequestCycle().urlFor(SummaryPage.class, WicketUtils.newRepositoryParameter(fork)).toString(); | |||
@@ -334,17 +330,17 @@ public abstract class RepositoryPage extends RootPage { | |||
add(new ExternalLink("forkLink", url)); | |||
} | |||
} | |||
if (showAdmin || isOwner) { | |||
String url = getRequestCycle().urlFor(EditRepositoryPage.class, WicketUtils.newRepositoryParameter(model.name)).toString(); | |||
add(new ExternalLink("editLink", url)); | |||
add(new ExternalLink("editLink", url)); | |||
} else { | |||
add(new Label("editLink").setVisible(false)); | |||
} | |||
super.setupPage(repositoryName, pageName); | |||
} | |||
protected void addToolbarButton(String wicketId, String iconClass, String label, String url) { | |||
Fragment button = new Fragment(wicketId, "toolbarLinkFragment", this); | |||
Label icon = new Label("icon"); | |||
@@ -402,8 +398,8 @@ public abstract class RepositoryPage extends RootPage { | |||
getSubmodules(commit); | |||
return commit; | |||
} | |||
protected Map<String, SubmoduleModel> getSubmodules(RevCommit commit) { | |||
protected Map<String, SubmoduleModel> getSubmodules(RevCommit commit) { | |||
if (submodules == null) { | |||
submodules = new HashMap<String, SubmoduleModel>(); | |||
for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { | |||
@@ -412,7 +408,7 @@ public abstract class RepositoryPage extends RootPage { | |||
} | |||
return submodules; | |||
} | |||
protected SubmoduleModel getSubmodule(String path) { | |||
SubmoduleModel model = null; | |||
if (submodules != null) { | |||
@@ -428,7 +424,7 @@ public abstract class RepositoryPage extends RootPage { | |||
// extract the repository name from the clone url | |||
List<String> patterns = GitBlit.getStrings(Keys.git.submoduleUrlPatterns); | |||
String submoduleName = StringUtils.extractRepositoryPath(model.url, patterns.toArray(new String[0])); | |||
// determine the current path for constructing paths relative | |||
// to the current repository | |||
String currentPath = ""; | |||
@@ -471,11 +467,11 @@ public abstract class RepositoryPage extends RootPage { | |||
return model; | |||
} | |||
} | |||
// we do not have a copy of the submodule, but we need a path | |||
model.gitblitPath = candidates.get(0); | |||
return model; | |||
} | |||
} | |||
} | |||
protected String getShortObjectId(String objectId) { | |||
@@ -574,7 +570,7 @@ public abstract class RepositoryPage extends RootPage { | |||
setupPage(repositoryName, "/ " + getPageName()); | |||
super.onBeforeRender(); | |||
} | |||
@Override | |||
protected void setLastModified() { | |||
if (getClass().isAnnotationPresent(CacheControl.class)) { | |||
@@ -614,11 +610,11 @@ public abstract class RepositoryPage extends RootPage { | |||
public boolean isShowAdmin() { | |||
return showAdmin; | |||
} | |||
public boolean isOwner() { | |||
return isOwner; | |||
} | |||
private class SearchForm extends SessionlessForm<Void> implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
@@ -652,7 +648,7 @@ public abstract class RepositoryPage extends RootPage { | |||
Constants.SearchType searchType = searchTypeModel.getObject(); | |||
String searchString = searchBoxModel.getObject(); | |||
if (StringUtils.isEmpty(searchString)) { | |||
// redirect to self to avoid wicket page update bug | |||
// redirect to self to avoid wicket page update bug | |||
PageParameters params = RepositoryPage.this.getPageParameters(); | |||
String relativeUrl = urlFor(RepositoryPage.this.getClass(), params).toString(); | |||
String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl); |
@@ -1,39 +0,0 @@ | |||
<!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> | |||
<!-- ticket title --> | |||
<div style="font-size:150%;padding-top:5px;padding-bottom:5px;" wicket:id="ticketTitle">[ticket title]</div> | |||
<!-- ticket info --> | |||
<table class="plain"> | |||
<tr><th><wicket:message key="gb.ticketId">ticket id</wicket:message></th><td><span class="sha1" wicket:id="ticketId">[ticket id]</span></td></tr> | |||
<tr><th><wicket:message key="gb.ticketAssigned">assigned</wicket:message></th><td><span wicket:id=ticketHandler>[ticket title]</span></td></tr> | |||
<tr><th><wicket:message key="gb.ticketOpenDate">open date</wicket:message></th><td><span wicket:id="ticketOpenDate">[ticket open date]</span></td></tr> | |||
<tr><th><wicket:message key="gb.ticketState">state</wicket:message></th><td><span wicket:id="ticketState">[ticket state]</span></td></tr> | |||
<tr><th><wicket:message key="gb.tags">tags</wicket:message></th><td><span wicket:id="ticketTags">[ticket tags]</span></td></tr> | |||
</table> | |||
<!-- comments header --> | |||
<div class="header"><wicket:message key="gb.ticketComments">comments</wicket:message></div> | |||
<!-- comments --> | |||
<table class="comments"> | |||
<tbody> | |||
<tr valign="top" wicket:id="comment"> | |||
<td><span class="author" wicket:id="commentAuthor">[comment author]</span><br/> | |||
<span class="date" wicket:id="commentDate">[comment date]</span> | |||
</td> | |||
<td><span wicket:id="commentText">[comment text]</span></td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</wicket:extend> | |||
</body> | |||
</html> |
@@ -1,86 +0,0 @@ | |||
/* | |||
* 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 org.apache.wicket.PageParameters; | |||
import org.apache.wicket.markup.html.basic.Label; | |||
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.lib.Repository; | |||
import com.gitblit.models.TicketModel; | |||
import com.gitblit.models.TicketModel.Comment; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TicgitUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
public class TicketPage extends RepositoryPage { | |||
public TicketPage(PageParameters params) { | |||
super(params); | |||
final String ticketFolder = WicketUtils.getPath(params); | |||
Repository r = getRepository(); | |||
TicketModel t = TicgitUtils.getTicket(r, ticketFolder); | |||
add(new Label("ticketTitle", t.title)); | |||
add(new Label("ticketId", t.id)); | |||
add(new Label("ticketHandler", t.handler.toLowerCase())); | |||
add(WicketUtils.createTimestampLabel("ticketOpenDate", t.date, getTimeZone(), getTimeUtils())); | |||
Label stateLabel = new Label("ticketState", t.state); | |||
WicketUtils.setTicketCssClass(stateLabel, t.state); | |||
add(stateLabel); | |||
add(new Label("ticketTags", StringUtils.flattenStrings(t.tags))); | |||
ListDataProvider<Comment> commentsDp = new ListDataProvider<Comment>(t.comments); | |||
DataView<Comment> commentsView = new DataView<Comment>("comment", commentsDp) { | |||
private static final long serialVersionUID = 1L; | |||
int counter; | |||
public void populateItem(final Item<Comment> item) { | |||
final Comment entry = item.getModelObject(); | |||
item.add(WicketUtils.createDateLabel("commentDate", entry.date, GitBlitWebSession | |||
.get().getTimezone(), getTimeUtils())); | |||
item.add(new Label("commentAuthor", entry.author.toLowerCase())); | |||
item.add(new Label("commentText", prepareComment(entry.text)) | |||
.setEscapeModelStrings(false)); | |||
WicketUtils.setAlternatingBackground(item, counter); | |||
counter++; | |||
} | |||
}; | |||
add(commentsView); | |||
} | |||
@Override | |||
protected String getPageName() { | |||
return getString("gb.ticket"); | |||
} | |||
@Override | |||
protected Class<? extends BasePage> getRepoNavPageClass() { | |||
return TicketsPage.class; | |||
} | |||
private String prepareComment(String comment) { | |||
String html = StringUtils.escapeForHtml(comment, false); | |||
html = StringUtils.breakLinesForHtml(comment).trim(); | |||
return html.replaceAll("\\bcommit\\s*([A-Za-z0-9]*)\\b", "<a href=\"/commit/" | |||
+ repositoryName + "/$1\">commit $1</a>"); | |||
} | |||
} |
@@ -1,24 +0,0 @@ | |||
<!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> | |||
<!-- tickets --> | |||
<table class="pretty"> | |||
<tbody> | |||
<tr wicket:id="ticket"> | |||
<td style="padding:0; margin:0;"><div wicket:id="ticketState">[ticket state]</div></td> | |||
<td class="date"><span wicket:id="ticketDate">[ticket date]</span></td> | |||
<td class="author"><div wicket:id="ticketHandler">[ticket handler]</div></td> | |||
<td><div wicket:id="ticketTitle">[ticket title]</div></td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</wicket:extend> | |||
</body> | |||
</html> |
@@ -1,72 +0,0 @@ | |||
/* | |||
* 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.util.List; | |||
import org.apache.wicket.PageParameters; | |||
import org.apache.wicket.markup.html.basic.Label; | |||
import org.apache.wicket.markup.repeater.Item; | |||
import org.apache.wicket.markup.repeater.data.DataView; | |||
import org.apache.wicket.markup.repeater.data.ListDataProvider; | |||
import com.gitblit.models.TicketModel; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TicgitUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
import com.gitblit.wicket.panels.LinkPanel; | |||
public class TicketsPage extends RepositoryPage { | |||
public TicketsPage(PageParameters params) { | |||
super(params); | |||
List<TicketModel> tickets = TicgitUtils.getTickets(getRepository()); | |||
ListDataProvider<TicketModel> ticketsDp = new ListDataProvider<TicketModel>(tickets); | |||
DataView<TicketModel> ticketsView = new DataView<TicketModel>("ticket", ticketsDp) { | |||
private static final long serialVersionUID = 1L; | |||
int counter; | |||
public void populateItem(final Item<TicketModel> item) { | |||
final TicketModel entry = item.getModelObject(); | |||
Label stateLabel = new Label("ticketState", entry.state); | |||
WicketUtils.setTicketCssClass(stateLabel, entry.state); | |||
item.add(stateLabel); | |||
item.add(WicketUtils.createDateLabel("ticketDate", entry.date, GitBlitWebSession | |||
.get().getTimezone(), getTimeUtils())); | |||
item.add(new Label("ticketHandler", StringUtils.trimString( | |||
entry.handler.toLowerCase(), 30))); | |||
item.add(new LinkPanel("ticketTitle", "list subject", StringUtils.trimString( | |||
entry.title, 80), TicketPage.class, newPathParameter(entry.name))); | |||
WicketUtils.setAlternatingBackground(item, counter); | |||
counter++; | |||
} | |||
}; | |||
add(ticketsView); | |||
} | |||
protected PageParameters newPathParameter(String path) { | |||
return WicketUtils.newPathParameter(repositoryName, objectId, path); | |||
} | |||
@Override | |||
protected String getPageName() { | |||
return getString("gb.tickets"); | |||
} | |||
} |
@@ -42,9 +42,6 @@ | |||
<img class="inlineIcon" wicket:id="frozenIcon" /> | |||
<img class="inlineIcon" wicket:id="federatedIcon" /> | |||
<a style="text-decoration: none;" wicket:id="tickets" wicket:message="title:gb.tickets"> | |||
<img style="border:0px;vertical-align:middle;" src="bug_16x16.png"></img> | |||
</a> | |||
<a style="text-decoration: none;" wicket:id="docs" wicket:message="title:gb.docs"> | |||
<img style="border:0px;vertical-align:middle;" src="book_16x16.png"></img> | |||
</a> |
@@ -41,7 +41,6 @@ import com.gitblit.wicket.pages.DocsPage; | |||
import com.gitblit.wicket.pages.EditRepositoryPage; | |||
import com.gitblit.wicket.pages.LogPage; | |||
import com.gitblit.wicket.pages.SummaryPage; | |||
import com.gitblit.wicket.pages.TicketsPage; | |||
import com.gitblit.wicket.pages.TreePage; | |||
public class ProjectRepositoryPanel extends BasePanel { | |||
@@ -78,7 +77,7 @@ public class ProjectRepositoryPanel extends BasePanel { | |||
add(new Label("originRepository").setVisible(false)); | |||
} else { | |||
Fragment forkFrag = new Fragment("originRepository", "originFragment", this); | |||
forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(entry.originRepository), | |||
forkFrag.add(new LinkPanel("originRepository", null, StringUtils.stripDotGit(entry.originRepository), | |||
SummaryPage.class, WicketUtils.newRepositoryParameter(entry.originRepository))); | |||
add(forkFrag); | |||
} | |||
@@ -89,7 +88,6 @@ public class ProjectRepositoryPanel extends BasePanel { | |||
add(WicketUtils.newClearPixel("sparkleshareIcon").setVisible(false)); | |||
} | |||
add(new BookmarkablePageLink<Void>("tickets", TicketsPage.class, pp).setVisible(entry.useTickets)); | |||
add(new BookmarkablePageLink<Void>("docs", DocsPage.class, pp).setVisible(entry.useDocs)); | |||
if (entry.isFrozen) { | |||
@@ -110,10 +108,10 @@ public class ProjectRepositoryPanel extends BasePanel { | |||
String owner = ""; | |||
for (String username : entry.owners) { | |||
UserModel ownerModel = GitBlit.self().getUserModel(username); | |||
if (ownerModel != null) { | |||
owner = ownerModel.getDisplayName(); | |||
} | |||
} | |||
} | |||
if (entry.owners.size() > 1) { | |||
owner += ", ..."; |
@@ -55,9 +55,8 @@ | |||
- Syntax highlighting for popular source code types | |||
- Customizable regular expression substitution for commit messages (i.e. bug or code review link integration) | |||
- Single text file for users configuration | |||
- Optional utility pages | |||
- ![docs](book_16x16.png) Docs page which enumerates all Markdown files within a repository | |||
- ![tickets](bug_16x16.png) **readonly and deprecated** Ticgit ticket pages *(based on last MIT release bf57b032 2009-01-27)* | |||
- Optional Docs page which enumerates all Markdown files within a repository | |||
2009-01-27)* | |||
- Translations | |||
- English | |||
- Japanese |
@@ -43,21 +43,21 @@ import com.gitblit.utils.JGitUtils; | |||
* The GitBlitSuite uses test-gitblit.properties and test-users.conf. The suite | |||
* is fairly comprehensive for all lower-level functionality. Wicket pages are | |||
* currently not unit-tested. | |||
* | |||
* | |||
* This suite starts a Gitblit server instance within the same JVM instance as | |||
* the unit tests. This allows the unit tests to access the GitBlit static | |||
* singleton while also being able to communicate with the instance via tcp/ip | |||
* for testing rpc requests, federation requests, and git servlet operations. | |||
* | |||
* | |||
* @author James Moger | |||
* | |||
* | |||
*/ | |||
@RunWith(Suite.class) | |||
@SuiteClasses({ ArrayUtilsTest.class, FileUtilsTest.class, TimeUtilsTest.class, | |||
StringUtilsTest.class, Base64Test.class, JsonUtilsTest.class, ByteFormatTest.class, | |||
ObjectCacheTest.class, PermissionsTest.class, UserServiceTest.class, LdapUserServiceTest.class, | |||
MarkdownUtilsTest.class, JGitUtilsTest.class, SyndicationUtilsTest.class, | |||
DiffUtilsTest.class, MetricUtilsTest.class, TicgitUtilsTest.class, X509UtilsTest.class, | |||
DiffUtilsTest.class, MetricUtilsTest.class, X509UtilsTest.class, | |||
GitBlitTest.class, FederationTests.class, RpcTests.class, GitServletTest.class, GitDaemonTest.class, | |||
GroovyScriptTest.class, LuceneExecutorTest.class, IssuesTest.class, RepositoryModelTest.class, | |||
FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdUserServiceTest.class, | |||
@@ -65,9 +65,9 @@ import com.gitblit.utils.JGitUtils; | |||
public class GitBlitSuite { | |||
public static final File REPOSITORIES = new File("data/git"); | |||
public static final File SETTINGS = new File("src/test/config/test-gitblit.properties"); | |||
public static final File USERSCONF = new File("src/test/config/test-users.conf"); | |||
static int port = 8280; | |||
@@ -102,11 +102,11 @@ public class GitBlitSuite { | |||
JGitUtils.createRepository(REPOSITORIES, "gb-issues.git").close(); | |||
return getRepository("gb-issues.git"); | |||
} | |||
public static Repository getGitectiveRepository() throws Exception { | |||
return getRepository("test/gitective.git"); | |||
} | |||
private static Repository getRepository(String name) throws Exception { | |||
File gitDir = FileKey.resolve(new File(REPOSITORIES, name), FS.DETECTED); | |||
Repository repository = new FileRepositoryBuilder().setGitDir(gitDir).build(); | |||
@@ -118,11 +118,12 @@ public class GitBlitSuite { | |||
// already started | |||
return false; | |||
} | |||
GitServletTest.deleteWorkingFolders(); | |||
// Start a Gitblit instance | |||
Executors.newSingleThreadExecutor().execute(new Runnable() { | |||
@Override | |||
public void run() { | |||
GitBlitServer.main("--httpPort", "" + port, "--httpsPort", "0", "--shutdownPort", | |||
"" + shutdownPort, "--gitPort", "" + gitPort, "--repositoriesFolder", | |||
@@ -158,13 +159,13 @@ public class GitBlitSuite { | |||
cloneOrFetch("test/helloworld.git", "https://github.com/git/hello-world.git"); | |||
cloneOrFetch("test/ambition.git", "https://github.com/defunkt/ambition.git"); | |||
cloneOrFetch("test/gitective.git", "https://github.com/kevinsawicki/gitective.git"); | |||
enableTickets("ticgit.git"); | |||
enableDocs("ticgit.git"); | |||
showRemoteBranches("ticgit.git"); | |||
automaticallyTagBranchTips("ticgit.git"); | |||
showRemoteBranches("test/jgit.git"); | |||
automaticallyTagBranchTips("test/jgit.git"); | |||
automaticallyTagBranchTips("test/jgit.git"); | |||
} | |||
} | |||
@@ -212,7 +213,7 @@ public class GitBlitSuite { | |||
g.printStackTrace(); | |||
} | |||
} | |||
private static void automaticallyTagBranchTips(String repositoryName) { | |||
try { | |||
RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName); | |||
@@ -222,7 +223,7 @@ public class GitBlitSuite { | |||
g.printStackTrace(); | |||
} | |||
} | |||
public static void close(File repository) { | |||
try { | |||
File gitDir = FileKey.resolve(repository, FS.detect()); | |||
@@ -233,11 +234,11 @@ public class GitBlitSuite { | |||
e.printStackTrace(); | |||
} | |||
} | |||
public static void close(Git git) { | |||
close(git.getRepository()); | |||
} | |||
public static void close(Repository r) { | |||
RepositoryCache.close(r); | |||
@@ -1,87 +0,0 @@ | |||
/* | |||
* 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.tests; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertTrue; | |||
import java.util.List; | |||
import org.eclipse.jgit.lib.Repository; | |||
import org.junit.Test; | |||
import com.gitblit.models.RefModel; | |||
import com.gitblit.models.TicketModel; | |||
import com.gitblit.models.TicketModel.Comment; | |||
import com.gitblit.utils.TicgitUtils; | |||
public class TicgitUtilsTest { | |||
@Test | |||
public void testTicgitBranch() throws Exception { | |||
Repository repository = GitBlitSuite.getTicgitRepository(); | |||
RefModel branch = TicgitUtils.getTicketsBranch(repository); | |||
repository.close(); | |||
assertNotNull("Ticgit branch does not exist!", branch); | |||
repository = GitBlitSuite.getHelloworldRepository(); | |||
branch = TicgitUtils.getTicketsBranch(repository); | |||
repository.close(); | |||
assertNull("Ticgit branch exists!", branch); | |||
} | |||
@Test | |||
public void testRetrieveTickets() throws Exception { | |||
Repository repository = GitBlitSuite.getTicgitRepository(); | |||
List<TicketModel> ticketsA = TicgitUtils.getTickets(repository); | |||
List<TicketModel> ticketsB = TicgitUtils.getTickets(repository); | |||
repository.close(); | |||
assertTrue("No tickets found!", ticketsA.size() > 0); | |||
for (int i = 0; i < ticketsA.size(); i++) { | |||
TicketModel ticketA = ticketsA.get(i); | |||
TicketModel ticketB = ticketsB.get(i); | |||
assertTrue("Tickets are not equal!", ticketA.equals(ticketB)); | |||
assertFalse(ticketA.equals("")); | |||
assertTrue(ticketA.hashCode() == ticketA.id.hashCode()); | |||
for (int j = 0; j < ticketA.comments.size(); j++) { | |||
Comment commentA = ticketA.comments.get(j); | |||
Comment commentB = ticketB.comments.get(j); | |||
assertTrue("Comments are not equal!", commentA.equals(commentB)); | |||
assertFalse(commentA.equals("")); | |||
assertEquals(commentA.hashCode(), commentA.text.hashCode()); | |||
} | |||
} | |||
repository = GitBlitSuite.getHelloworldRepository(); | |||
List<TicketModel> ticketsC = TicgitUtils.getTickets(repository); | |||
repository.close(); | |||
assertNull(ticketsC); | |||
} | |||
@Test | |||
public void testReadTicket() throws Exception { | |||
Repository repository = GitBlitSuite.getTicgitRepository(); | |||
List<TicketModel> tickets = TicgitUtils.getTickets(repository); | |||
TicketModel ticket = TicgitUtils | |||
.getTicket(repository, tickets.get(tickets.size() - 1).name); | |||
repository.close(); | |||
assertNotNull(ticket); | |||
assertEquals("1206206148_add-attachment-to-ticket_138", ticket.name); | |||
} | |||
} |