Automatic detection also will now also display a plain text "readme" or "readme.txt" file. Change-Id: Id6be729bdc469e7a5cfd1f4144df340a6b93475etags/v1.4.0
@@ -23,6 +23,8 @@ r20: { | |||
- Updated default binary and Lucene ignore extensions | |||
- Change the WAR baseFolder context parameter to a JNDI env-entry to improve enterprise deployments | |||
- Removed internal Gitblit ref exclusions in the upload pack | |||
- Removed "show readme" setting in favor of automatic detection | |||
- Support plain text "readme" files | |||
additions: | |||
- Added branch graph image servlet based on EGit's branch graph renderer (issue-194) | |||
- Added option to render Markdown commit messages (issue-203) |
@@ -2015,7 +2015,6 @@ public class GitBlit implements ServletContextListener { | |||
model.verifyCommitter = getConfig(config, "verifyCommitter", false); | |||
model.showRemoteBranches = getConfig(config, "showRemoteBranches", hasOrigin); | |||
model.isFrozen = getConfig(config, "isFrozen", false); | |||
model.showReadme = getConfig(config, "showReadme", false); | |||
model.skipSizeCalculation = getConfig(config, "skipSizeCalculation", false); | |||
model.skipSummaryMetrics = getConfig(config, "skipSummaryMetrics", false); | |||
model.commitMessageRenderer = CommitMessageRenderer.fromName(getConfig(config, "commitMessageRenderer", | |||
@@ -2578,7 +2577,6 @@ public class GitBlit implements ServletContextListener { | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "verifyCommitter", repository.verifyCommitter); | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "showRemoteBranches", repository.showRemoteBranches); | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "isFrozen", repository.isFrozen); | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "showReadme", repository.showReadme); | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "skipSizeCalculation", repository.skipSizeCalculation); | |||
config.setBoolean(Constants.CONFIG_GITBLIT, null, "skipSummaryMetrics", repository.skipSummaryMetrics); | |||
config.setString(Constants.CONFIG_GITBLIT, null, "federationStrategy", |
@@ -94,8 +94,6 @@ public class EditRepositoryDialog extends JDialog { | |||
private JCheckBox showRemoteBranches; | |||
private JCheckBox showReadme; | |||
private JCheckBox skipSizeCalculation; | |||
private JCheckBox skipSummaryMetrics; | |||
@@ -216,8 +214,6 @@ public class EditRepositoryDialog extends JDialog { | |||
showRemoteBranches = new JCheckBox( | |||
Translation.get("gb.showRemoteBranchesDescription"), | |||
anRepository.showRemoteBranches); | |||
showReadme = new JCheckBox(Translation.get("gb.showReadmeDescription"), | |||
anRepository.showReadme); | |||
skipSizeCalculation = new JCheckBox( | |||
Translation.get("gb.skipSizeCalculationDescription"), | |||
anRepository.skipSizeCalculation); | |||
@@ -312,8 +308,6 @@ public class EditRepositoryDialog extends JDialog { | |||
.add(newFieldPanel(Translation.get("gb.enableIncrementalPushTags"), useIncrementalPushTags)); | |||
fieldsPanel.add(newFieldPanel(Translation.get("gb.showRemoteBranches"), | |||
showRemoteBranches)); | |||
fieldsPanel.add(newFieldPanel(Translation.get("gb.showReadme"), | |||
showReadme)); | |||
fieldsPanel | |||
.add(newFieldPanel(Translation.get("gb.skipSizeCalculation"), | |||
skipSizeCalculation)); | |||
@@ -567,7 +561,6 @@ public class EditRepositoryDialog extends JDialog { | |||
repository.useDocs = useDocs.isSelected(); | |||
repository.useIncrementalPushTags = useIncrementalPushTags.isSelected(); | |||
repository.showRemoteBranches = showRemoteBranches.isSelected(); | |||
repository.showReadme = showReadme.isSelected(); | |||
repository.skipSizeCalculation = skipSizeCalculation.isSelected(); | |||
repository.skipSummaryMetrics = skipSummaryMetrics.isSelected(); | |||
repository.maxActivityCommits = (Integer) maxActivityCommits.getSelectedItem(); |
@@ -58,7 +58,6 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel | |||
public AuthorizationControl authorizationControl; | |||
public boolean allowAuthenticated; | |||
public boolean isFrozen; | |||
public boolean showReadme; | |||
public FederationStrategy federationStrategy; | |||
public List<String> federationSets; | |||
public boolean isFederated; | |||
@@ -208,7 +207,6 @@ public class RepositoryModel implements Serializable, Comparable<RepositoryModel | |||
clone.accessRestriction = AccessRestrictionType.PUSH; | |||
clone.authorizationControl = AuthorizationControl.NAMED; | |||
clone.federationStrategy = federationStrategy; | |||
clone.showReadme = showReadme; | |||
clone.showRemoteBranches = false; | |||
clone.allowForks = false; | |||
clone.useDocs = useDocs; |
@@ -32,6 +32,21 @@ import org.pegdown.PegDownProcessor; | |||
*/ | |||
public class MarkdownUtils { | |||
/** | |||
* Returns the html version of the plain source text. | |||
* | |||
* @param text | |||
* @return html version of plain text | |||
* @throws java.text.ParseException | |||
*/ | |||
public static String transformPlainText(String text) { | |||
// url auto-linking | |||
text = text.replaceAll("((http|https)://[0-9A-Za-z-_=\\?\\.\\$#&/]*)", "<a href=\"$1\">$1</a>"); | |||
String html = "<pre>" + text + "</pre>"; | |||
return html; | |||
} | |||
/** | |||
* Returns the html version of the markdown source text. | |||
* |
@@ -36,14 +36,13 @@ | |||
<tr><th><wicket:message key="gb.enableDocs"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="useDocs" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.useDocsDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.enableIncrementalPushTags"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="useIncrementalPushTags" tabindex="8" /> <span class="help-inline"><wicket:message key="gb.useIncrementalPushTagsDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.showRemoteBranches"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="showRemoteBranches" tabindex="9" /> <span class="help-inline"><wicket:message key="gb.showRemoteBranchesDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.showReadme"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="showReadme" tabindex="10" /> <span class="help-inline"><wicket:message key="gb.showReadmeDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.skipSizeCalculation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="skipSizeCalculation" tabindex="11" /> <span class="help-inline"><wicket:message key="gb.skipSizeCalculationDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.skipSummaryMetrics"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="skipSummaryMetrics" tabindex="12" /> <span class="help-inline"><wicket:message key="gb.skipSummaryMetricsDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.maxActivityCommits"></wicket:message></th><td class="edit"><select class="span2" wicket:id="maxActivityCommits" tabindex="13" /> <span class="help-inline"><wicket:message key="gb.maxActivityCommitsDescription"></wicket:message></span></td></tr> | |||
<tr><th><wicket:message key="gb.metricAuthorExclusions"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="metricAuthorExclusions" size="40" tabindex="14" /></td></tr> | |||
<tr><th><wicket:message key="gb.commitMessageRenderer"></wicket:message></th><td class="edit"><select class="span2" wicket:id="commitMessageRenderer" tabindex="15" /></td></tr> | |||
<tr><th><wicket:message key="gb.skipSizeCalculation"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="skipSizeCalculation" tabindex="10" /> <span class="help-inline"><wicket:message key="gb.skipSizeCalculationDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.skipSummaryMetrics"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="skipSummaryMetrics" tabindex="11" /> <span class="help-inline"><wicket:message key="gb.skipSummaryMetricsDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.maxActivityCommits"></wicket:message></th><td class="edit"><select class="span2" wicket:id="maxActivityCommits" tabindex="12" /> <span class="help-inline"><wicket:message key="gb.maxActivityCommitsDescription"></wicket:message></span></td></tr> | |||
<tr><th><wicket:message key="gb.metricAuthorExclusions"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="metricAuthorExclusions" size="40" tabindex="13" /></td></tr> | |||
<tr><th><wicket:message key="gb.commitMessageRenderer"></wicket:message></th><td class="edit"><select class="span2" wicket:id="commitMessageRenderer" tabindex="14" /></td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
<tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="16" /></td></tr> | |||
<tr><th><wicket:message key="gb.mailingLists"></wicket:message></th><td class="edit"><input class="span8" type="text" wicket:id="mailingLists" size="40" tabindex="15" /></td></tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
@@ -52,15 +51,15 @@ | |||
<div class="tab-pane" id="permissions"> | |||
<table class="plain"> | |||
<tbody class="settings"> | |||
<tr><th><wicket:message key="gb.owners"></wicket:message></th><td class="edit"><span wicket:id="owners" tabindex="17" /> </td></tr> | |||
<tr><th><wicket:message key="gb.owners"></wicket:message></th><td class="edit"><span wicket:id="owners" tabindex="16" /> </td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span4" wicket:id="accessRestriction" tabindex="18" /></td></tr> | |||
<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span4" wicket:id="accessRestriction" tabindex="17" /></td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
<tr><th><wicket:message key="gb.authorizationControl"></wicket:message></th><td style="padding:2px;"><span class="authorizationControl" wicket:id="authorizationControl"></span></td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
<tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="isFrozen" tabindex="19" /> <span class="help-inline"><wicket:message key="gb.isFrozenDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.allowForks"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="allowForks" tabindex="20" /> <span class="help-inline"><wicket:message key="gb.allowForksDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.verifyCommitter"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="verifyCommitter" tabindex="21" /> <span class="help-inline"><wicket:message key="gb.verifyCommitterDescription"></wicket:message></span><br/><span class="help-inline" style="padding-left:10px;"><wicket:message key="gb.verifyCommitterNote"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="isFrozen" tabindex="18" /> <span class="help-inline"><wicket:message key="gb.isFrozenDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.allowForks"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="allowForks" tabindex="19" /> <span class="help-inline"><wicket:message key="gb.allowForksDescription"></wicket:message></span></label></td></tr> | |||
<tr><th><wicket:message key="gb.verifyCommitter"></wicket:message></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="verifyCommitter" tabindex="20" /> <span class="help-inline"><wicket:message key="gb.verifyCommitterDescription"></wicket:message></span><br/><span class="help-inline" style="padding-left:10px;"><wicket:message key="gb.verifyCommitterNote"></wicket:message></span></label></td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
<tr><th><wicket:message key="gb.userPermissions"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr> | |||
<tr><th colspan="2"><hr/></th></tr> | |||
@@ -73,7 +72,7 @@ | |||
<div class="tab-pane" id="federation"> | |||
<table class="plain"> | |||
<tbody class="settings"> | |||
<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span4" wicket:id="federationStrategy" tabindex="22" /></td></tr> | |||
<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span4" wicket:id="federationStrategy" tabindex="21" /></td></tr> | |||
<tr><th><wicket:message key="gb.federationSets"></wicket:message></th><td style="padding:2px;"><span wicket:id="federationSets"></span></td></tr> | |||
</tbody> | |||
</table> |
@@ -448,7 +448,6 @@ public class EditRepositoryPage extends RootSubPage { | |||
form.add(new CheckBox("useDocs")); | |||
form.add(new CheckBox("useIncrementalPushTags")); | |||
form.add(new CheckBox("showRemoteBranches")); | |||
form.add(new CheckBox("showReadme")); | |||
form.add(new CheckBox("skipSizeCalculation")); | |||
form.add(new CheckBox("skipSummaryMetrics")); | |||
List<Integer> maxActivityCommits = Arrays.asList(-1, 0, 25, 50, 75, 100, 150, 200, 250, 500 ); |
@@ -204,7 +204,7 @@ public abstract class RepositoryPage extends RootPage { | |||
// conditional links | |||
// per-repository extra page links | |||
if (model.showReadme || model.useDocs) { | |||
if (model.useDocs) { | |||
pages.put("docs", new PageRegistration("gb.docs", DocsPage.class, params, true)); | |||
} | |||
if (JGitUtils.getPagesBranch(r) != null) { |
@@ -48,7 +48,16 @@ | |||
<div wicket:id="readmeContent" class="markdown"></div> | |||
</div> | |||
</wicket:fragment> | |||
<wicket:fragment wicket:id="plaintextPanel"> | |||
<div class="header" style="margin-top:0px;" > | |||
<i style="vertical-align: middle;" class="icon-book"></i> | |||
<span style="font-weight:bold;vertical-align:middle;" wicket:id="readmeFile"></span> | |||
</div> | |||
<div style="border:1px solid #ddd;border-radius: 0 0 3px 3px;padding: 20px;"> | |||
<div wicket:id="readmeContent"></div> | |||
</div> | |||
</wicket:fragment> | |||
<wicket:fragment wicket:id="ownersFragment"> | |||
</wicket:fragment> |
@@ -137,47 +137,56 @@ public class SummaryPage extends RepositoryPage { | |||
add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty()); | |||
add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty()); | |||
if (getRepositoryModel().showReadme) { | |||
String htmlText = null; | |||
String markdownText = null; | |||
String readme = null; | |||
try { | |||
RevCommit head = JGitUtils.getCommit(r, null); | |||
List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
List<PathModel> paths = JGitUtils.getFilesInPath(r, null, head); | |||
for (PathModel path : paths) { | |||
if (!path.isTree()) { | |||
String name = path.name.toLowerCase(); | |||
if (name.startsWith("readme")) { | |||
if (name.indexOf('.') > -1) { | |||
String ext = name.substring(name.lastIndexOf('.') + 1); | |||
if (markdownExtensions.contains(ext)) { | |||
readme = path.name; | |||
break; | |||
} | |||
String htmlText = null; | |||
String markdownText = null; | |||
String readme = null; | |||
boolean isMarkdown = false; | |||
try { | |||
RevCommit head = JGitUtils.getCommit(r, null); | |||
List<String> markdownExtensions = GitBlit.getStrings(Keys.web.markdownExtensions); | |||
List<PathModel> paths = JGitUtils.getFilesInPath(r, null, head); | |||
for (PathModel path : paths) { | |||
if (!path.isTree()) { | |||
String name = path.name.toLowerCase(); | |||
if (name.equals("readme") || name.equals("readme.txt")) { | |||
readme = path.name; | |||
isMarkdown = false; | |||
} else if (name.startsWith("readme")) { | |||
if (name.indexOf('.') > -1) { | |||
String ext = name.substring(name.lastIndexOf('.') + 1); | |||
if (markdownExtensions.contains(ext)) { | |||
readme = path.name; | |||
isMarkdown = true; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
if (!StringUtils.isEmpty(readme)) { | |||
String [] encodings = GitBlit.getEncodings(); | |||
markdownText = JGitUtils.getStringContent(r, head.getTree(), readme, encodings); | |||
} | |||
if (!StringUtils.isEmpty(readme)) { | |||
String [] encodings = GitBlit.getEncodings(); | |||
markdownText = JGitUtils.getStringContent(r, head.getTree(), readme, encodings); | |||
if (isMarkdown) { | |||
htmlText = MarkdownUtils.transformMarkdown(markdownText); | |||
} else { | |||
htmlText = MarkdownUtils.transformPlainText(markdownText); | |||
} | |||
} catch (Exception e) { | |||
logger.error("failed to transform markdown", e); | |||
markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText); | |||
htmlText = StringUtils.breakLinesForHtml(markdownText); | |||
} | |||
Fragment fragment = new Fragment("readme", "markdownPanel"); | |||
} catch (Exception e) { | |||
logger.error("failed to transform markdown", e); | |||
markdownText = MessageFormat.format("<div class=\"alert alert-error\"><strong>{0}:</strong> {1}</div>{2}", getString("gb.error"), getString("gb.markdownFailure"), markdownText); | |||
htmlText = MarkdownUtils.transformPlainText(markdownText); | |||
} | |||
if (StringUtils.isEmpty(htmlText)) { | |||
add(new Label("readme").setVisible(false)); | |||
} else { | |||
Fragment fragment = new Fragment("readme", isMarkdown ? "markdownPanel" : "plaintextPanel"); | |||
fragment.add(new Label("readmeFile", readme)); | |||
// Add the html to the page | |||
Component content = new Label("readmeContent", htmlText).setEscapeModelStrings(false); | |||
fragment.add(content.setVisible(!StringUtils.isEmpty(htmlText))); | |||
add(fragment); | |||
} else { | |||
add(new Label("readme").setVisible(false)); | |||
} | |||
// Display an activity line graph |