Merge "Add SSH to configure logging level at runtime"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index ed44db8..7ebbbbe 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1750,6 +1750,24 @@
This property is honored only if the password does not
appear in the http.proxy property above.
+[[http.addUserAsRequestAttribute]]http.addUserAsRequestAttribute::
++
+If true, 'User' attribute will be added to the request attributes so it
+can be accessed outside the request scope (will be set to username or id
+if username not configured).
++
+This attribute can be used by the servlet container to log user in the
+http access log.
++
+When running the embedded servlet container, this attribute is used to
+print user in the httpd_log.
++
+* `%{User}r`
++
+Pattern to print user in Tomcat AccessLog.
+
++
+Default value is true.
[[httpd]]
=== Section httpd
diff --git a/Documentation/dev-buck.txt b/Documentation/dev-buck.txt
index 8121a63..0bf44d0 100644
--- a/Documentation/dev-buck.txt
+++ b/Documentation/dev-buck.txt
@@ -467,6 +467,15 @@
To use `buckd` the additional
link:https://facebook.github.io/watchman[watchman] program must be installed.
+To disable `buckd`, the environment variable `NO_BUCKD` must be set. It's not
+recommended to put it in the shell config, as it can be forgotten about it and
+then assumed Buck was working as it should when it should be using buckd.
+Prepend the variable to Buck invocation instead:
+
+----
+ $ NO_BUCKD=1 buck build gerrit
+----
+
[[watchman]]
=== Installing watchman
diff --git a/Documentation/dev-eclipse.txt b/Documentation/dev-eclipse.txt
index 3063882..adc62b2 100644
--- a/Documentation/dev-eclipse.txt
+++ b/Documentation/dev-eclipse.txt
@@ -49,7 +49,7 @@
=== Running GWT Debug Mode
-The gerrit_gwt_debug launch configuration uses GWT's
+The gerrit_gwt_debug launch configuration uses GWT's
link:http://www.gwtproject.org/articles/superdevmode.html[Super Dev Mode].
Due to a problem where the codeserver does not correctly identify the connected
@@ -58,7 +58,7 @@
[source,xml]
----
- <set-property name="user.agent" value="geko1_8" />
+ <set-property name="user.agent" value="gecko1_8" />
----
or
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 71fc175..997f481 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -295,9 +295,9 @@
authenticated and has commented on the current revision.
--
-[[patch-set-links]]
+[[web-links]]
--
-* `PATCHSET_LINKS`: include the `web_links` field.
+* `WEB_LINKS`: include the `web_links` field.
--
.Request
diff --git a/bucklets/gerrit_plugin.bucklet b/bucklets/gerrit_plugin.bucklet
index eb10456..f3e9830 100644
--- a/bucklets/gerrit_plugin.bucklet
+++ b/bucklets/gerrit_plugin.bucklet
@@ -13,3 +13,6 @@
#
# When compiling from standalone cookbook-plugin, bucklets directory points
# to cloned bucklets library that includes real gerrit_plugin.bucklet code.
+
+GERRIT_PLUGIN_API = ['//gerrit-plugin-api:lib']
+GERRIT_GWT_API = ['//gerrit-plugin-gwtui/gerrit:gwtui-api']
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 5b3795e..2134fda 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -24,17 +24,25 @@
import com.google.gerrit.extensions.common.LabelInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.testutil.ConfigSuite;
import com.google.gwtorm.server.OrmException;
import com.jcraft.jsch.JSchException;
import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public abstract class AbstractPushForReview extends AbstractDaemonTest {
+ @ConfigSuite.Config
+ public static Config noteDbEnabled() {
+ return NotesMigration.allEnabledConfig();
+ }
+
protected enum Protocol {
SSH, HTTP
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/actions/ActionButton.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/actions/ActionButton.java
index 6aaac8c..2e2d314 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/actions/ActionButton.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/actions/ActionButton.java
@@ -68,6 +68,7 @@
.openDiv()
.append(action.label())
.closeDiv());
+ setStyleName("");
setTitle(action.title());
setEnabled(action.enabled());
addClickHandler(this);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
index f3e99b5..a0b1fc73 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
@@ -584,6 +584,7 @@
private Button createChangeAction() {
final Button createChange = new Button(Util.C.buttonCreateChange());
+ createChange.setStyleName("");
createChange.setTitle(Util.C.buttonCreateChangeDescription());
createChange.addClickHandler(new ClickHandler() {
@Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Hashtags.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Hashtags.java
index 0cc3ced..bc84984 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Hashtags.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Hashtags.java
@@ -162,9 +162,10 @@
.setAttribute(DATA_ID, hashtagName)
.setStyleName(style.hashtagName())
.openAnchor()
- .setAttribute("href", "#" + PageLinks.toChangeQuery("hashtag:" + hashtagName))
+ .setAttribute("href",
+ "#" + PageLinks.toChangeQuery("hashtag:\"" + hashtagName + "\""))
.setAttribute("role", "listitem")
- .append(hashtagName)
+ .append("#").append(hashtagName)
.closeAnchor()
.openElement("button")
.setAttribute("title", "Remove hashtag")
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/GetUserFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GetUserFilter.java
similarity index 72%
rename from gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/GetUserFilter.java
rename to gerrit-httpd/src/main/java/com/google/gerrit/httpd/GetUserFilter.java
index 4f35f1c..94b8f29 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/GetUserFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GetUserFilter.java
@@ -12,9 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.pgm.http.jetty;
+package com.google.gerrit.httpd;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -24,7 +25,6 @@
import org.eclipse.jgit.lib.Config;
import java.io.IOException;
-import java.net.URI;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -34,28 +34,26 @@
import javax.servlet.ServletResponse;
/**
- * Stores as a request attribute, so the {@link HttpLog} can include the the
- * user for the request outside of the request scope.
+ * Stores user as a request attribute, so servlets can access it outside of the
+ * request scope.
*/
@Singleton
public class GetUserFilter implements Filter {
- static final String REQ_ATTR_KEY = CurrentUser.class.toString();
+ public static final String REQ_ATTR_KEY = "User";
public static class Module extends ServletModule {
- private boolean loggingEnabled;
+ private final boolean enabled;
@Inject
Module(@GerritServerConfig final Config cfg) {
- URI[] urls = JettyServer.listenURLs(cfg);
- boolean reverseProxy = JettyServer.isReverseProxied(urls);
- this.loggingEnabled = cfg.getBoolean("httpd", "requestLog", !reverseProxy);
+ enabled = cfg.getBoolean("http", "addUserAsRequestAttribute", true);
}
@Override
protected void configureServlets() {
- if (loggingEnabled) {
+ if (enabled) {
filter("/*").through(GetUserFilter.class);
}
}
@@ -72,7 +70,15 @@
public void doFilter(
ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
- req.setAttribute(REQ_ATTR_KEY, userProvider.get());
+ CurrentUser user = userProvider.get();
+ if (user != null && user.isIdentifiedUser()) {
+ IdentifiedUser who = (IdentifiedUser) user;
+ if (who.getUserName() != null && !who.getUserName().isEmpty()) {
+ req.setAttribute(REQ_ATTR_KEY, who.getUserName());
+ } else {
+ req.setAttribute(REQ_ATTR_KEY, "a/" + who.getAccountId());
+ }
+ }
chain.doFilter(req, resp);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index 75f2e96..cc00294 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -21,6 +21,7 @@
import com.google.gerrit.common.ChangeHookRunner;
import com.google.gerrit.httpd.AllRequestFilter;
import com.google.gerrit.httpd.GerritOptions;
+import com.google.gerrit.httpd.GetUserFilter;
import com.google.gerrit.httpd.GitOverHttpModule;
import com.google.gerrit.httpd.H2CacheBasedWebSession;
import com.google.gerrit.httpd.HttpCanonicalWebUrlProvider;
@@ -31,7 +32,6 @@
import com.google.gerrit.httpd.plugins.HttpPluginModule;
import com.google.gerrit.lifecycle.LifecycleManager;
import com.google.gerrit.lucene.LuceneIndexModule;
-import com.google.gerrit.pgm.http.jetty.GetUserFilter;
import com.google.gerrit.pgm.http.jetty.JettyEnv;
import com.google.gerrit.pgm.http.jetty.JettyModule;
import com.google.gerrit.pgm.http.jetty.ProjectQoSFilter;
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/HttpLog.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/HttpLog.java
index ba97d4a..f84abce 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/HttpLog.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/HttpLog.java
@@ -14,8 +14,7 @@
package com.google.gerrit.pgm.http.jetty;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.httpd.GetUserFilter;
import com.google.gerrit.server.util.SystemLog;
import com.google.gerrit.server.util.TimeUtil;
import com.google.inject.Inject;
@@ -66,11 +65,6 @@
@Override
public void log(final Request req, final Response rsp) {
- CurrentUser user = (CurrentUser) req.getAttribute(GetUserFilter.REQ_ATTR_KEY);
- doLog(req, rsp, user);
- }
-
- private void doLog(Request req, Response rsp, CurrentUser user) {
final LoggingEvent event = new LoggingEvent( //
Logger.class.getName(), // fqnOfCategoryClass
log, // logger
@@ -90,13 +84,9 @@
uri = uri + "?" + qs;
}
- if (user != null && user.isIdentifiedUser()) {
- IdentifiedUser who = (IdentifiedUser) user;
- if (who.getUserName() != null && !who.getUserName().isEmpty()) {
- event.setProperty(P_USER, who.getUserName());
- } else {
- event.setProperty(P_USER, "a/" + who.getAccountId());
- }
+ String user = (String) req.getAttribute(GetUserFilter.REQ_ATTR_KEY);
+ if (user != null) {
+ event.setProperty(P_USER, user);
}
set(event, P_HOST, req.getRemoteAddr());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/WebLinks.java b/gerrit-server/src/main/java/com/google/gerrit/server/WebLinks.java
index 629e75b..ae61fcf 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/WebLinks.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/WebLinks.java
@@ -52,7 +52,7 @@
return links;
}
- public Iterable<WebLinkInfo> getPatchLinks(String project, String revision,
+ public Iterable<WebLinkInfo> getFileLinks(String project, String revision,
String file) {
List<WebLinkInfo> links = Lists.newArrayList();
for (FileWebLink webLink : fileLinks) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index c20cc71..0c72d35 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -59,7 +59,7 @@
private final Restore restore;
private final GetTopic getTopic;
private final PutTopic putTopic;
- private final Provider<PostReviewers> postReviewers;
+ private final PostReviewers postReviewers;
private final Provider<ChangeJson> changeJson;
private final PostHashtags postHashtags;
@@ -72,7 +72,7 @@
Restore restore,
GetTopic getTopic,
PutTopic putTopic,
- Provider<PostReviewers> postReviewers,
+ PostReviewers postReviewers,
Provider<ChangeJson> changeJson,
PostHashtags postHashtags,
@Assisted ChangeResource change) {
@@ -183,7 +183,7 @@
@Override
public void addReviewer(AddReviewerInput in) throws RestApiException {
try {
- postReviewers.get().apply(change, in);
+ postReviewers.apply(change, in);
} catch (OrmException | EmailException | IOException e) {
throw new RestApiException("Cannot add change reviewer", e);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/EmailReviewComments.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/EmailReviewComments.java
index bc38039..6330e34 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/EmailReviewComments.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/EmailReviewComments.java
@@ -32,6 +32,7 @@
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
+import com.google.inject.OutOfScopeException;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.assistedinject.Assisted;
@@ -152,7 +153,7 @@
@Override
public CurrentUser getCurrentUser() {
- return null;
+ throw new OutOfScopeException("No user on email thread");
}
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
index f18481e..d3232cb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
@@ -206,7 +206,7 @@
private List<WebLinkInfo> getFileWebLinks(Project project, String rev,
String file) {
List<WebLinkInfo> fileWebLinks = new ArrayList<>();
- for (WebLinkInfo link : webLinks.get().getPatchLinks(project.getName(),
+ for (WebLinkInfo link : webLinks.get().getFileLinks(project.getName(),
rev, file)) {
if (!Strings.isNullOrEmpty(link.name) && !Strings.isNullOrEmpty(link.url)) {
fileWebLinks.add(link);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditUtil.java
index d74a314f..3767b32 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditUtil.java
@@ -27,6 +27,7 @@
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -63,14 +64,14 @@
private final PatchSetInserter.Factory patchSetInserterFactory;
private final ChangeControl.GenericFactory changeControlFactory;
private final Provider<ReviewDb> db;
- private final Provider<IdentifiedUser> user;
+ private final Provider<CurrentUser> user;
@Inject
ChangeEditUtil(GitRepositoryManager gitManager,
PatchSetInserter.Factory patchSetInserterFactory,
ChangeControl.GenericFactory changeControlFactory,
Provider<ReviewDb> db,
- Provider<IdentifiedUser> user) {
+ Provider<CurrentUser> user) {
this.gitManager = gitManager;
this.patchSetInserterFactory = patchSetInserterFactory;
this.changeControlFactory = changeControlFactory;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
index 2bfdaa7..9013ad9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java
@@ -2045,6 +2045,7 @@
recipients.remove(me);
ChangeUpdate update = updateFactory.create(changeCtl, newPatchSet.getCreatedOn());
+ update.setPatchSetId(newPatchSet.getId());
db.changes().beginTransaction(change.getId());
try {
change = db.changes().get(change.getId());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/MostSpecificComparator.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/MostSpecificComparator.java
index 804a7ec..1cb180b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/util/MostSpecificComparator.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/MostSpecificComparator.java
@@ -28,7 +28,7 @@
* name and the regex string shortest example. A shorter distance is a more
* specific match.
* <li>2 - Finites first, infinities after.
- * <li>3 - Number of transitions.
+ * <li>3 - Number of transitions. More transitions is more specific.
* <li>4 - Length of the expression text.
* </ul>
*
@@ -72,7 +72,7 @@
}
}
if (cmp == 0) {
- cmp = transitions(pattern1) - transitions(pattern2);
+ cmp = transitions(pattern2) - transitions(pattern1);
}
if (cmp == 0) {
cmp = pattern2.length() - pattern1.length();
@@ -86,7 +86,7 @@
example = RefControl.shortestExample(pattern);
} else if (pattern.endsWith("/*")) {
- example = pattern.substring(0, pattern.length() - 1) + '1';
+ example = pattern;
} else if (pattern.equals(refName)) {
return 0;
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/util/MostSpecificComparatorTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/util/MostSpecificComparatorTest.java
new file mode 100644
index 0000000..e974f1f
--- /dev/null
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/util/MostSpecificComparatorTest.java
@@ -0,0 +1,80 @@
+// Copyright (C) 2014 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.util;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class MostSpecificComparatorTest {
+
+ private MostSpecificComparator cmp;
+
+ @Test
+ public void shorterDistanceWins() {
+ cmp = new MostSpecificComparator("refs/heads/master");
+ moreSpecificFirst("refs/heads/master", "refs/heads/master2");
+ moreSpecificFirst("refs/heads/master", "refs/heads/maste");
+ moreSpecificFirst("refs/heads/master", "refs/heads/*");
+ moreSpecificFirst("refs/heads/master", "^refs/heads/.*");
+ moreSpecificFirst("refs/heads/master", "^refs/heads/master.*");
+ }
+
+ /**
+ * Assuming two patterns have the same Levenshtein distance,
+ * the pattern which represents a finite language wins over a pattern
+ * which represents an infinite language.
+ */
+ @Test
+ public void finiteWinsOverInfinite() {
+ cmp = new MostSpecificComparator("refs/heads/master");
+ moreSpecificFirst("^refs/heads/......", "refs/heads/*");
+ moreSpecificFirst("^refs/heads/maste.", "^refs/heads/maste.*");
+ }
+
+ /**
+ * Assuming two patterns have the same Levenshtein distance
+ * and are both either finite or infinite the one with the higher
+ * number of state transitions (in an equivalent automaton) wins
+ */
+ @Test
+ public void higherNumberOfTransitionsWins() {
+ cmp = new MostSpecificComparator("refs/heads/x");
+ moreSpecificFirst("^refs/heads/[a-z].*", "refs/heads/*");
+ // Previously there was a bug where having a '1' in a refname would cause a
+ // glob pattern's Levenshtein distance to decrease by 1. These two
+ // patterns should be a Levenshtein distance of 12 from the both of the
+ // refnames, where previously the 'branch1' refname would be a distance of
+ // 11 from 'refs/heads/abc/*'
+ cmp = new MostSpecificComparator("refs/heads/abc/spam/branch2");
+ moreSpecificFirst("^refs/heads/.*spam.*", "refs/heads/abc/*");
+ cmp = new MostSpecificComparator("refs/heads/abc/spam/branch1");
+ moreSpecificFirst("^refs/heads/.*spam.*", "refs/heads/abc/*");
+ }
+
+ /**
+ * Assuming the same Levenshtein distance, (in)finity and the number
+ * of transitions, the longer pattern wins
+ */
+ @Test
+ public void longerPatternWins() {
+ cmp = new MostSpecificComparator("refs/heads/x");
+ moreSpecificFirst("^refs/heads/[a-z].*", "^refs/heads/..*");
+ }
+
+ private void moreSpecificFirst(String first, String second) {
+ assertTrue(cmp.compare(first, second) < 0);
+ }
+}
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
index 99db2db..fbe2743 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
@@ -344,6 +344,7 @@
if (authConfig.getAuthType() == AuthType.OPENID) {
modules.add(new OpenIdModule());
}
+ modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
return sysInjector.createChildInjector(modules);
}
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index 133e8b4..294aad2 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -37,15 +37,17 @@
opts = OptionParser()
opts.add_option('--src', action='store_true')
+opts.add_option('--plugins', help='create eclipse projects for plugins',
+ action='store_true')
args, _ = opts.parse_args()
-def gen_project():
- p = path.join(ROOT, '.project')
+def gen_project(name='gerrit', dir=ROOT):
+ p = path.join(dir, '.project')
with open(p, 'w') as fd:
print("""\
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>gerrit</name>
+ <name>""" + name + """</name>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
@@ -57,6 +59,18 @@
</projectDescription>\
""", file=fd)
+def gen_plugin_classpath(dir):
+ p = path.join(dir, '.classpath')
+ with open(p, 'w') as fd:
+ print("""\
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/gerrit"/>
+ <classpathentry kind="output" path="buck-out/eclipse/classes"/>
+</classpath>""", file=fd)
+
def gen_classpath():
def query_classpath(targets):
deps = []
@@ -72,7 +86,7 @@
impl = minidom.getDOMImplementation()
return impl.createDocument(None, 'classpath', None)
- def classpathentry(kind, path, src=None, out=None):
+ def classpathentry(kind, path, src=None, out=None, exported=None):
e = doc.createElement('classpathentry')
e.setAttribute('kind', kind)
e.setAttribute('path', path)
@@ -80,6 +94,8 @@
e.setAttribute('sourcepath', src)
if out:
e.setAttribute('output', out)
+ if exported:
+ e.setAttribute('exported', 'true')
doc.documentElement.appendChild(e)
doc = make_classpath()
@@ -87,6 +103,7 @@
lib = set()
gwt_src = set()
gwt_lib = set()
+ plugins = set()
java_library = re.compile(r'[^/]+/gen/(.*)/lib__[^/]+__output/[^/]+[.]jar$')
for p in query_classpath(MAIN):
@@ -119,6 +136,9 @@
if s.startswith('lib/'):
out = 'buck-out/eclipse/lib'
elif s.startswith('plugins/'):
+ if args.plugins:
+ plugins.add(s)
+ continue
out = 'buck-out/eclipse/' + s
p = path.join(s, 'java')
@@ -145,8 +165,10 @@
s = j[:-4] + '-src.jar'
if not path.exists(s):
s = None
- classpathentry('lib', j, s)
-
+ if args.plugins:
+ classpathentry('lib', j, s, exported=True)
+ else:
+ classpathentry('lib', j, s)
for s in sorted(gwt_src):
p = path.join(ROOT, s, 'src', 'main', 'java')
classpathentry('lib', p, out='buck-out/eclipse/gwtsrc')
@@ -158,6 +180,15 @@
with open(p, 'w') as fd:
doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
+ if args.plugins:
+ for plugin in plugins:
+ plugindir = path.join(ROOT, plugin)
+ try:
+ gen_project(plugin.replace('plugins/', ""), plugindir)
+ gen_plugin_classpath(plugindir)
+ except (IOError, OSError) as err:
+ print('error generating project for %s: %s' % (plugin, err), file=sys.stderr)
+
try:
if args.src:
try: