Merge changes from topic 'gitweb-cleanup'
* changes: Use consistent lowercase for "gitweb" GitWebConfig: Minor cleanup Move logic from GitWebType to GitWebConfig Extract CGI configuration from GitWebConfig GitWebConfig: Fix check for set-to-empty-string
This commit is contained in:
commit
b3f83e2ec6
@ -1763,7 +1763,7 @@ Whether or not Gerrit should encode the generated viewer URL.
|
|||||||
+
|
+
|
||||||
Gerrit composes the viewer URL using information about the project, branch, file
|
Gerrit composes the viewer URL using information about the project, branch, file
|
||||||
or commit of the target object to be displayed. Typically viewers such as CGit
|
or commit of the target object to be displayed. Typically viewers such as CGit
|
||||||
and GitWeb do need those parts to be encoded, including the '/' in project's name,
|
and gitweb do need those parts to be encoded, including the '/' in project's name,
|
||||||
for being correctly parsed.
|
for being correctly parsed.
|
||||||
However other viewers could instead require an unencoded URL (e.g. GitHub web
|
However other viewers could instead require an unencoded URL (e.g. GitHub web
|
||||||
based viewer)
|
based viewer)
|
||||||
|
@ -67,12 +67,12 @@ able to read the gitweb info for any of the branches in that project.
|
|||||||
|
|
||||||
For the external configuration, gitweb runs under the control of an
|
For the external configuration, gitweb runs under the control of an
|
||||||
external web server, and Gerrit access controls are not enforced. Gerrit
|
external web server, and Gerrit access controls are not enforced. Gerrit
|
||||||
provides configuration parameters for integration with GitWeb.
|
provides configuration parameters for integration with gitweb.
|
||||||
|
|
||||||
[[linuxGitWeb]]
|
[[linuxGitWeb]]
|
||||||
==== Linux Installation
|
==== Linux Installation
|
||||||
|
|
||||||
===== Install GitWeb
|
===== Install Gitweb
|
||||||
|
|
||||||
On Ubuntu:
|
On Ubuntu:
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ With Yum:
|
|||||||
$ yum install gitweb
|
$ yum install gitweb
|
||||||
====
|
====
|
||||||
|
|
||||||
===== Configure GitWeb
|
===== Configure Gitweb
|
||||||
|
|
||||||
|
|
||||||
Update `/etc/gitweb.conf`, add the public GIT repositories:
|
Update `/etc/gitweb.conf`, add the public GIT repositories:
|
||||||
@ -161,7 +161,7 @@ link:http://localhost/gitweb[http://localhost/gitweb]
|
|||||||
[[WindowsGitWeb]]
|
[[WindowsGitWeb]]
|
||||||
==== Windows Installation
|
==== Windows Installation
|
||||||
|
|
||||||
Instructions are available for installing the GitWeb module distributed with
|
Instructions are available for installing the gitweb module distributed with
|
||||||
MsysGit:
|
MsysGit:
|
||||||
|
|
||||||
link:https://github.com/msysgit/msysgit/wiki/GitWeb[GitWeb]
|
link:https://github.com/msysgit/msysgit/wiki/GitWeb[GitWeb]
|
||||||
@ -176,7 +176,7 @@ If you're still having difficulty setting up permissions, you may find this
|
|||||||
tech note useful for configuring Apache Service to run under another account.
|
tech note useful for configuring Apache Service to run under another account.
|
||||||
You must grant the new account link:http://technet.microsoft.com/en-us/library/cc794944(WS.10).aspx["run as service"] permission:
|
You must grant the new account link:http://technet.microsoft.com/en-us/library/cc794944(WS.10).aspx["run as service"] permission:
|
||||||
|
|
||||||
The GitWeb version in msysgit is missing several important and required
|
The gitweb version in msysgit is missing several important and required
|
||||||
perl modules, including CGI.pm. The perl included with the msysgit distro 1.7.8
|
perl modules, including CGI.pm. The perl included with the msysgit distro 1.7.8
|
||||||
is broken.. The link:http://groups.google.com/group/msysgit/browse_thread/thread/ba3501f1f0ed95af[unicore folder is missing along with utf8_heavy.pl and CGI.pm]. You can
|
is broken.. The link:http://groups.google.com/group/msysgit/browse_thread/thread/ba3501f1f0ed95af[unicore folder is missing along with utf8_heavy.pl and CGI.pm]. You can
|
||||||
verify by checking for perl modules. From an msys console, execute the
|
verify by checking for perl modules. From an msys console, execute the
|
||||||
@ -207,7 +207,7 @@ contents: `bin/` `lib/` `site/`
|
|||||||
|
|
||||||
copy the contents of lib into `msysgit/lib/perl5/5.8.8` and overwrite existing files.
|
copy the contents of lib into `msysgit/lib/perl5/5.8.8` and overwrite existing files.
|
||||||
|
|
||||||
==== Enable GitWeb Integration
|
==== Enable Gitweb Integration
|
||||||
|
|
||||||
To enable the external gitweb integration, set
|
To enable the external gitweb integration, set
|
||||||
link:config-gerrit.html#gitweb.url[gitweb.url] with the URL of your
|
link:config-gerrit.html#gitweb.url[gitweb.url] with the URL of your
|
||||||
|
@ -166,7 +166,7 @@ Project]
|
|||||||
|
|
||||||
This plugin allows the rendering of Git repository branch network in a
|
This plugin allows the rendering of Git repository branch network in a
|
||||||
graphical HTML5 Canvas. It is mainly intended to be used as a
|
graphical HTML5 Canvas. It is mainly intended to be used as a
|
||||||
"project link" in a GitWeb configuration or by other Gerrit GWT UI
|
"project link" in a gitweb configuration or by other Gerrit GWT UI
|
||||||
plugins to be plugged elsewhere in Gerrit.
|
plugins to be plugged elsewhere in Gerrit.
|
||||||
|
|
||||||
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/branch-network[
|
link:https://gerrit-review.googlesource.com/#/admin/projects/plugins/branch-network[
|
||||||
|
@ -63,7 +63,7 @@ always see how the access rights were changed and by whom. If a good
|
|||||||
commit message is provided you can also see from the history why the
|
commit message is provided you can also see from the history why the
|
||||||
access rights were modified.
|
access rights were modified.
|
||||||
|
|
||||||
If a Git browser such as GitWeb is configured for the Gerrit server you
|
If a Git browser such as gitweb is configured for the Gerrit server you
|
||||||
can find a link to the history of the `project.config` file in the
|
can find a link to the history of the `project.config` file in the
|
||||||
Web UI. Otherwise you may inspect the history locally. If you have
|
Web UI. Otherwise you may inspect the history locally. If you have
|
||||||
cloned the repository you can do this by executing the following
|
cloned the repository you can do this by executing the following
|
||||||
|
@ -1165,48 +1165,48 @@ bugs link].
|
|||||||
|=================================
|
|=================================
|
||||||
|
|
||||||
[[git-web-info]]
|
[[git-web-info]]
|
||||||
=== GitWebInfo
|
=== GitwebInfo
|
||||||
The `GitWebInfo` entity contains information about the
|
The `GitwebInfo` entity contains information about the
|
||||||
link:config-gerrit.html#gitweb[GitWeb] configuration.
|
link:config-gerrit.html#gitweb[gitweb] configuration.
|
||||||
|
|
||||||
[options="header",cols="1,6"]
|
[options="header",cols="1,6"]
|
||||||
|=======================
|
|=======================
|
||||||
|Field Name |Description
|
|Field Name |Description
|
||||||
|`url` |
|
|`url` |
|
||||||
The link:config-gerrit.html#gitweb.url[GitWeb base URL].
|
The link:config-gerrit.html#gitweb.url[gitweb base URL].
|
||||||
|`type` |
|
|`type` |
|
||||||
The link:config-gerrit.html#gitweb.type[GitWeb type] as
|
The link:config-gerrit.html#gitweb.type[gitweb type] as
|
||||||
link:#git-web-type-info[GitWebTypeInfo] entity.
|
link:#git-web-type-info[GitwebTypeInfo] entity.
|
||||||
|=======================
|
|=======================
|
||||||
|
|
||||||
[[git-web-type-info]]
|
[[git-web-type-info]]
|
||||||
=== GitWebTypeInfo
|
=== GitwebTypeInfo
|
||||||
The `GitWebTypeInfo` entity contains information about the
|
The `GitwebTypeInfo` entity contains information about the
|
||||||
link:config-gerrit.html#gitweb[GitWeb] configuration.
|
link:config-gerrit.html#gitweb[gitweb] configuration.
|
||||||
|
|
||||||
[options="header",cols="1,^1,5"]
|
[options="header",cols="1,^1,5"]
|
||||||
|=============================
|
|=============================
|
||||||
|Field Name ||Description
|
|Field Name ||Description
|
||||||
|`name` ||
|
|`name` ||
|
||||||
The link:config-gerrit.html#gitweb.linkname[GitWeb link name].
|
The link:config-gerrit.html#gitweb.linkname[gitweb link name].
|
||||||
|`revision` |optional|
|
|`revision` |optional|
|
||||||
The link:config-gerrit.html#gitweb.revision[GitWeb revision pattern].
|
The link:config-gerrit.html#gitweb.revision[gitweb revision pattern].
|
||||||
|`project` |optional|
|
|`project` |optional|
|
||||||
The link:config-gerrit.html#gitweb.project[GitWeb project pattern].
|
The link:config-gerrit.html#gitweb.project[gitweb project pattern].
|
||||||
|`branch` |optional|
|
|`branch` |optional|
|
||||||
The link:config-gerrit.html#gitweb.branch[GitWeb branch pattern].
|
The link:config-gerrit.html#gitweb.branch[gitweb branch pattern].
|
||||||
|`root_tree` |optional|
|
|`root_tree` |optional|
|
||||||
The link:config-gerrit.html#gitweb.roottree[GitWeb root tree pattern].
|
The link:config-gerrit.html#gitweb.roottree[gitweb root tree pattern].
|
||||||
|`file` |optional|
|
|`file` |optional|
|
||||||
The link:config-gerrit.html#gitweb.file[GitWeb file pattern].
|
The link:config-gerrit.html#gitweb.file[gitweb file pattern].
|
||||||
|`file_history` |optional|
|
|`file_history` |optional|
|
||||||
The link:config-gerrit.html#gitweb.filehistory[GitWeb file history
|
The link:config-gerrit.html#gitweb.filehistory[gitweb file history
|
||||||
pattern].
|
pattern].
|
||||||
|`path_separator`||
|
|`path_separator`||
|
||||||
The link:config-gerrit.html#gitweb.pathSeparator[GitWeb path separator].
|
The link:config-gerrit.html#gitweb.pathSeparator[gitweb path separator].
|
||||||
|`link_drafts` |optional|
|
|`link_drafts` |optional|
|
||||||
link:config-gerrit.html#gitweb.linkDrafts[Whether Gerrit should provide
|
link:config-gerrit.html#gitweb.linkDrafts[Whether Gerrit should provide
|
||||||
links to GitWeb on draft patch set.]
|
links to gitweb on draft patch set.]
|
||||||
|`url_encode` |optional|
|
|`url_encode` |optional|
|
||||||
link:config-gerrit.html#gitweb.urlEncode[Whether Gerrit should encode
|
link:config-gerrit.html#gitweb.urlEncode[Whether Gerrit should encode
|
||||||
the generated viewer URL.]
|
the generated viewer URL.]
|
||||||
@ -1300,9 +1300,9 @@ information about Gerrit
|
|||||||
Information about the configuration from the
|
Information about the configuration from the
|
||||||
link:config-gerrit.html#gerrit[gerrit] section as link:#gerrit-info[
|
link:config-gerrit.html#gerrit[gerrit] section as link:#gerrit-info[
|
||||||
GerritInfo] entity.
|
GerritInfo] entity.
|
||||||
|`git_web` |optional|
|
|`gitweb ` |optional|
|
||||||
Information about the link:config-gerrit.html#gitweb[GitWeb]
|
Information about the link:config-gerrit.html#gitweb[gitweb]
|
||||||
configuration as link:#git-web-info[GitWebInfo] entity.
|
configuration as link:#git-web-info[GitwebInfo] entity.
|
||||||
|`sshd` |optional|
|
|`sshd` |optional|
|
||||||
Information about the configuration from the
|
Information about the configuration from the
|
||||||
link:config-gerrit.html#sshd[sshd] section as link:#sshd-info[SshdInfo]
|
link:config-gerrit.html#sshd[sshd] section as link:#sshd-info[SshdInfo]
|
||||||
|
@ -94,7 +94,7 @@ The commit ID, the parent commit(s) and the link:user-changeid.html[Change-Id] a
|
|||||||
displayed with a copy-to-clipboard icon that allows the ID to be copied
|
displayed with a copy-to-clipboard icon that allows the ID to be copied
|
||||||
into the clipboard.
|
into the clipboard.
|
||||||
|
|
||||||
If a Git web browser, such as GitWeb or Gitiles, is configured, there
|
If a Git web browser, such as gitweb or Gitiles, is configured, there
|
||||||
is also a link to the commit in the Git web browser.
|
is also a link to the commit in the Git web browser.
|
||||||
|
|
||||||
image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"]
|
image::images/user-review-ui-change-screen-commit-info.png[width=800, link="images/user-review-ui-change-screen-commit-info.png"]
|
||||||
|
@ -108,7 +108,7 @@ public class ServerInfoIT extends AbstractDaemonTest {
|
|||||||
assertThat(i.gerrit.reportBugText).isEqualTo("REPORT BUG");
|
assertThat(i.gerrit.reportBugText).isEqualTo("REPORT BUG");
|
||||||
|
|
||||||
// gitweb
|
// gitweb
|
||||||
assertThat(i.gitWeb).isNull();
|
assertThat(i.gitweb).isNull();
|
||||||
|
|
||||||
// sshd
|
// sshd
|
||||||
assertThat(i.sshd).isNotNull();
|
assertThat(i.sshd).isNotNull();
|
||||||
@ -161,7 +161,7 @@ public class ServerInfoIT extends AbstractDaemonTest {
|
|||||||
assertThat(i.gerrit.reportBugText).isNull();
|
assertThat(i.gerrit.reportBugText).isNull();
|
||||||
|
|
||||||
// gitweb
|
// gitweb
|
||||||
assertThat(i.gitWeb).isNull();
|
assertThat(i.gitweb).isNull();
|
||||||
|
|
||||||
// sshd
|
// sshd
|
||||||
assertThat(i.sshd).isNotNull();
|
assertThat(i.sshd).isNotNull();
|
||||||
|
@ -1,275 +0,0 @@
|
|||||||
// Copyright (C) 2009 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// 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.google.gerrit.common.data;
|
|
||||||
|
|
||||||
/** Class to store information about different gitweb types. */
|
|
||||||
public class GitWebType {
|
|
||||||
/**
|
|
||||||
* Get a GitWebType based on the given name.
|
|
||||||
*
|
|
||||||
* @param name Name to look for.
|
|
||||||
* @return GitWebType from the given name, else null if not found.
|
|
||||||
*/
|
|
||||||
public static GitWebType fromName(final String name) {
|
|
||||||
final GitWebType type;
|
|
||||||
|
|
||||||
if (name == null || name.isEmpty() || name.equalsIgnoreCase("gitweb")) {
|
|
||||||
type = new GitWebType();
|
|
||||||
type.setLinkName("gitweb");
|
|
||||||
type.setProject("?p=${project}.git;a=summary");
|
|
||||||
type.setRevision("?p=${project}.git;a=commit;h=${commit}");
|
|
||||||
type.setBranch("?p=${project}.git;a=shortlog;h=${branch}");
|
|
||||||
type.setRootTree("?p=${project}.git;a=tree;hb=${commit}");
|
|
||||||
type.setFile("?p=${project}.git;hb=${commit};f=${file}");
|
|
||||||
type.setFileHistory("?p=${project}.git;a=history;hb=${branch};f=${file}");
|
|
||||||
} else if (name.equalsIgnoreCase("cgit")) {
|
|
||||||
type = new GitWebType();
|
|
||||||
type.setLinkName("cgit");
|
|
||||||
type.setProject("${project}.git/summary");
|
|
||||||
type.setRevision("${project}.git/commit/?id=${commit}");
|
|
||||||
type.setBranch("${project}.git/log/?h=${branch}");
|
|
||||||
type.setRootTree("${project}.git/tree/?h=${commit}");
|
|
||||||
type.setFile("${project}.git/tree/${file}?h=${commit}");
|
|
||||||
type.setFileHistory("${project}.git/log/${file}?h=${branch}");
|
|
||||||
} else if (name.equalsIgnoreCase("custom")) {
|
|
||||||
type = new GitWebType();
|
|
||||||
// The custom name is not defined, let's keep the old style of using GitWeb
|
|
||||||
type.setLinkName("gitweb");
|
|
||||||
} else {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** name of the type. */
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/** String for revision view url. */
|
|
||||||
private String revision;
|
|
||||||
|
|
||||||
/** ParameterizedString for project view url. */
|
|
||||||
private String project;
|
|
||||||
|
|
||||||
/** ParameterizedString for branch view url. */
|
|
||||||
private String branch;
|
|
||||||
|
|
||||||
/** ParameterizedString for root tree view url. */
|
|
||||||
private String rootTree;
|
|
||||||
|
|
||||||
/** ParameterizedString for file view url. */
|
|
||||||
private String file;
|
|
||||||
|
|
||||||
/** ParameterizedString for file history view url. */
|
|
||||||
private String fileHistory;
|
|
||||||
|
|
||||||
/** Character to substitute the standard path separator '/' in branch and
|
|
||||||
* project names */
|
|
||||||
private char pathSeparator = '/';
|
|
||||||
|
|
||||||
/** Whether to include links to draft patch sets */
|
|
||||||
private boolean linkDrafts;
|
|
||||||
|
|
||||||
/** Whether to encode URL segments */
|
|
||||||
private boolean urlEncode;
|
|
||||||
|
|
||||||
/** Private default constructor for gson. */
|
|
||||||
protected GitWebType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for branch view.
|
|
||||||
*
|
|
||||||
* @return The String for branch view
|
|
||||||
*/
|
|
||||||
public String getBranch() {
|
|
||||||
return branch;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for link-name of the type.
|
|
||||||
*
|
|
||||||
* @return The String for link-name of the type
|
|
||||||
*/
|
|
||||||
public String getLinkName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for project view.
|
|
||||||
*
|
|
||||||
* @return The String for project view
|
|
||||||
*/
|
|
||||||
public String getProject() {
|
|
||||||
return project;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for revision view.
|
|
||||||
*
|
|
||||||
* @return The String for revision view
|
|
||||||
*/
|
|
||||||
public String getRevision() {
|
|
||||||
return revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for root tree view.
|
|
||||||
*
|
|
||||||
* @return The String for root tree view
|
|
||||||
*/
|
|
||||||
public String getRootTree() {
|
|
||||||
return rootTree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for file view.
|
|
||||||
*
|
|
||||||
* @return The String for file view
|
|
||||||
*/
|
|
||||||
public String getFile() {
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the String for file history view.
|
|
||||||
*
|
|
||||||
* @return The String for file history view
|
|
||||||
*/
|
|
||||||
public String getFileHistory() {
|
|
||||||
return fileHistory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get whether to link to draft patch sets
|
|
||||||
*
|
|
||||||
* @return True to link
|
|
||||||
*/
|
|
||||||
public boolean getLinkDrafts() {
|
|
||||||
return linkDrafts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for branch view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for branch view
|
|
||||||
*/
|
|
||||||
public void setBranch(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
branch = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for link-name type.
|
|
||||||
*
|
|
||||||
* @param name The link-name type
|
|
||||||
*/
|
|
||||||
public void setLinkName(final String name) {
|
|
||||||
if (name != null && !name.isEmpty()) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for project view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for project view
|
|
||||||
*/
|
|
||||||
public void setProject(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
project = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for revision view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for revision view
|
|
||||||
*/
|
|
||||||
public void setRevision(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
revision = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for root tree view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for root tree view
|
|
||||||
*/
|
|
||||||
public void setRootTree(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
rootTree = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for file view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for file view
|
|
||||||
*/
|
|
||||||
public void setFile(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
file = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pattern for file history view.
|
|
||||||
*
|
|
||||||
* @param pattern The pattern for file history view
|
|
||||||
*/
|
|
||||||
public void setFileHistory(final String pattern) {
|
|
||||||
if (pattern != null && !pattern.isEmpty()) {
|
|
||||||
fileHistory = pattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace the standard path separator ('/') in a branch name or project
|
|
||||||
* name with a custom path separator configured by the property
|
|
||||||
* gitweb.pathSeparator.
|
|
||||||
* @param urlSegment The branch or project to replace the path separator in
|
|
||||||
* @return the urlSegment with the standard path separator replaced by the
|
|
||||||
* custom path separator
|
|
||||||
*/
|
|
||||||
public String replacePathSeparator(String urlSegment) {
|
|
||||||
if ('/' != pathSeparator) {
|
|
||||||
return urlSegment.replace('/', pathSeparator);
|
|
||||||
}
|
|
||||||
return urlSegment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the custom path separator
|
|
||||||
* @param separator The custom path separator
|
|
||||||
*/
|
|
||||||
public void setPathSeparator(char separator) {
|
|
||||||
this.pathSeparator = separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLinkDrafts(boolean linkDrafts) {
|
|
||||||
this.linkDrafts = linkDrafts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUrlEncode() {
|
|
||||||
return urlEncode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrlEncode(boolean urlEncode) {
|
|
||||||
this.urlEncode = urlEncode;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,186 @@
|
|||||||
|
// Copyright (C) 2009 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// 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.google.gerrit.common.data;
|
||||||
|
|
||||||
|
/** Class to store information about different source browser types. */
|
||||||
|
public class GitwebType {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String branch;
|
||||||
|
private String file;
|
||||||
|
private String fileHistory;
|
||||||
|
private String project;
|
||||||
|
private String revision;
|
||||||
|
private String rootTree;
|
||||||
|
|
||||||
|
private char pathSeparator = '/';
|
||||||
|
private boolean linkDrafts = true;
|
||||||
|
private boolean urlEncode = true;
|
||||||
|
|
||||||
|
/** @return name displayed in links. */
|
||||||
|
public String getLinkName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name displayed in links.
|
||||||
|
*
|
||||||
|
* @param name new name.
|
||||||
|
*/
|
||||||
|
public void setLinkName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the branch URL. */
|
||||||
|
public String getBranch() {
|
||||||
|
return branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the branch URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setBranch(String str) {
|
||||||
|
branch = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the file URL. */
|
||||||
|
public String getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the file URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setFile(String str) {
|
||||||
|
file = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the file history URL. */
|
||||||
|
public String getFileHistory() {
|
||||||
|
return fileHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the file history URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setFileHistory(String str) {
|
||||||
|
fileHistory = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the project URL. */
|
||||||
|
public String getProject() {
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the project URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setProject(String str) {
|
||||||
|
project = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the revision URL. */
|
||||||
|
public String getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the revision URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setRevision(String str) {
|
||||||
|
revision = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return parameterized string for the root tree URL. */
|
||||||
|
public String getRootTree() {
|
||||||
|
return rootTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameterized string for the root tree URL.
|
||||||
|
*
|
||||||
|
* @param str new string.
|
||||||
|
*/
|
||||||
|
public void setRootTree(String str) {
|
||||||
|
rootTree = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return path separator used for branch and project names. */
|
||||||
|
public char getPathSeparator() {
|
||||||
|
return pathSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the custom path separator.
|
||||||
|
*
|
||||||
|
* @param separator new separator.
|
||||||
|
*/
|
||||||
|
public void setPathSeparator(char separator) {
|
||||||
|
this.pathSeparator = separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether to generate links to draft patch sets. */
|
||||||
|
public boolean getLinkDrafts() {
|
||||||
|
return linkDrafts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to generate links to draft patch sets.
|
||||||
|
*
|
||||||
|
* @param linkDrafts new value.
|
||||||
|
*/
|
||||||
|
public void setLinkDrafts(boolean linkDrafts) {
|
||||||
|
this.linkDrafts = linkDrafts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether to URL encode path segments. */
|
||||||
|
public boolean getUrlEncode() {
|
||||||
|
return urlEncode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to URL encode path segments.
|
||||||
|
*
|
||||||
|
* @param urlEncode new value.
|
||||||
|
*/
|
||||||
|
public void setUrlEncode(boolean urlEncode) {
|
||||||
|
this.urlEncode = urlEncode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace standard path separator with custom configured path separator.
|
||||||
|
*
|
||||||
|
* @param urlSegment URL segment (e.g. branch or project name) in which to
|
||||||
|
* replace the path separator.
|
||||||
|
* @return the segment with the standard path separator replaced by the custom
|
||||||
|
* {@link #getPathSeparator()}.
|
||||||
|
*/
|
||||||
|
public String replacePathSeparator(String urlSegment) {
|
||||||
|
if ('/' != pathSeparator) {
|
||||||
|
return urlSegment.replace('/', pathSeparator);
|
||||||
|
}
|
||||||
|
return urlSegment;
|
||||||
|
}
|
||||||
|
}
|
@ -19,22 +19,16 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class EncodePathSeparatorTest {
|
public class EncodePathSeparatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultBehaviour() {
|
public void testDefaultBehaviour() {
|
||||||
|
assertEquals("a/b", new GitwebType().replacePathSeparator("a/b"));
|
||||||
GitWebType gitWebType = GitWebType.fromName(null);
|
|
||||||
|
|
||||||
assertEquals("a/b", gitWebType.replacePathSeparator("a/b"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExclamationMark() {
|
public void testExclamationMark() {
|
||||||
|
GitwebType gitwebType = new GitwebType();
|
||||||
GitWebType gitWebType = GitWebType.fromName(null);
|
gitwebType.setPathSeparator('!');
|
||||||
gitWebType.setPathSeparator('!');
|
assertEquals("a!b", gitwebType.replacePathSeparator("a/b"));
|
||||||
|
|
||||||
assertEquals("a!b", gitWebType.replacePathSeparator("a/b"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ package com.google.gerrit.client.admin;
|
|||||||
|
|
||||||
import com.google.gerrit.client.Dispatcher;
|
import com.google.gerrit.client.Dispatcher;
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.client.ui.Hyperlink;
|
import com.google.gerrit.client.ui.Hyperlink;
|
||||||
import com.google.gerrit.client.ui.ParentProjectBox;
|
import com.google.gerrit.client.ui.ParentProjectBox;
|
||||||
import com.google.gerrit.common.data.AccessSection;
|
import com.google.gerrit.common.data.AccessSection;
|
||||||
@ -121,7 +121,7 @@ public class ProjectAccessEditor extends Composite implements
|
|||||||
inheritsFrom.getStyle().setDisplay(Display.NONE);
|
inheritsFrom.getStyle().setDisplay(Display.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
GitWebInfo c = Gerrit.info().gitWeb();
|
GitwebInfo c = Gerrit.info().gitweb();
|
||||||
if (value.isConfigVisible() && c != null) {
|
if (value.isConfigVisible() && c != null) {
|
||||||
history.getStyle().setDisplay(Display.BLOCK);
|
history.getStyle().setDisplay(Display.BLOCK);
|
||||||
gitweb.setText(c.getLinkName());
|
gitweb.setText(c.getLinkName());
|
||||||
|
@ -26,7 +26,7 @@ import com.google.gerrit.client.access.AccessMap;
|
|||||||
import com.google.gerrit.client.access.ProjectAccessInfo;
|
import com.google.gerrit.client.access.ProjectAccessInfo;
|
||||||
import com.google.gerrit.client.actions.ActionButton;
|
import com.google.gerrit.client.actions.ActionButton;
|
||||||
import com.google.gerrit.client.actions.ActionInfo;
|
import com.google.gerrit.client.actions.ActionInfo;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.client.projects.BranchInfo;
|
import com.google.gerrit.client.projects.BranchInfo;
|
||||||
import com.google.gerrit.client.projects.ProjectApi;
|
import com.google.gerrit.client.projects.ProjectApi;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
@ -457,7 +457,7 @@ public class ProjectBranchesScreen extends ProjectScreen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void populate(int row, BranchInfo k) {
|
void populate(int row, BranchInfo k) {
|
||||||
GitWebInfo c = Gerrit.info().gitWeb();
|
GitwebInfo c = Gerrit.info().gitweb();
|
||||||
|
|
||||||
if (k.canDelete()) {
|
if (k.canDelete()) {
|
||||||
CheckBox sel = new CheckBox();
|
CheckBox sel = new CheckBox();
|
||||||
|
@ -19,7 +19,7 @@ import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
|
|||||||
import com.google.gerrit.client.Dispatcher;
|
import com.google.gerrit.client.Dispatcher;
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.WebLinkInfo;
|
import com.google.gerrit.client.WebLinkInfo;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.client.projects.ProjectInfo;
|
import com.google.gerrit.client.projects.ProjectInfo;
|
||||||
import com.google.gerrit.client.projects.ProjectMap;
|
import com.google.gerrit.client.projects.ProjectMap;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
@ -185,16 +185,16 @@ public class ProjectListScreen extends Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addWebLinks(int row, ProjectInfo k) {
|
private void addWebLinks(int row, ProjectInfo k) {
|
||||||
GitWebInfo gitWebLink = Gerrit.info().gitWeb();
|
GitwebInfo gitwebLink = Gerrit.info().gitweb();
|
||||||
List<WebLinkInfo> webLinks = Natives.asList(k.webLinks());
|
List<WebLinkInfo> webLinks = Natives.asList(k.webLinks());
|
||||||
if (gitWebLink != null || (webLinks != null && !webLinks.isEmpty())) {
|
if (gitwebLink != null || (webLinks != null && !webLinks.isEmpty())) {
|
||||||
FlowPanel p = new FlowPanel();
|
FlowPanel p = new FlowPanel();
|
||||||
table.setWidget(row, ProjectsTable.C_REPO_BROWSER, p);
|
table.setWidget(row, ProjectsTable.C_REPO_BROWSER, p);
|
||||||
|
|
||||||
if (gitWebLink != null) {
|
if (gitwebLink != null) {
|
||||||
Anchor a = new Anchor();
|
Anchor a = new Anchor();
|
||||||
a.setText(gitWebLink.getLinkName());
|
a.setText(gitwebLink.getLinkName());
|
||||||
a.setHref(gitWebLink.toProject(k.name_key()));
|
a.setHref(gitwebLink.toProject(k.name_key()));
|
||||||
p.add(a);
|
p.add(a);
|
||||||
}
|
}
|
||||||
if (webLinks != null) {
|
if (webLinks != null) {
|
||||||
|
@ -23,7 +23,7 @@ import com.google.gerrit.client.changes.ChangeInfo;
|
|||||||
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
||||||
import com.google.gerrit.client.changes.ChangeInfo.GitPerson;
|
import com.google.gerrit.client.changes.ChangeInfo.GitPerson;
|
||||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.client.rpc.Natives;
|
import com.google.gerrit.client.rpc.Natives;
|
||||||
import com.google.gerrit.client.ui.CommentLinkProcessor;
|
import com.google.gerrit.client.ui.CommentLinkProcessor;
|
||||||
import com.google.gerrit.client.ui.InlineHyperlink;
|
import com.google.gerrit.client.ui.InlineHyperlink;
|
||||||
@ -135,7 +135,7 @@ class CommitBox extends Composite {
|
|||||||
|
|
||||||
private void setWebLinks(ChangeInfo change, String revision,
|
private void setWebLinks(ChangeInfo change, String revision,
|
||||||
RevisionInfo revInfo) {
|
RevisionInfo revInfo) {
|
||||||
GitWebInfo gw = Gerrit.info().gitWeb();
|
GitwebInfo gw = Gerrit.info().gitweb();
|
||||||
if (gw != null && gw.canLink(revInfo)) {
|
if (gw != null && gw.canLink(revInfo)) {
|
||||||
toAnchor(gw.toRevision(change.project(), revision),
|
toAnchor(gw.toRevision(change.project(), revision),
|
||||||
gw.getLinkName());
|
gw.getLinkName());
|
||||||
@ -184,7 +184,7 @@ class CommitBox extends Composite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addLinks(String project, CommitInfo c, FlowPanel panel) {
|
private void addLinks(String project, CommitInfo c, FlowPanel panel) {
|
||||||
GitWebInfo gw = Gerrit.info().gitWeb();
|
GitwebInfo gw = Gerrit.info().gitweb();
|
||||||
if (gw != null) {
|
if (gw != null) {
|
||||||
Anchor a =
|
Anchor a =
|
||||||
new Anchor(gw.getLinkName(), gw.toRevision(project, c.commit()));
|
new Anchor(gw.getLinkName(), gw.toRevision(project, c.commit()));
|
||||||
|
@ -18,7 +18,7 @@ import com.google.gerrit.client.Gerrit;
|
|||||||
import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit;
|
import com.google.gerrit.client.change.RelatedChanges.ChangeAndCommit;
|
||||||
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
import com.google.gerrit.client.changes.ChangeInfo.CommitInfo;
|
||||||
import com.google.gerrit.client.changes.Util;
|
import com.google.gerrit.client.changes.Util;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
@ -301,7 +301,7 @@ class RelatedChangesTab implements IsWidget {
|
|||||||
sb.closeSpan();
|
sb.closeSpan();
|
||||||
|
|
||||||
sb.openSpan();
|
sb.openSpan();
|
||||||
GitWebInfo gw = Gerrit.info().gitWeb();
|
GitwebInfo gw = Gerrit.info().gitweb();
|
||||||
if (gw != null && (!info.hasChangeNumber() || !info.hasRevisionNumber())) {
|
if (gw != null && (!info.hasChangeNumber() || !info.hasRevisionNumber())) {
|
||||||
sb.setStyleName(RelatedChanges.R.css().gitweb());
|
sb.setStyleName(RelatedChanges.R.css().gitweb());
|
||||||
sb.setAttribute("title", gw.getLinkName());
|
sb.setAttribute("title", gw.getLinkName());
|
||||||
@ -335,7 +335,7 @@ class RelatedChangesTab implements IsWidget {
|
|||||||
id.getId());
|
id.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
GitWebInfo gw = Gerrit.info().gitWeb();
|
GitwebInfo gw = Gerrit.info().gitweb();
|
||||||
if (gw != null && project != null) {
|
if (gw != null && project != null) {
|
||||||
return gw.toRevision(project, info.commit().commit());
|
return gw.toRevision(project, info.commit().commit());
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ import com.google.gwt.http.client.URL;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class GitWebInfo extends JavaScriptObject {
|
public class GitwebInfo extends JavaScriptObject {
|
||||||
public final native String url() /*-{ return this.url; }-*/;
|
public final native String url() /*-{ return this.url; }-*/;
|
||||||
public final native GitWebTypeInfo type() /*-{ return this.type; }-*/;
|
public final native GitwebTypeInfo type() /*-{ return this.type; }-*/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given patch set can be linked.
|
* Checks whether the given patch set can be linked.
|
||||||
@ -56,20 +56,20 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name for GitWeb links.
|
* Returns the name for gitweb links.
|
||||||
*
|
*
|
||||||
* @return the name for GitWeb links
|
* @return the name for gitweb links
|
||||||
*/
|
*/
|
||||||
public final String getLinkName() {
|
public final String getLinkName() {
|
||||||
return "(" + type().name() + ")";
|
return "(" + type().name() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a revision.
|
* Returns the gitweb link to a revision.
|
||||||
*
|
*
|
||||||
* @param project the name of the project
|
* @param project the name of the project
|
||||||
* @param commit the commit ID
|
* @param commit the commit ID
|
||||||
* @return GitWeb link to a revision
|
* @return gitweb link to a revision
|
||||||
*/
|
*/
|
||||||
public final String toRevision(String project, String commit) {
|
public final String toRevision(String project, String commit) {
|
||||||
ParameterizedString pattern = new ParameterizedString(type().revision());
|
ParameterizedString pattern = new ParameterizedString(type().revision());
|
||||||
@ -80,21 +80,21 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a revision.
|
* Returns the gitweb link to a revision.
|
||||||
*
|
*
|
||||||
* @param project the name of the project
|
* @param project the name of the project
|
||||||
* @param ps the patch set
|
* @param ps the patch set
|
||||||
* @return GitWeb link to a revision
|
* @return gitweb link to a revision
|
||||||
*/
|
*/
|
||||||
public final String toRevision(Project.NameKey project, PatchSet ps) {
|
public final String toRevision(Project.NameKey project, PatchSet ps) {
|
||||||
return toRevision(project.get(), ps.getRevision().get());
|
return toRevision(project.get(), ps.getRevision().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a project.
|
* Returns the gitweb link to a project.
|
||||||
*
|
*
|
||||||
* @param project the project name key
|
* @param project the project name key
|
||||||
* @return GitWeb link to a project
|
* @return gitweb link to a project
|
||||||
*/
|
*/
|
||||||
public final String toProject(Project.NameKey project) {
|
public final String toProject(Project.NameKey project) {
|
||||||
ParameterizedString pattern = new ParameterizedString(type().project());
|
ParameterizedString pattern = new ParameterizedString(type().project());
|
||||||
@ -105,10 +105,10 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a branch.
|
* Returns the gitweb link to a branch.
|
||||||
*
|
*
|
||||||
* @param branch the branch name key
|
* @param branch the branch name key
|
||||||
* @return GitWeb link to a branch
|
* @return gitweb link to a branch
|
||||||
*/
|
*/
|
||||||
public final String toBranch(Branch.NameKey branch) {
|
public final String toBranch(Branch.NameKey branch) {
|
||||||
ParameterizedString pattern = new ParameterizedString(type().branch());
|
ParameterizedString pattern = new ParameterizedString(type().branch());
|
||||||
@ -120,12 +120,12 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a file.
|
* Returns the gitweb link to a file.
|
||||||
*
|
*
|
||||||
* @param project the branch name key
|
* @param project the branch name key
|
||||||
* @param commit the commit ID
|
* @param commit the commit ID
|
||||||
* @param file the path of the file
|
* @param file the path of the file
|
||||||
* @return GitWeb link to a file
|
* @return gitweb link to a file
|
||||||
*/
|
*/
|
||||||
public final String toFile(String project, String commit, String file) {
|
public final String toFile(String project, String commit, String file) {
|
||||||
Map<String, String> p = new HashMap<>();
|
Map<String, String> p = new HashMap<>();
|
||||||
@ -140,11 +140,11 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the GitWeb link to a file history.
|
* Returns the gitweb link to a file history.
|
||||||
*
|
*
|
||||||
* @param branch the branch name key
|
* @param branch the branch name key
|
||||||
* @param file the path of the file
|
* @param file the path of the file
|
||||||
* @return GitWeb link to a file history
|
* @return gitweb link to a file history
|
||||||
*/
|
*/
|
||||||
public final String toFileHistory(Branch.NameKey branch, String file) {
|
public final String toFileHistory(Branch.NameKey branch, String file) {
|
||||||
ParameterizedString pattern = new ParameterizedString(type().fileHistory());
|
ParameterizedString pattern = new ParameterizedString(type().fileHistory());
|
||||||
@ -164,6 +164,6 @@ public class GitWebInfo extends JavaScriptObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GitWebInfo() {
|
protected GitwebInfo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@ package com.google.gerrit.client.config;
|
|||||||
|
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
|
|
||||||
public class GitWebTypeInfo extends JavaScriptObject {
|
public class GitwebTypeInfo extends JavaScriptObject {
|
||||||
/**
|
/**
|
||||||
* Replace the standard path separator ('/') in a branch name or project
|
* Replace the standard path separator ('/') in a branch name or project
|
||||||
* name with a custom path separator configured by the property
|
* name with a custom path separator configured by the property
|
||||||
@ -43,6 +43,6 @@ public class GitWebTypeInfo extends JavaScriptObject {
|
|||||||
public final native boolean linkDrafts() /*-{ return this.link_drafts || false; }-*/;
|
public final native boolean linkDrafts() /*-{ return this.link_drafts || false; }-*/;
|
||||||
public final native boolean urlEncode() /*-{ return this.url_encode || false; }-*/;
|
public final native boolean urlEncode() /*-{ return this.url_encode || false; }-*/;
|
||||||
|
|
||||||
protected GitWebTypeInfo() {
|
protected GitwebTypeInfo() {
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ public class ServerInfo extends JavaScriptObject {
|
|||||||
public final native ContactStoreInfo contactStore() /*-{ return this.contact_store; }-*/;
|
public final native ContactStoreInfo contactStore() /*-{ return this.contact_store; }-*/;
|
||||||
public final native DownloadInfo download() /*-{ return this.download; }-*/;
|
public final native DownloadInfo download() /*-{ return this.download; }-*/;
|
||||||
public final native GerritInfo gerrit() /*-{ return this.gerrit; }-*/;
|
public final native GerritInfo gerrit() /*-{ return this.gerrit; }-*/;
|
||||||
public final native GitWebInfo gitWeb() /*-{ return this.git_web; }-*/;
|
public final native GitwebInfo gitweb() /*-{ return this.gitweb; }-*/;
|
||||||
public final native SshdInfo sshd() /*-{ return this.sshd; }-*/;
|
public final native SshdInfo sshd() /*-{ return this.sshd; }-*/;
|
||||||
public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/;
|
public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/;
|
||||||
public final native UserConfigInfo user() /*-{ return this.user; }-*/;
|
public final native UserConfigInfo user() /*-{ return this.user; }-*/;
|
||||||
|
@ -22,7 +22,7 @@ import com.google.gerrit.client.changes.ChangeInfo;
|
|||||||
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
|
||||||
import com.google.gerrit.client.changes.ReviewInfo;
|
import com.google.gerrit.client.changes.ReviewInfo;
|
||||||
import com.google.gerrit.client.changes.Util;
|
import com.google.gerrit.client.changes.Util;
|
||||||
import com.google.gerrit.client.config.GitWebInfo;
|
import com.google.gerrit.client.config.GitwebInfo;
|
||||||
import com.google.gerrit.client.diff.DiffInfo.Region;
|
import com.google.gerrit.client.diff.DiffInfo.Region;
|
||||||
import com.google.gerrit.client.patches.PatchUtil;
|
import com.google.gerrit.client.patches.PatchUtil;
|
||||||
import com.google.gerrit.client.rpc.CallbackGroup;
|
import com.google.gerrit.client.rpc.CallbackGroup;
|
||||||
@ -115,8 +115,8 @@ public class Header extends Composite {
|
|||||||
return b.append(Util.C.commitMessage());
|
return b.append(Util.C.commitMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
GitWebInfo gw = (project != null && commit != null)
|
GitwebInfo gw = (project != null && commit != null)
|
||||||
? Gerrit.info().gitWeb() : null;
|
? Gerrit.info().gitweb() : null;
|
||||||
int s = path.lastIndexOf('/') + 1;
|
int s = path.lastIndexOf('/') + 1;
|
||||||
if (gw != null && s > 0) {
|
if (gw != null && s > 0) {
|
||||||
String base = path.substring(0, s - 1);
|
String base = path.substring(0, s - 1);
|
||||||
@ -193,7 +193,7 @@ public class Header extends Composite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setChangeInfo(ChangeInfo info) {
|
void setChangeInfo(ChangeInfo info) {
|
||||||
GitWebInfo gw = Gerrit.info().gitWeb();
|
GitwebInfo gw = Gerrit.info().gitweb();
|
||||||
if (gw != null) {
|
if (gw != null) {
|
||||||
for (RevisionInfo rev : Natives.asList(info.revisions().values())) {
|
for (RevisionInfo rev : Natives.asList(info.revisions().values())) {
|
||||||
if (patchSetId.getId().equals(rev.id())) {
|
if (patchSetId.getId().equals(rev.id())) {
|
||||||
|
@ -23,14 +23,14 @@ import com.google.gerrit.httpd.auth.become.BecomeAnyAccountModule;
|
|||||||
import com.google.gerrit.httpd.auth.container.HttpAuthModule;
|
import com.google.gerrit.httpd.auth.container.HttpAuthModule;
|
||||||
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
|
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
|
||||||
import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
|
import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
|
||||||
import com.google.gerrit.httpd.gitweb.GitWebModule;
|
import com.google.gerrit.httpd.gitweb.GitwebModule;
|
||||||
import com.google.gerrit.httpd.rpc.UiRpcModule;
|
import com.google.gerrit.httpd.rpc.UiRpcModule;
|
||||||
import com.google.gerrit.lifecycle.LifecycleModule;
|
import com.google.gerrit.lifecycle.LifecycleModule;
|
||||||
import com.google.gerrit.server.RemotePeer;
|
import com.google.gerrit.server.RemotePeer;
|
||||||
import com.google.gerrit.server.config.AuthConfig;
|
import com.google.gerrit.server.config.AuthConfig;
|
||||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
import com.google.gerrit.server.config.GerritRequestModule;
|
import com.google.gerrit.server.config.GerritRequestModule;
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
import com.google.gerrit.server.config.GitwebCgiConfig;
|
||||||
import com.google.gerrit.server.git.AsyncReceiveCommits;
|
import com.google.gerrit.server.git.AsyncReceiveCommits;
|
||||||
import com.google.gerrit.server.util.GuiceRequestScopePropagator;
|
import com.google.gerrit.server.util.GuiceRequestScopePropagator;
|
||||||
import com.google.gerrit.server.util.RequestScopePropagator;
|
import com.google.gerrit.server.util.RequestScopePropagator;
|
||||||
@ -43,18 +43,18 @@ import java.net.SocketAddress;
|
|||||||
public class WebModule extends LifecycleModule {
|
public class WebModule extends LifecycleModule {
|
||||||
private final AuthConfig authConfig;
|
private final AuthConfig authConfig;
|
||||||
private final boolean wantSSL;
|
private final boolean wantSSL;
|
||||||
private final GitWebConfig gitWebConfig;
|
private final GitwebCgiConfig gitwebCgiConfig;
|
||||||
private final GerritOptions options;
|
private final GerritOptions options;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
WebModule(AuthConfig authConfig,
|
WebModule(AuthConfig authConfig,
|
||||||
@CanonicalWebUrl @Nullable String canonicalUrl,
|
@CanonicalWebUrl @Nullable String canonicalUrl,
|
||||||
GerritOptions options,
|
GerritOptions options,
|
||||||
GitWebConfig gitWebConfig) {
|
GitwebCgiConfig gitwebCgiConfig) {
|
||||||
this.authConfig = authConfig;
|
this.authConfig = authConfig;
|
||||||
this.wantSSL = canonicalUrl != null && canonicalUrl.startsWith("https:");
|
this.wantSSL = canonicalUrl != null && canonicalUrl.startsWith("https:");
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.gitWebConfig = gitWebConfig;
|
this.gitwebCgiConfig = gitwebCgiConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,8 +75,8 @@ public class WebModule extends LifecycleModule {
|
|||||||
install(new GerritRequestModule());
|
install(new GerritRequestModule());
|
||||||
install(new GitOverHttpServlet.Module(options.enableMasterFeatures()));
|
install(new GitOverHttpServlet.Module(options.enableMasterFeatures()));
|
||||||
|
|
||||||
if (gitWebConfig.getGitwebCGI() != null) {
|
if (gitwebCgiConfig.getGitwebCgi() != null) {
|
||||||
install(new GitWebModule());
|
install(new GitwebModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicSet.setOf(binder(), WebUiPlugin.class);
|
DynamicSet.setOf(binder(), WebUiPlugin.class);
|
||||||
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
|||||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||||
|
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
import com.google.gerrit.server.config.GitwebCgiConfig;
|
||||||
import com.google.gwtexpui.server.CacheHeaders;
|
import com.google.gwtexpui.server.CacheHeaders;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
@ -41,9 +41,9 @@ class GitLogoServlet extends HttpServlet {
|
|||||||
private final byte[] raw;
|
private final byte[] raw;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GitLogoServlet(GitWebConfig gitWebConfig) throws IOException {
|
GitLogoServlet(GitwebCgiConfig cfg) throws IOException {
|
||||||
byte[] png;
|
byte[] png;
|
||||||
Path src = gitWebConfig.getGitLogoPNG();
|
Path src = cfg.getGitLogoPng();
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
try (InputStream in = Files.newInputStream(src)) {
|
try (InputStream in = Files.newInputStream(src)) {
|
||||||
png = ByteStreams.toByteArray(in);
|
png = ByteStreams.toByteArray(in);
|
||||||
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
|||||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||||
|
|
||||||
import com.google.gerrit.httpd.HtmlDomUtil;
|
import com.google.gerrit.httpd.HtmlDomUtil;
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
import com.google.gerrit.server.config.GitwebCgiConfig;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
import com.google.gwtexpui.server.CacheHeaders;
|
import com.google.gwtexpui.server.CacheHeaders;
|
||||||
import com.google.gwtjsonrpc.server.RPCServletUtils;
|
import com.google.gwtjsonrpc.server.RPCServletUtils;
|
||||||
@ -34,9 +34,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
abstract class GitWebCssServlet extends HttpServlet {
|
abstract class GitwebCssServlet extends HttpServlet {
|
||||||
@Singleton
|
@Singleton
|
||||||
static class Site extends GitWebCssServlet {
|
static class Site extends GitwebCssServlet {
|
||||||
@Inject
|
@Inject
|
||||||
Site(SitePaths paths) throws IOException {
|
Site(SitePaths paths) throws IOException {
|
||||||
super(paths.site_css);
|
super(paths.site_css);
|
||||||
@ -44,10 +44,10 @@ abstract class GitWebCssServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
static class Default extends GitWebCssServlet {
|
static class Default extends GitwebCssServlet {
|
||||||
@Inject
|
@Inject
|
||||||
Default(GitWebConfig gwc) throws IOException {
|
Default(GitwebCgiConfig gwcc) throws IOException {
|
||||||
super(gwc.getGitwebCSS());
|
super(gwcc.getGitwebCss());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ abstract class GitWebCssServlet extends HttpServlet {
|
|||||||
private final byte[] raw_css;
|
private final byte[] raw_css;
|
||||||
private final byte[] gz_css;
|
private final byte[] gz_css;
|
||||||
|
|
||||||
GitWebCssServlet(final Path src)
|
GitwebCssServlet(final Path src)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
final Path dir = src.getParent();
|
final Path dir = src.getParent();
|
@ -17,7 +17,7 @@ package com.google.gerrit.httpd.gitweb;
|
|||||||
import static com.google.gerrit.common.FileUtil.lastModified;
|
import static com.google.gerrit.common.FileUtil.lastModified;
|
||||||
|
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
import com.google.gerrit.server.config.GitwebCgiConfig;
|
||||||
import com.google.gwtexpui.server.CacheHeaders;
|
import com.google.gwtexpui.server.CacheHeaders;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
@ -36,14 +36,14 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@Singleton
|
@Singleton
|
||||||
class GitWebJavaScriptServlet extends HttpServlet {
|
class GitwebJavaScriptServlet extends HttpServlet {
|
||||||
private final long modified;
|
private final long modified;
|
||||||
private final byte[] raw;
|
private final byte[] raw;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GitWebJavaScriptServlet(final GitWebConfig gitWebConfig) throws IOException {
|
GitwebJavaScriptServlet(GitwebCgiConfig gitwebCgiConfig) throws IOException {
|
||||||
byte[] png;
|
byte[] png;
|
||||||
Path src = gitWebConfig.getGitwebJS();
|
Path src = gitwebCgiConfig.getGitwebJs();
|
||||||
if (src != null) {
|
if (src != null) {
|
||||||
try (InputStream in = Files.newInputStream(src)) {
|
try (InputStream in = Files.newInputStream(src)) {
|
||||||
png = ByteStreams.toByteArray(in);
|
png = ByteStreams.toByteArray(in);
|
@ -16,13 +16,13 @@ package com.google.gerrit.httpd.gitweb;
|
|||||||
|
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
public class GitWebModule extends ServletModule {
|
public class GitwebModule extends ServletModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
serve("/gitweb").with(GitWebServlet.class);
|
serve("/gitweb").with(GitwebServlet.class);
|
||||||
serve("/gitweb-logo.png").with(GitLogoServlet.class);
|
serve("/gitweb-logo.png").with(GitLogoServlet.class);
|
||||||
serve("/gitweb.js").with(GitWebJavaScriptServlet.class);
|
serve("/gitweb.js").with(GitwebJavaScriptServlet.class);
|
||||||
serve("/gitweb-default.css").with(GitWebCssServlet.Default.class);
|
serve("/gitweb-default.css").with(GitwebCssServlet.Default.class);
|
||||||
serve("/gitweb-site.css").with(GitWebCssServlet.Site.class);
|
serve("/gitweb-site.css").with(GitwebCssServlet.Site.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,7 +38,8 @@ import com.google.gerrit.server.AnonymousUser;
|
|||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
import com.google.gerrit.server.config.GitwebCgiConfig;
|
||||||
|
import com.google.gerrit.server.config.GitwebConfig;
|
||||||
import com.google.gerrit.server.config.SitePaths;
|
import com.google.gerrit.server.config.SitePaths;
|
||||||
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
|
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
|
||||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||||
@ -81,9 +82,9 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
/** Invokes {@code gitweb.cgi} for the project given in {@code p}. */
|
/** Invokes {@code gitweb.cgi} for the project given in {@code p}. */
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@Singleton
|
@Singleton
|
||||||
class GitWebServlet extends HttpServlet {
|
class GitwebServlet extends HttpServlet {
|
||||||
private static final Logger log =
|
private static final Logger log =
|
||||||
LoggerFactory.getLogger(GitWebServlet.class);
|
LoggerFactory.getLogger(GitwebServlet.class);
|
||||||
|
|
||||||
private static final String PROJECT_LIST_ACTION = "project_list";
|
private static final String PROJECT_LIST_ACTION = "project_list";
|
||||||
|
|
||||||
@ -98,23 +99,24 @@ class GitWebServlet extends HttpServlet {
|
|||||||
private final EnvList _env;
|
private final EnvList _env;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GitWebServlet(LocalDiskRepositoryManager repoManager,
|
GitwebServlet(LocalDiskRepositoryManager repoManager,
|
||||||
ProjectControl.Factory projectControl,
|
ProjectControl.Factory projectControl,
|
||||||
Provider<AnonymousUser> anonymousUserProvider,
|
Provider<AnonymousUser> anonymousUserProvider,
|
||||||
Provider<CurrentUser> userProvider,
|
Provider<CurrentUser> userProvider,
|
||||||
SitePaths site,
|
SitePaths site,
|
||||||
@GerritServerConfig Config cfg,
|
@GerritServerConfig Config cfg,
|
||||||
SshInfo sshInfo,
|
SshInfo sshInfo,
|
||||||
GitWebConfig gitWebConfig)
|
GitwebConfig gitwebConfig,
|
||||||
|
GitwebCgiConfig gitwebCgiConfig)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.projectControl = projectControl;
|
this.projectControl = projectControl;
|
||||||
this.anonymousUserProvider = anonymousUserProvider;
|
this.anonymousUserProvider = anonymousUserProvider;
|
||||||
this.userProvider = userProvider;
|
this.userProvider = userProvider;
|
||||||
this.gitwebCgi = gitWebConfig.getGitwebCGI();
|
this.gitwebCgi = gitwebCgiConfig.getGitwebCgi();
|
||||||
this.deniedActions = new HashSet<>();
|
this.deniedActions = new HashSet<>();
|
||||||
|
|
||||||
final String url = gitWebConfig.getUrl();
|
final String url = gitwebConfig.getUrl();
|
||||||
if ((url != null) && (!url.equals("gitweb"))) {
|
if ((url != null) && (!url.equals("gitweb"))) {
|
||||||
URI uri = null;
|
URI uri = null;
|
||||||
try {
|
try {
|
||||||
@ -267,7 +269,7 @@ class GitWebServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Link back to Gerrit (when possible, to matching review record).
|
// Link back to Gerrit (when possible, to matching review record).
|
||||||
// Supported Gitweb's hash values are:
|
// Supported gitweb's hash values are:
|
||||||
// - (missing),
|
// - (missing),
|
||||||
// - HEAD,
|
// - HEAD,
|
||||||
// - refs/heads/<branch>,
|
// - refs/heads/<branch>,
|
||||||
@ -577,7 +579,7 @@ class GitWebServlet extends HttpServlet {
|
|||||||
env.set("REMOTE_USER", remoteUser);
|
env.set("REMOTE_USER", remoteUser);
|
||||||
|
|
||||||
// Override CGI settings using alternative URI provided by gitweb.url.
|
// Override CGI settings using alternative URI provided by gitweb.url.
|
||||||
// This is required to trick Gitweb into thinking that it's served under
|
// This is required to trick gitweb into thinking that it's served under
|
||||||
// different URL. Setting just $my_uri on the perl's side isn't enough,
|
// different URL. Setting just $my_uri on the perl's side isn't enough,
|
||||||
// because few actions (atom, blobdiff_plain, commitdiff_plain) rely on
|
// because few actions (atom, blobdiff_plain, commitdiff_plain) rely on
|
||||||
// URL returned by $cgi->self_url().
|
// URL returned by $cgi->self_url().
|
||||||
@ -642,7 +644,7 @@ class GitWebServlet extends HttpServlet {
|
|||||||
log.debug("Unexpected error copying input to CGI", e);
|
log.debug("Unexpected error copying input to CGI", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "GitWeb-InputFeeder").start();
|
}, "Gitweb-InputFeeder").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyStderrToLog(final InputStream in) {
|
private void copyStderrToLog(final InputStream in) {
|
||||||
@ -664,7 +666,7 @@ class GitWebServlet extends HttpServlet {
|
|||||||
log.debug("Unexpected error copying stderr from CGI", e);
|
log.debug("Unexpected error copying stderr from CGI", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "GitWeb-ErrorLogger").start();
|
}, "Gitweb-ErrorLogger").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) {
|
private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) {
|
@ -216,7 +216,7 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
bind(ToolsCatalog.class);
|
bind(ToolsCatalog.class);
|
||||||
bind(EventFactory.class);
|
bind(EventFactory.class);
|
||||||
bind(TransferConfig.class);
|
bind(TransferConfig.class);
|
||||||
bind(GitWebConfig.class);
|
bind(GitwebConfig.class);
|
||||||
|
|
||||||
bind(GcConfig.class);
|
bind(GcConfig.class);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import com.google.common.base.Function;
|
|||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gerrit.common.data.GitWebType;
|
import com.google.gerrit.common.data.GitwebType;
|
||||||
import com.google.gerrit.extensions.config.CloneCommand;
|
import com.google.gerrit.extensions.config.CloneCommand;
|
||||||
import com.google.gerrit.extensions.config.DownloadCommand;
|
import com.google.gerrit.extensions.config.DownloadCommand;
|
||||||
import com.google.gerrit.extensions.config.DownloadScheme;
|
import com.google.gerrit.extensions.config.DownloadScheme;
|
||||||
@ -51,7 +51,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
private final AllProjectsName allProjectsName;
|
private final AllProjectsName allProjectsName;
|
||||||
private final AllUsersName allUsersName;
|
private final AllUsersName allUsersName;
|
||||||
private final String anonymousCowardName;
|
private final String anonymousCowardName;
|
||||||
private final GitWebConfig gitWebConfig;
|
private final GitwebConfig gitwebConfig;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GetServerInfo(
|
public GetServerInfo(
|
||||||
@ -65,7 +65,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
AllProjectsName allProjectsName,
|
AllProjectsName allProjectsName,
|
||||||
AllUsersName allUsersName,
|
AllUsersName allUsersName,
|
||||||
@AnonymousCowardName String anonymousCowardName,
|
@AnonymousCowardName String anonymousCowardName,
|
||||||
GitWebConfig gitWebConfig) {
|
GitwebConfig gitwebConfig) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.authConfig = authConfig;
|
this.authConfig = authConfig;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
@ -76,7 +76,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
this.allProjectsName = allProjectsName;
|
this.allProjectsName = allProjectsName;
|
||||||
this.allUsersName = allUsersName;
|
this.allUsersName = allUsersName;
|
||||||
this.anonymousCowardName = anonymousCowardName;
|
this.anonymousCowardName = anonymousCowardName;
|
||||||
this.gitWebConfig = gitWebConfig;
|
this.gitwebConfig = gitwebConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,7 +89,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
getDownloadInfo(downloadSchemes, downloadCommands, cloneCommands,
|
getDownloadInfo(downloadSchemes, downloadCommands, cloneCommands,
|
||||||
archiveFormats);
|
archiveFormats);
|
||||||
info.gerrit = getGerritInfo(config, allProjectsName, allUsersName);
|
info.gerrit = getGerritInfo(config, allProjectsName, allUsersName);
|
||||||
info.gitWeb = getGitWebInfo(gitWebConfig);
|
info.gitweb = getGitwebInfo(gitwebConfig);
|
||||||
info.sshd = getSshdInfo(config);
|
info.sshd = getSshdInfo(config);
|
||||||
info.suggest = getSuggestInfo(config);
|
info.suggest = getSuggestInfo(config);
|
||||||
info.user = getUserInfo(anonymousCowardName);
|
info.user = getUserInfo(anonymousCowardName);
|
||||||
@ -227,14 +227,14 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GitWebInfo getGitWebInfo(GitWebConfig cfg) {
|
private GitwebInfo getGitwebInfo(GitwebConfig cfg) {
|
||||||
if (cfg.getUrl() == null || cfg.getGitWebType() == null) {
|
if (cfg.getUrl() == null || cfg.getGitwebType() == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GitWebInfo info = new GitWebInfo();
|
GitwebInfo info = new GitwebInfo();
|
||||||
info.url = cfg.getUrl();
|
info.url = cfg.getUrl();
|
||||||
info.type = cfg.getGitWebType();
|
info.type = cfg.getGitwebType();
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
public ContactStoreInfo contactStore;
|
public ContactStoreInfo contactStore;
|
||||||
public DownloadInfo download;
|
public DownloadInfo download;
|
||||||
public GerritInfo gerrit;
|
public GerritInfo gerrit;
|
||||||
public GitWebInfo gitWeb;
|
public GitwebInfo gitweb;
|
||||||
public SshdInfo sshd;
|
public SshdInfo sshd;
|
||||||
public SuggestInfo suggest;
|
public SuggestInfo suggest;
|
||||||
public UserConfigInfo user;
|
public UserConfigInfo user;
|
||||||
@ -326,9 +326,9 @@ public class GetServerInfo implements RestReadView<ConfigResource> {
|
|||||||
public String reportBugText;
|
public String reportBugText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GitWebInfo {
|
public static class GitwebInfo {
|
||||||
public String url;
|
public String url;
|
||||||
public GitWebType type;
|
public GitwebType type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SshdInfo {
|
public static class SshdInfo {
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
// Copyright (C) 2009 The Android Open Source Project
|
|
||||||
//
|
|
||||||
// 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.google.gerrit.server.config;
|
|
||||||
|
|
||||||
import static java.nio.file.Files.isExecutable;
|
|
||||||
import static java.nio.file.Files.isRegularFile;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.data.GitWebType;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.Config;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
public class GitWebConfig {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(GitWebConfig.class);
|
|
||||||
|
|
||||||
private final String url;
|
|
||||||
private final Path gitweb_cgi;
|
|
||||||
private final Path gitweb_css;
|
|
||||||
private final Path gitweb_js;
|
|
||||||
private final Path git_logo_png;
|
|
||||||
private GitWebType type;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
GitWebConfig(final SitePaths sitePaths, @GerritServerConfig final Config cfg) {
|
|
||||||
final String cfgUrl = cfg.getString("gitweb", null, "url");
|
|
||||||
final String cfgCgi = cfg.getString("gitweb", null, "cgi");
|
|
||||||
|
|
||||||
type = GitWebType.fromName(cfg.getString("gitweb", null, "type"));
|
|
||||||
if (type == null) {
|
|
||||||
url = null;
|
|
||||||
gitweb_cgi = null;
|
|
||||||
gitweb_css = null;
|
|
||||||
gitweb_js = null;
|
|
||||||
git_logo_png = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
type.setLinkName(cfg.getString("gitweb", null, "linkname"));
|
|
||||||
type.setBranch(cfg.getString("gitweb", null, "branch"));
|
|
||||||
type.setProject(cfg.getString("gitweb", null, "project"));
|
|
||||||
type.setRevision(cfg.getString("gitweb", null, "revision"));
|
|
||||||
type.setRootTree(cfg.getString("gitweb", null, "roottree"));
|
|
||||||
type.setFile(cfg.getString("gitweb", null, "file"));
|
|
||||||
type.setFileHistory(cfg.getString("gitweb", null, "filehistory"));
|
|
||||||
type.setLinkDrafts(cfg.getBoolean("gitweb", null, "linkdrafts", true));
|
|
||||||
type.setUrlEncode(cfg.getBoolean("gitweb", null, "urlencode", true));
|
|
||||||
String pathSeparator = cfg.getString("gitweb", null, "pathSeparator");
|
|
||||||
if (pathSeparator != null) {
|
|
||||||
if (pathSeparator.length() == 1) {
|
|
||||||
char c = pathSeparator.charAt(0);
|
|
||||||
if (isValidPathSeparator(c)) {
|
|
||||||
type.setPathSeparator(c);
|
|
||||||
} else {
|
|
||||||
log.warn("Invalid value specified for gitweb.pathSeparator: " + c);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("Value specified for gitweb.pathSeparator is not a single character:" + pathSeparator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.getBranch() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.branch, disabling.");
|
|
||||||
type = null;
|
|
||||||
} else if (type.getProject() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.project, disabling.");
|
|
||||||
type = null;
|
|
||||||
} else if (type.getRevision() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.revision, disabling.");
|
|
||||||
type = null;
|
|
||||||
} else if (type.getRootTree() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.roottree, disabling.");
|
|
||||||
type = null;
|
|
||||||
} else if (type.getFile() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.file, disabling.");
|
|
||||||
type = null;
|
|
||||||
} else if (type.getFileHistory() == null) {
|
|
||||||
log.warn("No Pattern specified for gitweb.filehistory, disabling.");
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cfgUrl != null && cfgUrl.isEmpty())
|
|
||||||
|| (cfgCgi != null && cfgCgi.isEmpty())) {
|
|
||||||
// Either setting was explicitly set to the empty string disabling
|
|
||||||
// gitweb for this server. Disable the configuration.
|
|
||||||
//
|
|
||||||
url = null;
|
|
||||||
gitweb_cgi = null;
|
|
||||||
gitweb_css = null;
|
|
||||||
gitweb_js = null;
|
|
||||||
git_logo_png = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cfgUrl != null) && (cfgCgi == null || cfgCgi.isEmpty())) {
|
|
||||||
// Use an externally managed gitweb instance, and not an internal one.
|
|
||||||
//
|
|
||||||
url = cfgUrl;
|
|
||||||
gitweb_cgi = null;
|
|
||||||
gitweb_css = null;
|
|
||||||
gitweb_js = null;
|
|
||||||
git_logo_png = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
|
|
||||||
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
|
|
||||||
"/var/www/static", "/var/www"};
|
|
||||||
Path cgi;
|
|
||||||
|
|
||||||
if (cfgCgi != null) {
|
|
||||||
// Use the CGI script configured by the administrator, failing if it
|
|
||||||
// cannot be used as specified.
|
|
||||||
//
|
|
||||||
cgi = sitePaths.resolve(cfgCgi);
|
|
||||||
if (!isRegularFile(cgi)) {
|
|
||||||
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
|
|
||||||
}
|
|
||||||
if (!isExecutable(cgi)) {
|
|
||||||
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cgi.equals(pkgCgi)) {
|
|
||||||
// Assume the administrator pointed us to the distribution,
|
|
||||||
// which also has the corresponding CSS and logo file.
|
|
||||||
//
|
|
||||||
String absPath = cgi.getParent().toAbsolutePath().toString();
|
|
||||||
resourcePaths = new String[] {absPath + "/static", absPath};
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
|
|
||||||
// Use the OS packaged CGI.
|
|
||||||
//
|
|
||||||
log.debug("Assuming gitweb at " + pkgCgi);
|
|
||||||
cgi = pkgCgi;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
log.warn("gitweb not installed (no " + pkgCgi + " found)");
|
|
||||||
cgi = null;
|
|
||||||
resourcePaths = new String[] {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Path css = null;
|
|
||||||
Path js = null;
|
|
||||||
Path logo = null;
|
|
||||||
for (String path : resourcePaths) {
|
|
||||||
Path dir = Paths.get(path);
|
|
||||||
css = dir.resolve("gitweb.css");
|
|
||||||
js = dir.resolve("gitweb.js");
|
|
||||||
logo = dir.resolve("git-logo.png");
|
|
||||||
if (isRegularFile(css) && isRegularFile(logo)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfgUrl == null || cfgUrl.isEmpty()) {
|
|
||||||
url = cgi != null ? "gitweb" : null;
|
|
||||||
} else {
|
|
||||||
url = cgi != null ? cfgUrl : null;
|
|
||||||
}
|
|
||||||
gitweb_cgi = cgi;
|
|
||||||
gitweb_css = css;
|
|
||||||
gitweb_js = js;
|
|
||||||
git_logo_png = logo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return GitWebType for gitweb viewer. */
|
|
||||||
public GitWebType getGitWebType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return URL of the entry point into gitweb. This URL may be relative to our
|
|
||||||
* context if gitweb is hosted by ourselves; or absolute if its hosted
|
|
||||||
* elsewhere; or null if gitweb has not been configured.
|
|
||||||
*/
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return local path to the CGI executable; null if we shouldn't execute. */
|
|
||||||
public Path getGitwebCGI() {
|
|
||||||
return gitweb_cgi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return local path of the {@code gitweb.css} matching the CGI. */
|
|
||||||
public Path getGitwebCSS() {
|
|
||||||
return gitweb_css;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return local path of the {@code gitweb.js} for the CGI. */
|
|
||||||
public Path getGitwebJS() {
|
|
||||||
return gitweb_js;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return local path of the {@code git-logo.png} for the CGI. */
|
|
||||||
public Path getGitLogoPNG() {
|
|
||||||
return git_logo_png;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a given character can be used unencoded in an URL as a
|
|
||||||
* replacement for the path separator '/'.
|
|
||||||
*
|
|
||||||
* Reasoning: http://www.ietf.org/rfc/rfc1738.txt § 2.2:
|
|
||||||
*
|
|
||||||
* ... only alphanumerics, the special characters "$-_.+!*'(),", and
|
|
||||||
* reserved characters used for their reserved purposes may be used
|
|
||||||
* unencoded within a URL.
|
|
||||||
*
|
|
||||||
* The following characters might occur in file names, however:
|
|
||||||
*
|
|
||||||
* alphanumeric characters,
|
|
||||||
*
|
|
||||||
* "$-_.+!',"
|
|
||||||
*/
|
|
||||||
static boolean isValidPathSeparator(char c) {
|
|
||||||
switch (c) {
|
|
||||||
case '*':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,137 @@
|
|||||||
|
// Copyright (C) 2015 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// 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.google.gerrit.server.config;
|
||||||
|
|
||||||
|
import static java.nio.file.Files.isExecutable;
|
||||||
|
import static java.nio.file.Files.isRegularFile;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class GitwebCgiConfig {
|
||||||
|
private static final Logger log =
|
||||||
|
LoggerFactory.getLogger(GitwebCgiConfig.class);
|
||||||
|
|
||||||
|
public GitwebCgiConfig disabled() {
|
||||||
|
return new GitwebCgiConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Path cgi;
|
||||||
|
private final Path css;
|
||||||
|
private final Path js;
|
||||||
|
private final Path logoPng;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GitwebCgiConfig(SitePaths sitePaths, @GerritServerConfig Config cfg) {
|
||||||
|
if (GitwebConfig.isDisabled(cfg)) {
|
||||||
|
cgi = null;
|
||||||
|
css = null;
|
||||||
|
js = null;
|
||||||
|
logoPng = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cfgCgi = cfg.getString("gitweb", null, "cgi");
|
||||||
|
Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
|
||||||
|
String[] resourcePaths = {"/usr/share/gitweb/static", "/usr/share/gitweb",
|
||||||
|
"/var/www/static", "/var/www"};
|
||||||
|
Path cgi;
|
||||||
|
|
||||||
|
if (cfgCgi != null) {
|
||||||
|
// Use the CGI script configured by the administrator, failing if it
|
||||||
|
// cannot be used as specified.
|
||||||
|
//
|
||||||
|
cgi = sitePaths.resolve(cfgCgi);
|
||||||
|
if (!isRegularFile(cgi)) {
|
||||||
|
throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
|
||||||
|
}
|
||||||
|
if (!isExecutable(cgi)) {
|
||||||
|
throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cgi.equals(pkgCgi)) {
|
||||||
|
// Assume the administrator pointed us to the distribution,
|
||||||
|
// which also has the corresponding CSS and logo file.
|
||||||
|
//
|
||||||
|
String absPath = cgi.getParent().toAbsolutePath().toString();
|
||||||
|
resourcePaths = new String[] {absPath + "/static", absPath};
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
|
||||||
|
// Use the OS packaged CGI.
|
||||||
|
//
|
||||||
|
log.debug("Assuming gitweb at " + pkgCgi);
|
||||||
|
cgi = pkgCgi;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("gitweb not installed (no " + pkgCgi + " found)");
|
||||||
|
cgi = null;
|
||||||
|
resourcePaths = new String[] {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Path css = null;
|
||||||
|
Path js = null;
|
||||||
|
Path logo = null;
|
||||||
|
for (String path : resourcePaths) {
|
||||||
|
Path dir = Paths.get(path);
|
||||||
|
css = dir.resolve("gitweb.css");
|
||||||
|
js = dir.resolve("gitweb.js");
|
||||||
|
logo = dir.resolve("git-logo.png");
|
||||||
|
if (isRegularFile(css) && isRegularFile(logo)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cgi = cgi;
|
||||||
|
this.css = css;
|
||||||
|
this.js = js;
|
||||||
|
this.logoPng = logo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GitwebCgiConfig() {
|
||||||
|
this.cgi = null;
|
||||||
|
this.css = null;
|
||||||
|
this.js = null;
|
||||||
|
this.logoPng = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return local path to the CGI executable; null if we shouldn't execute. */
|
||||||
|
public Path getGitwebCgi() {
|
||||||
|
return cgi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return local path of the {@code gitweb.css} matching the CGI. */
|
||||||
|
public Path getGitwebCss() {
|
||||||
|
return css;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return local path of the {@code gitweb.js} for the CGI. */
|
||||||
|
public Path getGitwebJs() {
|
||||||
|
return js;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return local path of the {@code git-logo.png} for the CGI. */
|
||||||
|
public Path getGitLogoPng() {
|
||||||
|
return logoPng;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,229 @@
|
|||||||
|
// Copyright (C) 2009 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// 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.google.gerrit.server.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||||
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||||
|
import static com.google.common.base.Strings.nullToEmpty;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.gerrit.common.data.GitwebType;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class GitwebConfig {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GitwebConfig.class);
|
||||||
|
|
||||||
|
public static boolean isDisabled(Config cfg) {
|
||||||
|
return isEmptyString(cfg, "gitweb", null, "url")
|
||||||
|
|| isEmptyString(cfg, "gitweb", null, "cgi");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEmptyString(Config cfg, String section,
|
||||||
|
String subsection, String name) {
|
||||||
|
// This is currently the only way to check for the empty string in a JGit
|
||||||
|
// config. Fun!
|
||||||
|
String[] values = cfg.getStringList(section, subsection, name);
|
||||||
|
return values.length > 0 && Strings.isNullOrEmpty(values[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a GitwebType based on the given config.
|
||||||
|
*
|
||||||
|
* @param cfg Gerrit config.
|
||||||
|
* @return GitwebType from the given name, else null if not found.
|
||||||
|
*/
|
||||||
|
public static GitwebType typeFromConfig(Config cfg) {
|
||||||
|
GitwebType defaultType = defaultType(cfg.getString("gitweb", null, "type"));
|
||||||
|
if (defaultType == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
GitwebType type = new GitwebType();
|
||||||
|
|
||||||
|
type.setLinkName(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "linkname"),
|
||||||
|
defaultType.getLinkName()));
|
||||||
|
type.setBranch(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "branch"),
|
||||||
|
defaultType.getBranch()));
|
||||||
|
type.setProject(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "project"),
|
||||||
|
defaultType.getProject()));
|
||||||
|
type.setRevision(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "revision"),
|
||||||
|
defaultType.getRevision()));
|
||||||
|
type.setRootTree(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "roottree"),
|
||||||
|
defaultType.getRootTree()));
|
||||||
|
type.setFile(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "file"),
|
||||||
|
defaultType.getFile()));
|
||||||
|
type.setFileHistory(firstNonNull(
|
||||||
|
cfg.getString("gitweb", null, "filehistory"),
|
||||||
|
defaultType.getFileHistory()));
|
||||||
|
type.setLinkDrafts(
|
||||||
|
cfg.getBoolean("gitweb", null, "linkdrafts",
|
||||||
|
defaultType.getLinkDrafts()));
|
||||||
|
type.setUrlEncode(
|
||||||
|
cfg.getBoolean("gitweb", null, "urlencode",
|
||||||
|
defaultType.getUrlEncode()));
|
||||||
|
String pathSeparator = cfg.getString("gitweb", null, "pathSeparator");
|
||||||
|
if (pathSeparator != null) {
|
||||||
|
if (pathSeparator.length() == 1) {
|
||||||
|
char c = pathSeparator.charAt(0);
|
||||||
|
if (isValidPathSeparator(c)) {
|
||||||
|
type.setPathSeparator(
|
||||||
|
firstNonNull(c, defaultType.getPathSeparator()));
|
||||||
|
} else {
|
||||||
|
log.warn("Invalid gitweb.pathSeparator: " + c);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn(
|
||||||
|
"gitweb.pathSeparator is not a single character: " + pathSeparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GitwebType defaultType(String typeName) {
|
||||||
|
GitwebType type = new GitwebType();
|
||||||
|
switch (nullToEmpty(typeName)) {
|
||||||
|
case "":
|
||||||
|
case "gitweb":
|
||||||
|
type.setLinkName("gitweb");
|
||||||
|
type.setProject("?p=${project}.git;a=summary");
|
||||||
|
type.setRevision("?p=${project}.git;a=commit;h=${commit}");
|
||||||
|
type.setBranch("?p=${project}.git;a=shortlog;h=${branch}");
|
||||||
|
type.setRootTree("?p=${project}.git;a=tree;hb=${commit}");
|
||||||
|
type.setFile("?p=${project}.git;hb=${commit};f=${file}");
|
||||||
|
type.setFileHistory(
|
||||||
|
"?p=${project}.git;a=history;hb=${branch};f=${file}");
|
||||||
|
break;
|
||||||
|
case "cgit":
|
||||||
|
type.setLinkName("cgit");
|
||||||
|
type.setProject("${project}.git/summary");
|
||||||
|
type.setRevision("${project}.git/commit/?id=${commit}");
|
||||||
|
type.setBranch("${project}.git/log/?h=${branch}");
|
||||||
|
type.setRootTree("${project}.git/tree/?h=${commit}");
|
||||||
|
type.setFile("${project}.git/tree/${file}?h=${commit}");
|
||||||
|
type.setFileHistory("${project}.git/log/${file}?h=${branch}");
|
||||||
|
break;
|
||||||
|
case "custom":
|
||||||
|
// For a custom type with no explicit link name, just reuse "gitweb".
|
||||||
|
type.setLinkName("gitweb");
|
||||||
|
type.setProject("");
|
||||||
|
type.setRevision("");
|
||||||
|
type.setBranch("");
|
||||||
|
type.setRootTree("");
|
||||||
|
type.setFile("");
|
||||||
|
type.setFileHistory("");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String url;
|
||||||
|
private final GitwebType type;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
GitwebConfig(GitwebCgiConfig cgiConfig, @GerritServerConfig Config cfg) {
|
||||||
|
if (isDisabled(cfg)) {
|
||||||
|
type = null;
|
||||||
|
url = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String cfgUrl = cfg.getString("gitweb", null, "url");
|
||||||
|
GitwebType type = typeFromConfig(cfg);
|
||||||
|
if (type == null) {
|
||||||
|
this.type = null;
|
||||||
|
url = null;
|
||||||
|
return;
|
||||||
|
} else if (cgiConfig.getGitwebCgi() == null) {
|
||||||
|
// Use an externally managed gitweb instance, and not an internal one.
|
||||||
|
url = cfgUrl;
|
||||||
|
} else {
|
||||||
|
url = firstNonNull(cfgUrl, "gitweb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNullOrEmpty(type.getBranch())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.branch, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else if (isNullOrEmpty(type.getProject())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.project, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else if (isNullOrEmpty(type.getRevision())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.revision, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else if (isNullOrEmpty(type.getRootTree())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.roottree, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else if (isNullOrEmpty(type.getFile())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.file, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else if (isNullOrEmpty(type.getFileHistory())) {
|
||||||
|
log.warn("No Pattern specified for gitweb.filehistory, disabling.");
|
||||||
|
this.type = null;
|
||||||
|
} else {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return GitwebType for gitweb viewer. */
|
||||||
|
public GitwebType getGitwebType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return URL of the entry point into gitweb. This URL may be relative to our
|
||||||
|
* context if gitweb is hosted by ourselves; or absolute if its hosted
|
||||||
|
* elsewhere; or null if gitweb has not been configured.
|
||||||
|
*/
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a given character can be used unencoded in an URL as a
|
||||||
|
* replacement for the path separator '/'.
|
||||||
|
*
|
||||||
|
* Reasoning: http://www.ietf.org/rfc/rfc1738.txt § 2.2:
|
||||||
|
*
|
||||||
|
* ... only alphanumerics, the special characters "$-_.+!*'(),", and
|
||||||
|
* reserved characters used for their reserved purposes may be used
|
||||||
|
* unencoded within a URL.
|
||||||
|
*
|
||||||
|
* The following characters might occur in file names, however:
|
||||||
|
*
|
||||||
|
* alphanumeric characters,
|
||||||
|
*
|
||||||
|
* "$-_.+!',"
|
||||||
|
*/
|
||||||
|
static boolean isValidPathSeparator(char c) {
|
||||||
|
switch (c) {
|
||||||
|
case '*':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,14 +14,12 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.config;
|
package com.google.gerrit.server.config;
|
||||||
|
|
||||||
import com.google.gerrit.server.config.GitWebConfig;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class GitWebConfigTest {
|
public class GitwebConfigTest {
|
||||||
|
|
||||||
private static final String VALID_CHARACTERS = "*()";
|
private static final String VALID_CHARACTERS = "*()";
|
||||||
private static final String SOME_INVALID_CHARACTERS = "09AZaz$-_.+!',";
|
private static final String SOME_INVALID_CHARACTERS = "09AZaz$-_.+!',";
|
||||||
@ -29,14 +27,14 @@ public class GitWebConfigTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testValidPathSeparator() {
|
public void testValidPathSeparator() {
|
||||||
for(char c : VALID_CHARACTERS.toCharArray()) {
|
for(char c : VALID_CHARACTERS.toCharArray()) {
|
||||||
assertTrue("valid character rejected: " + c, GitWebConfig.isValidPathSeparator(c));
|
assertTrue("valid character rejected: " + c, GitwebConfig.isValidPathSeparator(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInalidPathSeparator() {
|
public void testInalidPathSeparator() {
|
||||||
for(char c : SOME_INVALID_CHARACTERS.toCharArray()) {
|
for(char c : SOME_INVALID_CHARACTERS.toCharArray()) {
|
||||||
assertFalse("invalid character accepted: " + c, GitWebConfig.isValidPathSeparator(c));
|
assertFalse("invalid character accepted: " + c, GitwebConfig.isValidPathSeparator(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user