Merge "Add ssh command create-branch for creating branches"
diff --git a/.buckconfig b/.buckconfig
index 1bc29ac..4eb5e85 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -5,6 +5,7 @@
docs = //Documentation:html
gerrit = //:gerrit
release = //:release
+ withdocs = //:withdocs
[buildfile]
includes = //tools/default.defs
@@ -14,3 +15,7 @@
[project]
ignore = .git
+
+[cache]
+ mode = dir
+ dir = buck-out/cache
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 631fe48..e07f9cb 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -21,8 +21,9 @@
directory = /var/cache/gerrit2
----
-[[accounts]]Section accounts
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[accounts]]
+Section accounts
+~~~~~~~~~~~~~~~~
[[accounts.visibility]]accounts.visibility::
+
@@ -42,8 +43,9 @@
+
Default is `ALL`.
-[[addreviewer]]Section addreviewer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[addreviewer]]
+Section addreviewer
+~~~~~~~~~~~~~~~~~~~
[[addreviewer.maxWithoutConfirmation]]addreviewer.maxWithoutConfirmation::
+
@@ -69,8 +71,9 @@
+
Default is 20.
-[[auth]]Section auth
-~~~~~~~~~~~~~~~~~~~~
+[[auth]]
+Section auth
+~~~~~~~~~~~~
See also link:config-sso.html[SSO configuration].
@@ -464,8 +467,9 @@
+
Default is true.
-[[cache]]Section cache
-~~~~~~~~~~~~~~~~~~~~~~
+[[cache]]
+Section cache
+~~~~~~~~~~~~~
[[cache.directory]]cache.directory::
+
@@ -767,8 +771,9 @@
+
Default is 5 minutes.
-[[change]]Section change
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[change]]
+Section change
+~~~~~~~~~~~~~~
[[change.largeChange]]change.largeChange::
+
@@ -800,8 +805,9 @@
+
Default is 30 seconds.
-[[changeMerge]]Section changeMerge
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[changeMerge]]
+Section changeMerge
+~~~~~~~~~~~~~~~~~~~
[[changeMerge.checkFrequency]]changeMerge.checkFrequency::
+
@@ -820,8 +826,10 @@
+
Default is 1.
-[[commentlink]]Section commentlink
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[commentlink]]
+Section commentlink
+~~~~~~~~~~~~~~~~~~~
+
Comment links are find/replace strings applied to change descriptions,
patch comments, in-line code comments and approval category value descriptions
to turn set strings into hyperlinks. One common use is for linking to
@@ -900,13 +908,16 @@
user-supplied and thus can be verified to be XSS-free, but are only
enabled for a subset of projects.
+
+By default, true.
++
Note that the names and contents of disabled sections are visible even
to anonymous users via the
link:rest-api-projects.html#get-config[REST API].
-[[contactstore]]Section contactstore
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[contactstore]]
+Section contactstore
+~~~~~~~~~~~~~~~~~~~~
[[contactstore.url]]contactstore.url::
+
@@ -921,8 +932,9 @@
Shared secret of the web based contact store.
-[[container]]Section container
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[container]]
+Section container
+~~~~~~~~~~~~~~~~~
These settings are applied only if Gerrit is started as the container
process through Gerrit's 'gerrit.sh' rc.d compatible wrapper script.
@@ -977,8 +989,9 @@
'$HOME/gerrit.war'.
-[[core]]Section core
-~~~~~~~~~~~~~~~~~~~~
+[[core]]
+Section core
+~~~~~~~~~~~~
[[core.packedGitWindowSize]]core.packedGitWindowSize::
+
@@ -1084,8 +1097,9 @@
+
Default is false, but in a future release may default to true.
-[[database]]Section database
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[database]]
+Section database
+~~~~~~~~~~~~~~~~
The database section configures where Gerrit stores its metadata
records about user accounts and change reviews.
@@ -1222,8 +1236,9 @@
This setting only applies if
<<database.connectionPool,database.connectionPool>> is true.
-[[download]]Section download
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[download]]
+Section download
+~~~~~~~~~~~~~~~~
----
[download]
@@ -1303,8 +1318,9 @@
If `download.scheme` is not specified, SSH, HTTP and Anonymous HTTP
downloads are allowed.
-[[gerrit]]Section gerrit
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[gerrit]]
+Section gerrit
+~~~~~~~~~~~~~~
[[gerrit.basePath]]gerrit.basePath::
+
@@ -1389,8 +1405,9 @@
Default change screen UI to direct users to. Valid values are
`OLD_UI` and `CHANGE_SCREEN2`. Default is `CHANGE_SCREEN2`.
-[[gitweb]]Section gitweb
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[gitweb]]
+Section gitweb
+~~~~~~~~~~~~~~
Gerrit can forward requests to either an internally managed gitweb
(which allows Gerrit to enforce some access controls), or to an
@@ -1502,8 +1519,9 @@
+
Valid values are "true" and "false," default is "true".
-[[groups]]Section groups
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[groups]]
+Section groups
+~~~~~~~~~~~~~~
[[groups.newGroupsVisibleToAll]]groups.newGroupsVisibleToAll::
+
@@ -1512,8 +1530,9 @@
+
By default, false.
-[[hooks]]Section hooks
-~~~~~~~~~~~~~~~~~~~~~~
+[[hooks]]
+Section hooks
+~~~~~~~~~~~~~
See also link:config-hooks.html[Hooks].
@@ -1586,8 +1605,9 @@
Optional timeout value in seconds for synchronous hooks, if not specified
then 30 seconds will be used.
-[[http]]Section http
-~~~~~~~~~~~~~~~~~~~~
+[[http]]
+Section http
+~~~~~~~~~~~~
[[http.proxy]]http.proxy::
+
@@ -1608,8 +1628,9 @@
appear in the http.proxy property above.
-[[httpd]]Section httpd
-~~~~~~~~~~~~~~~~~~~~~~
+[[httpd]]
+Section httpd
+~~~~~~~~~~~~~
The httpd section configures the embedded servlet container.
@@ -1841,8 +1862,9 @@
If the file doesn't exist or can't be read the default robots.txt file
bundled with the .war will be used instead.
-[[index]]Section index
-~~~~~~~~~~~~~~~~~~~~~~
+[[index]]
+Section index
+~~~~~~~~~~~~~
The index section configures the secondary index.
@@ -1866,8 +1888,9 @@
using the link:pgm-reindex.html[reindex program] before restarting the
Gerrit server.
-[[ldap]]Section ldap
-~~~~~~~~~~~~~~~~~~~~
+[[ldap]]
+Section ldap
+~~~~~~~~~~~~
LDAP integration is only enabled if `auth.type` is set to
`HTTP_LDAP`, `LDAP` or `CLIENT_SSL_CERT_LDAP`. See above for a
@@ -2153,8 +2176,9 @@
must have the DWORD value `allowtgtsessionkey` set to 1 and the account must not
have local administrator privileges.
-[[mimetype]]Section mimetype
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[mimetype]]
+Section mimetype
+~~~~~~~~~~~~~~~~
[[mimetype.name.safe]]mimetype.<name>.safe::
+
@@ -2182,8 +2206,10 @@
----
-[[pack]]Section pack
-~~~~~~~~~~~~~~~~~~~~
+[[pack]]
+Section pack
+~~~~~~~~~~~~
+
Global settings controlling how Gerrit Code Review creates pack
streams for Git clients running clone, fetch, or pull. Most of these
variables are per-client request, and thus should be carefully set
@@ -2207,8 +2233,9 @@
By default, 1.
-[[plugins]]Section plugins
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[plugins]]
+Section plugins
+~~~~~~~~~~~~~~~
[[plugins.checkFrequency]]plugins.checkFrequency::
+
@@ -2223,8 +2250,10 @@
Default is 1 minute.
-[[receive]]Section receive
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[receive]]
+Section receive
+~~~~~~~~~~~~~~~
+
This section is used to set who can execute the 'receive-pack' and
to limit the maximum Git object size that 'receive-pack' will accept.
'receive-pack' is what runs on the server during a user's push or
@@ -2324,8 +2353,10 @@
is assumed.
-[[repository]]Section repository
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[repository]]
+Section repository
+~~~~~~~~~~~~~~~~~~
+
Repositories in this sense are the same as projects.
In the following example configuration `Registered Users` is set
@@ -2354,8 +2385,9 @@
groups are allowed. Each on its own line. Groups which don't exist
in the database are ignored.
-[[rules]]Section rules
-~~~~~~~~~~~~~~~~~~~~~~
+[[rules]]
+Section rules
+~~~~~~~~~~~~~
[[rules.enable]]rules.enable::
+
@@ -2365,8 +2397,9 @@
+
Default is true, to execute project specific rules.
-[[sendemail]]Section sendemail
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[sendemail]]
+Section sendemail
+~~~~~~~~~~~~~~~~~
[[sendemail.enable]]sendemail.enable::
+
@@ -2494,8 +2527,9 @@
By default, unset, so no Expiry-Date header is generated.
-[[site]]Section site
-~~~~~~~~~~~~~~~~~~~~
+[[site]]
+Section site
+~~~~~~~~~~~~
[[site.checkUserAgent]]site.checkUserAgent::
+
@@ -2517,8 +2551,9 @@
and text results for changes. If false, the URL is disabled and
returns 404 to clients. Default is true, enabling `/query`.
-[[ssh-alias]] Section ssh-alias
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[ssh-alias]]
+Section ssh-alias
+~~~~~~~~~~~~~~~~~
Variables in section ssh-alias permit the site administrator to alias
another command from Gerrit or a plugin into the `gerrit` command
@@ -2529,8 +2564,9 @@
replicate = replication start
----
-[[sshd]] Section sshd
-~~~~~~~~~~~~~~~~~~~~~
+[[sshd]]
+Section sshd
+~~~~~~~~~~~~
[[sshd.backend]]sshd.backend::
+
@@ -2741,8 +2777,9 @@
+
By default, true.
-[[suggest]] Section suggest
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[suggest]]
+Section suggest
+~~~~~~~~~~~~~~~
[[suggest.accounts]]suggest.accounts::
+
@@ -2768,8 +2805,9 @@
+
By default 0.
-[[theme]] Section theme
-~~~~~~~~~~~~~~~~~~~~~~~
+[[theme]]
+Section theme
+~~~~~~~~~~~~~
[[theme.backgroundColor]]theme.backgroundColor::
+
@@ -2866,8 +2904,9 @@
backgroundColor = FFFFFF
----
-[[trackingid]] Section trackingid
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[trackingid]]
+Section trackingid
+~~~~~~~~~~~~~~~~~~
Tagged footer lines containing references to external
tracking systems, parsed out of the commit message and
@@ -2919,8 +2958,9 @@
It is possible to have several trackingid entries for the same
tracking system.
-[[transfer]] Section transfer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[transfer]]
+Section transfer
+~~~~~~~~~~~~~~~~
[[transfer.timeout]]transfer.timeout::
+
@@ -2937,8 +2977,10 @@
Defaults to 0 seconds, wait indefinitely.
-[[upload]]Section upload
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[upload]]
+Section upload
+~~~~~~~~~~~~~~
+
Sets the group of users allowed to execute 'upload-pack' on the
server, 'upload-pack' is what runs on the server during a user's
fetch, clone or repo sync command.
@@ -2958,8 +3000,9 @@
'upload-pack' on the server.
-[[user]] Section user
-~~~~~~~~~~~~~~~~~~~~~
+[[user]]
+Section user
+~~~~~~~~~~~~
[[user.name]]user.name::
+
diff --git a/Documentation/config-gitweb.txt b/Documentation/config-gitweb.txt
index 3e9cb96..80f577d 100644
--- a/Documentation/config-gitweb.txt
+++ b/Documentation/config-gitweb.txt
@@ -62,6 +62,12 @@
Access controls for internally managed gitweb page views are enforced
using the standard project READ +1 permission.
+Also, in order for a user to be able to view any gitweb information for a
+project, the user must be able to read all referencess (including
+refs/meta/config, refs/meta/dashboards/*, etc.). If you have exclusive read
+permissions for any references, make sure to include all parties that should be
+able to read the gitweb info for any of the branches in that project.
+
External/Unmanaged gitweb
~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/dev-buck.txt b/Documentation/dev-buck.txt
index 1acff3b..7b4981a 100644
--- a/Documentation/dev-buck.txt
+++ b/Documentation/dev-buck.txt
@@ -7,7 +7,7 @@
There is currently no binary distribution of Buck, so it has to be manually
built and installed. Apache Ant is required. Currently only Linux and Mac
-OS are supported.
+OS are supported. Gerrit's buck wrappers require Python version 2.6 or higher.
Clone the git and build it:
@@ -130,7 +130,7 @@
----
Java binaries, Java sources and Java docs are generated into corresponding
-project directories in buck-out/gen, here as example for plugin API:
+project directories in `buck-out/gen`, here as example for plugin API:
----
buck-out/gen/gerrit-plugin-api/plugin-api.jar
@@ -144,7 +144,7 @@
buck build api_install
----
-Deploy {extension,plugin,gwt}-api to the remote maven repository
+Deploy {extension,plugin,gwt}-api to the remote maven repository:
----
buck build api_deploy
@@ -154,6 +154,11 @@
* 2.9-SNAPSHOT: snapshot repo
* 2.9: release repo
+Deploying to the remote repository still depends on Maven, and the credentials
+for the repository need to be
+link:dev-release-deploy-config.html#deploy-configuration-settings-xml[
+configured in Maven's settings.xml file].
+
Plugins
~~~~~~~
@@ -211,7 +216,7 @@
Documentation
~~~~~~~~~~~~~
-To build the documentation:
+To build only the documentation:
----
buck build docs
@@ -229,6 +234,18 @@
buck-out/gen/Documentation/html.zip
----
+To build the executable WAR with the documentation included:
+
+----
+ buck build withdocs
+----
+
+The WAR file will be placed in:
+
+----
+ buck-out/gen/withdocs.war
+----
+
[[release]]
Gerrit Release WAR File
~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index df14c1d..b39adf7 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -1353,10 +1353,13 @@
</manifestEntries>
----
-It is important that the module name that is provided to the
-`GwtPlugin` matches the GWT module contained in the plugin. The name
-of the GWT module can be explicitly set in the GWT module file by
-specifying the `rename-to` attribute on the module.
+The name that is provided to the `GwtPlugin` must match the GWT
+module name compiled into the plugin. The name of the GWT module
+can be explicitly set in the GWT module XML file by specifying
+the `rename-to` attribute on the module. It is important that the
+module name be unique across all plugins installed on the server,
+as the module name determines the JavaScript namespace used by the
+compiled plugin code.
[source,xml]
----
@@ -1364,14 +1367,14 @@
----
The actual GWT code must be implemented in a class that extends
-`com.google.gerrit.plugin.client.Plugin`:
+`com.google.gerrit.plugin.client.PluginEntryPoint`:
[source,java]
----
-public class HelloPlugin extends Plugin {
+public class HelloPlugin extends PluginEntryPoint {
@Override
- public void onModuleLoad() {
+ public void onPluginLoad() {
// Create the dialog box
final DialogBox dialogBox = new DialogBox();
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index e73e039..10455c0 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -28,6 +28,23 @@
link:dev-buck.html#build[Building on the command line with Buck].
+Switching between branches
+--------------------------
+
+When switching between branches with `git checkout`, be aware that
+submodule revisions are not altered. This may result in the wrong
+plugin revisions being present, unneeded plugins being present, or
+expected plugins being missing.
+
+After switching branches, make sure the submodules are at the correct
+revisions for the new branch with the commands:
+
+----
+ git submodule update
+ git clean -fdx
+----
+
+
Configuring Eclipse
-------------------
diff --git a/Documentation/pgm-init.txt b/Documentation/pgm-init.txt
index 07ca154..99520ac 100644
--- a/Documentation/pgm-init.txt
+++ b/Documentation/pgm-init.txt
@@ -51,7 +51,7 @@
--list-plugins::
Print names of plugins that can be installed during init process.
---install-plugin:
+--install-plugin::
Automatically install plugin with given name without asking.
This option may be supplied more than once to install multiple
plugins.
diff --git a/Documentation/rest-api-documentation.txt b/Documentation/rest-api-documentation.txt
index 0defe6d..56e6c92 100644
--- a/Documentation/rest-api-documentation.txt
+++ b/Documentation/rest-api-documentation.txt
@@ -7,9 +7,9 @@
Please note that this feature is only usable with documentation built-in.
You'll need to
-`buck build :withdocs`
+`buck build withdocs`
or
-`buck build :release`
+`buck build release`
to test this feature.
[[documentation-endpoints]]
diff --git a/ReleaseNotes/ReleaseNotes-2.9.txt b/ReleaseNotes/ReleaseNotes-2.9.txt
index 174cdef..c0e2fcb 100644
--- a/ReleaseNotes/ReleaseNotes-2.9.txt
+++ b/ReleaseNotes/ReleaseNotes-2.9.txt
@@ -83,3 +83,10 @@
* The number of accounts shown on the 'Become Any Account' login
screen is increased from 5 to 100.
+
+
+Upgrades
+--------
+
+* Update gwtjsonrpc to 1.4
+* Update gwtorm to 1.8
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index 68d04cb..0643d7a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -16,7 +16,6 @@
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectInfo;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectOwners;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -30,6 +29,7 @@
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
import com.google.gerrit.server.account.GroupCache;
@@ -180,7 +180,7 @@
ProjectInput in = new ProjectInput();
in.permissions_only = true;
session.put("/projects/" + newProjectName, in);
- assertHead(newProjectName, GitRepositoryManager.REF_CONFIG);
+ assertHead(newProjectName, RefNames.REFS_CONFIG);
}
@Test
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
index 9fd7568..a93a23a 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ProjectLevelConfigIT.java
@@ -27,9 +27,9 @@
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.git.PushOneCommit;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.AllProjectsNameProvider;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.server.SchemaFactory;
@@ -73,7 +73,7 @@
project = "p";
createProject(sshSession, project, null, true);
git = cloneProject(sshSession.getUrl() + "/" + project);
- fetch(git, GitRepositoryManager.REF_CONFIG + ":refs/heads/config");
+ fetch(git, RefNames.REFS_CONFIG + ":refs/heads/config");
checkout(git, "refs/heads/config");
db = reviewDbProvider.open();
@@ -93,7 +93,7 @@
PushOneCommit push =
new PushOneCommit(db, admin.getIdent(), "Create Project Level Config",
configName, cfg.toText());
- push.to(git, GitRepositoryManager.REF_CONFIG);
+ push.to(git, RefNames.REFS_CONFIG);
ProjectState state = projectCache.get(new Project.NameKey(project));
assertEquals(cfg.toText(), state.getConfig(configName).get().toText());
@@ -117,19 +117,19 @@
Git parentGit =
cloneProject(sshSession.getUrl() + "/" + allProjects.get().get(), false);
- fetch(parentGit, GitRepositoryManager.REF_CONFIG + ":refs/heads/config");
+ fetch(parentGit, RefNames.REFS_CONFIG + ":refs/heads/config");
checkout(parentGit, "refs/heads/config");
PushOneCommit push =
new PushOneCommit(db, admin.getIdent(), "Create Project Level Config",
configName, parentCfg.toText());
- push.to(parentGit, GitRepositoryManager.REF_CONFIG);
+ push.to(parentGit, RefNames.REFS_CONFIG);
Config cfg = new Config();
cfg.setString("s1", null, "k1", "childValue1");
cfg.setString("s2", "ss", "k3", "childValue2");
push = new PushOneCommit(db, admin.getIdent(), "Create Project Level Config",
configName, cfg.toText());
- push.to(git, GitRepositoryManager.REF_CONFIG);
+ push.to(git, RefNames.REFS_CONFIG);
ProjectState state = projectCache.get(new Project.NameKey(project));
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/BUCK b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/BUCK
new file mode 100644
index 0000000..0157bd6
--- /dev/null
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/BUCK
@@ -0,0 +1,21 @@
+include_defs('//gerrit-acceptance-tests/tests.defs')
+
+acceptance_tests(
+ srcs = glob(['*IT.java']),
+ deps = [
+ ':util',
+ '//gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git:util',
+ '//lib:gwtjsonrpc',
+ ],
+)
+
+java_library(
+ name = 'util',
+ srcs = [
+ 'ChangeAndCommit.java',
+ 'RelatedInfo.java',
+ ],
+ deps = [
+ '//gerrit-server:server',
+ ],
+)
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ChangeAndCommit.java
similarity index 69%
copy from gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java
copy to gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ChangeAndCommit.java
index 64f832b..d9959b2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/ChangeAndCommit.java
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.client.api;
+package com.google.gerrit.acceptance.server.change;
-import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gerrit.server.change.ChangeJson.CommitInfo;
-class JsUiPlugin extends JavaScriptObject {
- final native String name() /*-{ return this.name }-*/;
-
- protected JsUiPlugin() {
- }
+public class ChangeAndCommit {
+ public String changeId;
+ public CommitInfo commit;
+ public Integer _changeNumber;
+ public Integer _revisionNumber;
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
new file mode 100644
index 0000000..3ae31b4
--- /dev/null
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
@@ -0,0 +1,199 @@
+// Copyright (C) 2013 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.acceptance.server.change;
+
+import static com.google.gerrit.acceptance.git.GitUtil.add;
+import static com.google.gerrit.acceptance.git.GitUtil.cloneProject;
+import static com.google.gerrit.acceptance.git.GitUtil.createCommit;
+import static com.google.gerrit.acceptance.git.GitUtil.createProject;
+import static com.google.gerrit.acceptance.git.GitUtil.initSsh;
+import static com.google.gerrit.acceptance.git.GitUtil.pushHead;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.AccountCreator;
+import com.google.gerrit.acceptance.RestSession;
+import com.google.gerrit.acceptance.SshSession;
+import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.git.PushOneCommit;
+import com.google.gerrit.acceptance.git.GitUtil.Commit;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.OutputFormat;
+import com.google.gson.reflect.TypeToken;
+import com.google.gwtorm.server.OrmException;
+import com.google.gwtorm.server.SchemaFactory;
+import com.google.inject.Inject;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+public class GetRelatedIT extends AbstractDaemonTest {
+
+ @Inject
+ private AccountCreator accounts;
+
+ @Inject
+ private SchemaFactory<ReviewDb> reviewDbProvider;
+
+ private TestAccount admin;
+ private RestSession session;
+ private Git git;
+ private ReviewDb db;
+
+ @Before
+ public void setUp() throws Exception {
+ admin = accounts.admin();
+ session = new RestSession(server, admin);
+
+ initSsh(admin);
+ Project.NameKey project = new Project.NameKey("p");
+ SshSession sshSession = new SshSession(server, admin);
+ createProject(sshSession, project.get());
+ git = cloneProject(sshSession.getUrl() + "/" + project.get());
+ sshSession.close();
+ db = reviewDbProvider.open();
+ }
+
+ @After
+ public void cleanup() {
+ db.close();
+ }
+
+ @Test
+ public void getRelatedNoResult() throws GitAPIException,
+ IOException, Exception {
+ PushOneCommit push = new PushOneCommit(db, admin.getIdent());
+ PatchSet.Id ps = push.to(git, "refs/for/master").getPatchSetId();
+ List<ChangeAndCommit> related = getRelated(ps);
+ assertEquals(0, related.size());
+ }
+
+ @Test
+ public void getRelatedLinear() throws GitAPIException,
+ IOException, Exception {
+ add(git, "a.txt", "1");
+ Commit c1 = createCommit(git, admin.getIdent(), "subject: 1");
+ add(git, "b.txt", "2");
+ Commit c2 = createCommit(git, admin.getIdent(), "subject: 2");
+ pushHead(git, "refs/for/master", false);
+
+ for (Commit c : ImmutableList.of(c2, c1)) {
+ List<ChangeAndCommit> related = getRelated(getPatchSetId(c));
+ assertEquals(2, related.size());
+ assertEquals("related to " + c.getChangeId(), c2.getChangeId(), related.get(0).changeId);
+ assertEquals("related to " + c.getChangeId(), c1.getChangeId(), related.get(1).changeId);
+ }
+ }
+
+ @Test
+ public void getRelatedReorder() throws GitAPIException,
+ IOException, Exception {
+ // Create two commits and push.
+ add(git, "a.txt", "1");
+ Commit c1 = createCommit(git, admin.getIdent(), "subject: 1");
+ add(git, "b.txt", "2");
+ Commit c2 = createCommit(git, admin.getIdent(), "subject: 2");
+ pushHead(git, "refs/for/master", false);
+ PatchSet.Id c1ps1 = getPatchSetId(c1);
+ PatchSet.Id c2ps1 = getPatchSetId(c2);
+
+ // Swap the order of commits and push again.
+ git.reset().setMode(ResetType.HARD).setRef("HEAD^^").call();
+ git.cherryPick().include(c2.getCommit()).include(c1.getCommit()).call();
+ pushHead(git, "refs/for/master", false);
+ PatchSet.Id c1ps2 = getPatchSetId(c1);
+ PatchSet.Id c2ps2 = getPatchSetId(c2);
+
+ for (PatchSet.Id ps : ImmutableList.of(c2ps2, c1ps2)) {
+ List<ChangeAndCommit> related = getRelated(ps);
+ assertEquals(2, related.size());
+ assertEquals("related to " + ps, c1.getChangeId(), related.get(0).changeId);
+ assertEquals("related to " + ps, c2.getChangeId(), related.get(1).changeId);
+ }
+
+ for (PatchSet.Id ps : ImmutableList.of(c2ps1, c1ps1)) {
+ List<ChangeAndCommit> related = getRelated(ps);
+ assertEquals(2, related.size());
+ assertEquals("related to " + ps, c2.getChangeId(), related.get(0).changeId);
+ assertEquals("related to " + ps, c1.getChangeId(), related.get(1).changeId);
+ }
+ }
+
+ @Test
+ public void getRelatedReorderAndExtend() throws GitAPIException,
+ IOException, Exception {
+ // Create two commits and push.
+ add(git, "a.txt", "1");
+ Commit c1 = createCommit(git, admin.getIdent(), "subject: 1");
+ add(git, "b.txt", "2");
+ Commit c2 = createCommit(git, admin.getIdent(), "subject: 2");
+ pushHead(git, "refs/for/master", false);
+ PatchSet.Id c1ps1 = getPatchSetId(c1);
+ PatchSet.Id c2ps1 = getPatchSetId(c2);
+
+ // Swap the order of commits, create a new commit on top, and push again.
+ git.reset().setMode(ResetType.HARD).setRef("HEAD^^").call();
+ git.cherryPick().include(c2.getCommit()).include(c1.getCommit()).call();
+ add(git, "c.txt", "3");
+ Commit c3 = createCommit(git, admin.getIdent(), "subject: 3");
+ pushHead(git, "refs/for/master", false);
+ PatchSet.Id c1ps2 = getPatchSetId(c1);
+ PatchSet.Id c2ps2 = getPatchSetId(c2);
+ PatchSet.Id c3ps1 = getPatchSetId(c3);
+
+
+ for (PatchSet.Id ps : ImmutableList.of(c3ps1, c2ps2, c1ps2)) {
+ List<ChangeAndCommit> related = getRelated(ps);
+ assertEquals(3, related.size());
+ assertEquals("related to " + ps, c3.getChangeId(), related.get(0).changeId);
+ assertEquals("related to " + ps, c1.getChangeId(), related.get(1).changeId);
+ assertEquals("related to " + ps, c2.getChangeId(), related.get(2).changeId);
+ }
+
+ for (PatchSet.Id ps : ImmutableList.of(c2ps1, c1ps1)) {
+ List<ChangeAndCommit> related = getRelated(ps);
+ assertEquals(3, related.size());
+ assertEquals("related to " + ps, c3.getChangeId(), related.get(0).changeId);
+ assertEquals("related to " + ps, c2.getChangeId(), related.get(1).changeId);
+ assertEquals("related to " + ps, c1.getChangeId(), related.get(2).changeId);
+ }
+ }
+
+ private List<ChangeAndCommit> getRelated(PatchSet.Id ps) throws IOException {
+ String url = String.format("/changes/%d/revisions/%d/related",
+ ps.getParentKey().get(), ps.get());
+ RelatedInfo related = OutputFormat.JSON_COMPACT.newGson().fromJson(
+ session.get(url).getReader(),
+ new TypeToken<RelatedInfo>() {}.getType());
+ return related.changes;
+ }
+
+ private PatchSet.Id getPatchSetId(Commit c) throws OrmException {
+ return Iterables.getOnlyElement(
+ db.changes().byKey(new Change.Key(c.getChangeId()))).currentPatchSetId();
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/RelatedInfo.java
similarity index 72%
rename from gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java
rename to gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/RelatedInfo.java
index 64f832b..4089910 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/JsUiPlugin.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/RelatedInfo.java
@@ -12,13 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.client.api;
+package com.google.gerrit.acceptance.server.change;
-import com.google.gwt.core.client.JavaScriptObject;
+import java.util.List;
-class JsUiPlugin extends JavaScriptObject {
- final native String name() /*-{ return this.name }-*/;
-
- protected JsUiPlugin() {
- }
+public class RelatedInfo {
+ public List<ChangeAndCommit> changes;
}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
index 7fd8864..408ad39 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
@@ -33,14 +33,18 @@
return new LabelType(name, values);
}
- private static String checkName(String name) {
+ public static String checkName(String name) {
+ if (name == null || name.isEmpty()) {
+ throw new IllegalArgumentException("Empty label name");
+ }
if ("SUBM".equals(name)) {
throw new IllegalArgumentException(
"Reserved label name \"" + name + "\"");
}
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
- if (!((c >= 'a' && c <= 'z') ||
+ if ((i == 0 && c == '-') ||
+ !((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '-')) {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
index 8015117..19fcbeb 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
@@ -15,29 +15,17 @@
package com.google.gerrit.common.data;
import com.google.gerrit.common.audit.Audit;
-import com.google.gerrit.common.auth.SignInRequired;
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtjsonrpc.common.RemoteJsonService;
import com.google.gwtjsonrpc.common.RpcImpl;
import com.google.gwtjsonrpc.common.RpcImpl.Version;
-import com.google.gwtjsonrpc.common.VoidResult;
@RpcImpl(version = Version.V2_0)
public interface PatchDetailService extends RemoteJsonService {
@Audit
void patchScript(Patch.Key key, PatchSet.Id a, PatchSet.Id b,
AccountDiffPreference diffPrefs, AsyncCallback<PatchScript> callback);
-
- @Audit
- @SignInRequired
- void saveDraft(PatchLineComment comment,
- AsyncCallback<PatchLineComment> callback);
-
- @Audit
- @SignInRequired
- void deleteDraft(PatchLineComment.Key key, AsyncCallback<VoidResult> callback);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index 179adc2..7972e52 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -22,6 +22,7 @@
import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.admin.ProjectScreen;
import com.google.gerrit.client.api.ApiGlue;
+import com.google.gerrit.client.api.PluginLoader;
import com.google.gerrit.client.changes.ChangeConstants;
import com.google.gerrit.client.changes.ChangeListScreen;
import com.google.gerrit.client.config.ConfigServerApi;
@@ -49,12 +50,8 @@
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.aria.client.Roles;
-import com.google.gwt.core.client.Callback;
-import com.google.gwt.core.client.CodeDownloadException;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.ScriptInjector;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -84,12 +81,9 @@
import com.google.gwtexpui.clippy.client.CopyableLabel;
import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtexpui.user.client.ViewSite;
-import com.google.gwtjsonrpc.client.CallbackHandle;
import com.google.gwtjsonrpc.client.JsonDefTarget;
import com.google.gwtjsonrpc.client.JsonUtil;
import com.google.gwtjsonrpc.client.XsrfManager;
-import com.google.gwtjsonrpc.client.impl.ResultDeserializer;
-import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.client.KeyUtil;
import java.util.HashMap;
@@ -571,7 +565,7 @@
}
saveDefaultTheme();
- loadPlugins(hpd, token);
+ PluginLoader.load(hpd.plugins, token);
}
private void saveDefaultTheme() {
@@ -580,53 +574,6 @@
Document.get().getElementById("gerrit_footer"));
}
- private void loadPlugins(HostPageData hpd, final String token) {
- if (hpd.plugins != null && !hpd.plugins.isEmpty()) {
- for (final String url : hpd.plugins) {
- ScriptInjector.fromUrl(url)
- .setWindow(ScriptInjector.TOP_WINDOW)
- .setCallback(new Callback<Void, Exception>() {
- @Override
- public void onSuccess(Void result) {
- }
-
- @Override
- public void onFailure(Exception reason) {
- ErrorDialog d;
- if (reason instanceof CodeDownloadException) {
- d = new ErrorDialog(M.cannotDownloadPlugin(url));
- } else {
- d = new ErrorDialog(M.pluginFailed(url));
- }
- d.center();
- }
- }).inject();
- }
- }
-
- CallbackHandle<Void> cb = new CallbackHandle<Void>(
- new ResultDeserializer<Void>() {
- @Override
- public Void fromResult(JavaScriptObject responseObject) {
- return null;
- }
- },
- new AsyncCallback<Void>() {
- @Override
- public void onFailure(Throwable caught) {
- }
-
- @Override
- public void onSuccess(Void result) {
- display(token);
- }
- });
- cb.install();
- ScriptInjector.fromString(cb.getFunctionName() + "();")
- .setWindow(ScriptInjector.TOP_WINDOW)
- .inject();
- }
-
public static void refreshMenuBar() {
menuLeft.clear();
menuRight.clear();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
index 44fcc8a..c0f91d3 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
@@ -20,6 +20,7 @@
String menuSignIn();
String menuRegister();
String reportBug();
+ String loadingPlugins();
String signInDialogTitle();
String signInDialogClose();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
index 893838a..d940f53 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
@@ -1,6 +1,7 @@
menuSignIn = Sign In
menuRegister = Register
reportBug = Report Bug
+loadingPlugins = Loading plugins ...
signInDialogTitle = Code Review - Sign In
signInDialogClose = Close
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
index 660a160..5bb207d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
@@ -116,6 +116,7 @@
String errorDialogGlass();
String errorDialogText();
String errorDialogTitle();
+ String loadingPluginsDialog();
String fileColumnHeader();
String fileCommentBorder();
String fileLine();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties
index 8196e98..4a97c81 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties
@@ -13,7 +13,7 @@
branchAlreadyExists = A branch with the name {0} already exists.
branchCreationConflict = Cannot create branch {0} since it conflicts with branch {1}.
-pluginFailed = Plugin JavaScript {0} failed to load
-cannotDownloadPlugin = Cannot download JavaScript plugin from: {0}.
+pluginFailed = Plugin "{0}" failed to load
+cannotDownloadPlugin = Cannot load plugin from {0}
parentUpdateFailed = Setting parent project failed: {0}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/DiffPreferences.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/DiffPreferences.java
index fdf0af3..8ed5f0b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/DiffPreferences.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/DiffPreferences.java
@@ -34,6 +34,7 @@
p.syntaxHighlighting(in.isSyntaxHighlighting());
p.hideTopMenu(in.isHideTopMenu());
p.expandAllComments(in.isExpandAllComments());
+ p.manualReview(in.isManualReview());
return p;
}
@@ -48,6 +49,7 @@
p.setSyntaxHighlighting(syntaxHighlighting());
p.setHideTopMenu(hideTopMenu());
p.setExpandAllComments(expandAllComments());
+ p.setManualReview(manualReview());
}
public final void ignoreWhitespace(Whitespace i) {
@@ -64,6 +66,7 @@
public final native void syntaxHighlighting(boolean s) /*-{ this.syntax_highlighting = s }-*/;
public final native void hideTopMenu(boolean s) /*-{ this.hide_top_menu = s }-*/;
public final native void expandAllComments(boolean e) /*-{ this.expand_all_comments = e }-*/;
+ public final native void manualReview(boolean r) /*-{ this.manual_review = r }-*/;
public final Whitespace ignoreWhitespace() {
String s = ignoreWhitespaceRaw();
@@ -80,6 +83,8 @@
public final native boolean syntaxHighlighting() /*-{ return this.syntax_highlighting || false }-*/;
public final native boolean hideTopMenu() /*-{ return this.hide_top_menu || false }-*/;
public final native boolean expandAllComments() /*-{ return this.expand_all_comments || false }-*/;
+ public final native boolean manualReview() /*-{ return this.manual_review || false }-*/;
+ public final boolean autoReview() { return !manualReview(); }
private final native int get(String n, int d)
/*-{ return this.hasOwnProperty(n) ? this[n] : d }-*/;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectAccessEditor.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectAccessEditor.java
index 02a19dc8..1d7b960 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectAccessEditor.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectAccessEditor.java
@@ -23,6 +23,7 @@
import com.google.gerrit.common.data.ProjectAccess;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
@@ -125,7 +126,7 @@
history.getStyle().setDisplay(Display.BLOCK);
gitweb.setText(c.getLinkName());
gitweb.setHref(c.toFileHistory(new Branch.NameKey(value.getProjectName(),
- "refs/meta/config"), "project.config"));
+ RefNames.REFS_CONFIG), "project.config"));
} else {
history.getStyle().setDisplay(Display.NONE);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesScreen.java
index b7c82fb..d84f931 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectBranchesScreen.java
@@ -34,6 +34,7 @@
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
@@ -394,7 +395,7 @@
final FlexCellFormatter fmt = table.getFlexCellFormatter();
String iconCellStyle = Gerrit.RESOURCES.css().iconCell();
String dataCellStyle = Gerrit.RESOURCES.css().dataCell();
- if ("refs/meta/config".equals(k.getShortName())
+ if (RefNames.REFS_CONFIG.equals(k.getShortName())
|| "HEAD".equals(k.getShortName())) {
iconCellStyle = Gerrit.RESOURCES.css().specialBranchIconCell();
dataCellStyle = Gerrit.RESOURCES.css().specialBranchDataCell();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
index 772b7c6..d23e094 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/ApiGlue.java
@@ -15,6 +15,8 @@
package com.google.gerrit.client.api;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.rpc.NativeString;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.History;
@@ -24,29 +26,36 @@
private static String pluginName;
public static void init() {
- init0();
+ init0(GWT.getHostPageBaseURL(), NativeString.TYPE);
ActionContext.init();
+ Plugin.init();
addHistoryHook();
}
- private static native void init0() /*-{
- var serverUrl = @com.google.gwt.core.client.GWT::getHostPageBaseURL()();
- var Plugin = function (name){this.name = name};
- var Gerrit = {
+ private static native void init0(String serverUrl, JavaScriptObject JsonString) /*-{
+ $wnd.Gerrit = {
+ JsonString: JsonString,
+ events: {},
+ plugins: {},
+ change_actions: {},
+ revision_actions: {},
+ project_actions: {},
+
getPluginName: @com.google.gerrit.client.api.ApiGlue::getPluginName(),
install: function (f) {
- var p = new Plugin(this.getPluginName());
- @com.google.gerrit.client.api.ApiGlue::install(Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gerrit/client/api/JsUiPlugin;)(f,p);
+ var p = this._getPluginByUrl(@com.google.gerrit.client.api.PluginName::getCallerUrl()());
+ @com.google.gerrit.client.api.ApiGlue::install(Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gerrit/client/api/Plugin;)(f,p);
+ },
+ installGwt: function(u){return this._getPluginByUrl(u)},
+ _getPluginByUrl: function(u) {
+ return u.indexOf(serverUrl) == 0
+ ? this.plugins[u.substring(serverUrl.length)]
+ : this.plugins[u]
},
go: @com.google.gerrit.client.api.ApiGlue::go(Ljava/lang/String;),
refresh: @com.google.gerrit.client.api.ApiGlue::refresh(),
- events: {},
- change_actions: {},
- revision_actions: {},
- project_actions: {},
-
on: function (e,f){(this.events[e] || (this.events[e]=[])).push(f)},
onAction: function (t,n,c){this._onAction(this.getPluginName(),t,n,c)},
_onAction: function (p,t,n,c) {
@@ -81,34 +90,7 @@
}
},
'delete': function(u,b){@com.google.gerrit.client.api.ActionContext::delete(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),b)},
- JsonString: @com.google.gerrit.client.rpc.NativeString::TYPE,
};
-
- Plugin.prototype = {
- getPluginName: function(){return this.name},
- go: @com.google.gerrit.client.api.ApiGlue::go(Ljava/lang/String;),
- refresh: Gerrit.refresh,
- onAction: function(t,n,c) {Gerrit._onAction(this.name,t,n,c)},
-
- url: function (d) {
- var u = serverUrl + 'plugins/' + this.name + '/';
- if (d && d.length > 0) u += d.charAt(0)=='/' ? d.substring(1) : d;
- return u;
- },
-
- _api: function(d) {
- var u = 'plugins/' + this.name + '/';
- if (d && d.length > 0) u += d.charAt(0)=='/' ? d.substring(1) : d;
- return @com.google.gerrit.client.rpc.RestApi::new(Ljava/lang/String;)(u);
- },
-
- get: function(u,b){@com.google.gerrit.client.api.ActionContext::get(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),b)},
- post: function(u,i,b){@com.google.gerrit.client.api.ActionContext::post(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),i,b)},
- put: function(u,i,b){@com.google.gerrit.client.api.ActionContext::put(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),i,b)},
- 'delete': function(u,b){@com.google.gerrit.client.api.ActionContext::delete(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),b)},
- };
-
- $wnd.Gerrit = Gerrit;
}-*/;
/** Install deprecated {@code gerrit_addHistoryHook()} function. */
@@ -119,17 +101,25 @@
};
}-*/;
- private static void install(JavaScriptObject cb, JsUiPlugin p) {
+ private static void install(JavaScriptObject cb, Plugin p) throws Exception {
try {
pluginName = p.name();
invoke(cb, p);
+ p._initialized();
+ } catch (Exception e) {
+ p.failure(e);
+ throw e;
} finally {
pluginName = null;
+ PluginLoader.loaded();
}
}
private static final String getPluginName() {
- return pluginName != null ? pluginName : PluginName.get();
+ if (pluginName != null) {
+ return pluginName;
+ }
+ return PluginName.fromUrl(PluginName.getCallerUrl());
}
private static final void go(String urlOrToken) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java
new file mode 100644
index 0000000..632f179
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/Plugin.java
@@ -0,0 +1,77 @@
+// Copyright (C) 2013 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.client.api;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+final class Plugin extends JavaScriptObject {
+ private static final JavaScriptObject TYPE = createType();
+
+ static Plugin create(String url) {
+ int s = "plugins/".length();
+ int e = url.indexOf('/', s);
+ String name = url.substring(s, e);
+ return create(TYPE, url, name);
+ }
+
+ final native String url() /*-{ return this._scriptUrl }-*/;
+ final native String name() /*-{ return this.name }-*/;
+
+ final native boolean loaded() /*-{ return this._success || this._failure != null }-*/;
+ final native Exception failure() /*-{ return this._failure }-*/;
+ final native void failure(Exception e) /*-{ this._failure = e }-*/;
+ final native boolean success() /*-{ return this._success || false }-*/;
+ final native void _initialized() /*-{ this._success = true }-*/;
+
+ private static native Plugin create(JavaScriptObject T, String u, String n)
+ /*-{ return new T(u,n) }-*/;
+
+ private static native JavaScriptObject createType() /*-{
+ function Plugin(u, n) {
+ this._scriptUrl = u;
+ this.name = n;
+ }
+ return Plugin;
+ }-*/;
+
+ static native void init() /*-{
+ var G = $wnd.Gerrit;
+ @com.google.gerrit.client.api.Plugin::TYPE.prototype = {
+ getPluginName: function(){return this.name},
+ go: @com.google.gerrit.client.api.ApiGlue::go(Ljava/lang/String;),
+ refresh: @com.google.gerrit.client.api.ApiGlue::refresh(),
+ on: G.on,
+ onAction: function(t,n,c){G._onAction(this.name,t,n,c)},
+
+ url: function (u){return G.url(this._url(u))},
+ get: function(u,b){@com.google.gerrit.client.api.ActionContext::get(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),b)},
+ post: function(u,i,b){@com.google.gerrit.client.api.ActionContext::post(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),i,b)},
+ put: function(u,i,b){@com.google.gerrit.client.api.ActionContext::put(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),i,b)},
+ 'delete': function(u,b){@com.google.gerrit.client.api.ActionContext::delete(Lcom/google/gerrit/client/rpc/RestApi;Lcom/google/gwt/core/client/JavaScriptObject;)(this._api(u),b)},
+
+ _loadedGwt: function(){@com.google.gerrit.client.api.PluginLoader::loaded()()},
+ _api: function(u){return @com.google.gerrit.client.rpc.RestApi::new(Ljava/lang/String;)(this._url(u))},
+ _url: function (d) {
+ var u = 'plugins/' + this.name + '/';
+ if (d && d.length > 0)
+ return u + (d.charAt(0)=='/' ? d.substring(1) : d);
+ return u;
+ },
+ };
+ }-*/;
+
+ protected Plugin() {
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginLoader.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginLoader.java
new file mode 100644
index 0000000..8b5c93e
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginLoader.java
@@ -0,0 +1,185 @@
+// Copyright (C) 2013 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.client.api;
+
+import com.google.gerrit.client.ErrorDialog;
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.rpc.NativeMap;
+import com.google.gerrit.client.rpc.Natives;
+import com.google.gwt.core.client.Callback;
+import com.google.gwt.core.client.CodeDownloadException;
+import com.google.gwt.core.client.ScriptInjector;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwtexpui.progress.client.ProgressBar;
+
+import java.util.List;
+
+/** Loads JavaScript plugins with a progress meter visible. */
+public class PluginLoader extends DialogBox {
+ private static final int MAX_LOAD_TIME_MILLIS = 5000;
+ private static PluginLoader self;
+
+ public static void load(List<String> plugins, final String token) {
+ if (plugins == null || plugins.isEmpty()) {
+ Gerrit.display(token);
+ } else {
+ self = new PluginLoader(token);
+ self.load(plugins);
+ self.startTimers();
+ self.center();
+ }
+ }
+
+ static void loaded() {
+ self.loadedOne();
+ }
+
+ private final String token;
+ private ProgressBar progress;
+ private Timer show;
+ private Timer update;
+ private Timer timeout;
+ private boolean visible;
+
+ private PluginLoader(String tokenToDisplay) {
+ super(/* auto hide */false, /* modal */true);
+ token = tokenToDisplay;
+ progress = new ProgressBar(Gerrit.C.loadingPlugins());
+
+ setStyleName(Gerrit.RESOURCES.css().errorDialog());
+ addStyleName(Gerrit.RESOURCES.css().loadingPluginsDialog());
+ }
+
+ private void load(List<String> pluginUrls) {
+ for (String url : pluginUrls) {
+ Plugin plugin = Plugin.create(url);
+ plugins().put(url, plugin);
+ ScriptInjector.fromUrl(url)
+ .setWindow(ScriptInjector.TOP_WINDOW)
+ .setCallback(new LoadCallback(plugin))
+ .inject();
+ }
+ }
+
+ private void startTimers() {
+ show = new Timer() {
+ @Override
+ public void run() {
+ setText(Window.getTitle());
+ setWidget(progress);
+ setGlassEnabled(true);
+ getGlassElement().addClassName(Gerrit.RESOURCES.css().errorDialogGlass());
+ hide(true);
+ center();
+ visible = true;
+ }
+ };
+ show.schedule(500);
+
+ update = new Timer() {
+ private int cycle;
+
+ @Override
+ public void run() {
+ progress.setValue(100 * ++cycle * 250 / MAX_LOAD_TIME_MILLIS);
+ }
+ };
+ update.scheduleRepeating(250);
+
+ timeout = new Timer() {
+ @Override
+ public void run() {
+ finish();
+ }
+ };
+ timeout.schedule(MAX_LOAD_TIME_MILLIS);
+ }
+
+ private void loadedOne() {
+ boolean done = true;
+ for (Plugin plugin : Natives.asList(plugins().values())) {
+ done &= plugin.loaded();
+ }
+ if (done) {
+ finish();
+ }
+ }
+
+ private void finish() {
+ show.cancel();
+ update.cancel();
+ timeout.cancel();
+ self = null;
+
+ if (!hadFailures()) {
+ if (visible) {
+ progress.setValue(100);
+ new Timer() {
+ @Override
+ public void run() {
+ hide(true);
+ }
+ }.schedule(250);
+ } else {
+ hide(true);
+ }
+ }
+
+ Gerrit.display(token);
+ }
+
+ private boolean hadFailures() {
+ boolean failed = false;
+ for (Plugin plugin : Natives.asList(plugins().values())) {
+ if (!plugin.success()) {
+ failed = true;
+
+ Exception e = plugin.failure();
+ String msg;
+ if (e != null && e instanceof CodeDownloadException) {
+ msg = Gerrit.M.cannotDownloadPlugin(plugin.url());
+ } else {
+ msg = Gerrit.M.pluginFailed(plugin.name());
+ }
+ hide(true);
+ new ErrorDialog(msg).center();
+ }
+ }
+ return failed;
+ }
+
+ private static native NativeMap<Plugin> plugins()
+ /*-{ return $wnd.Gerrit.plugins }-*/;
+
+ private class LoadCallback implements Callback<Void, Exception> {
+ private final Plugin plugin;
+
+ LoadCallback(Plugin plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public void onSuccess(Void result) {
+ }
+
+ @Override
+ public void onFailure(Exception reason) {
+ plugin.failure(reason);
+ loadedOne();
+ }
+ }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginName.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginName.java
index 5fc87d5..2c1f2c7 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginName.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/PluginName.java
@@ -31,14 +31,29 @@
class PluginName {
private static final String UNKNOWN = "<unknown>";
- static String get() {
- return GWT.<PluginName> create(PluginName.class).guessName();
+ private static String baseUrl() {
+ return GWT.getHostPageBaseURL() + "plugins/";
}
- String guessName() {
+ static String getCallerUrl() {
+ return GWT.<PluginName> create(PluginName.class).findCallerUrl();
+ }
+
+ static String fromUrl(String url) {
+ String baseUrl = baseUrl();
+ if (url != null && url.startsWith(baseUrl)) {
+ int s = url.indexOf('/', baseUrl.length());
+ if (s > 0) {
+ return url.substring(baseUrl.length(), s);
+ }
+ }
+ return UNKNOWN;
+ }
+
+ String findCallerUrl() {
JavaScriptException err = makeException();
if (hasStack(err)) {
- return PluginNameMoz.guessName(err);
+ return PluginNameMoz.getUrl(err);
}
String baseUrl = baseUrl();
@@ -46,19 +61,12 @@
for (int i = trace.length - 1; i >= 0; i--) {
String u = trace[i].getFileName();
if (u != null && u.startsWith(baseUrl)) {
- int s = u.indexOf('/', baseUrl.length());
- if (s > 0) {
- return u.substring(baseUrl.length(), s);
- }
+ return u;
}
}
return UNKNOWN;
}
- private static String baseUrl() {
- return GWT.getHostPageBaseURL() + "plugins/";
- }
-
private static StackTraceElement[] getTrace(JavaScriptException err) {
StackTraceCreator.fillInStackTrace(err);
return err.getStackTrace();
@@ -72,21 +80,22 @@
/** Extracts URL from the stack frame. */
static class PluginNameMoz extends PluginName {
- String guessName() {
- return guessName(makeException());
+ String findCallerUrl() {
+ return getUrl(makeException());
}
- static String guessName(JavaScriptException e) {
+ private static String getUrl(JavaScriptException e) {
String baseUrl = baseUrl();
JsArrayString stack = getStack(e);
for (int i = stack.length() - 1; i >= 0; i--) {
String frame = stack.get(i);
int at = frame.indexOf(baseUrl);
if (at >= 0) {
- int s = frame.indexOf('/', at + baseUrl.length());
- if (s > 0) {
- return frame.substring(at + baseUrl.length(), s);
+ int end = frame.indexOf(':', at + baseUrl.length());
+ if (end < 0) {
+ end = frame.length();
}
+ return frame.substring(at, end);
}
}
return UNKNOWN;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
index c974180..5aa5537 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
@@ -64,6 +64,7 @@
interface FileTableCss extends CssResource {
String table();
+ String nohover();
String pointer();
String reviewed();
String status();
@@ -81,6 +82,7 @@
private static final String REVIEWED;
private static final String OPEN;
+ private static final int C_PATH = 3;
private static final HyperlinkImpl link = GWT.create(HyperlinkImpl.class);
static {
@@ -111,6 +113,7 @@
if (t != null) {
t.onOpenRow(1 + idx);
e.preventDefault();
+ e.stopPropagation();
return false;
}
}
@@ -307,6 +310,15 @@
Gerrit.display(url(list.get(row - 1)));
}
}
+
+ @Override
+ protected void onCellSingleClick(Event event, int row, int column) {
+ if (column == C_PATH && link.handleAsClick(event)) {
+ onOpenRow(row);
+ } else {
+ super.onCellSingleClick(event, row, column);
+ }
+ }
}
private final class DisplayCommand implements RepeatingCommand {
@@ -406,7 +418,7 @@
}
private void header(SafeHtmlBuilder sb) {
- sb.openTr();
+ sb.openTr().setStyleName(R.css().nohover());
sb.openTh().setStyleName(R.css().pointer()).closeTh();
sb.openTh().setStyleName(R.css().reviewed()).closeTh();
sb.openTh().setStyleName(R.css().status()).closeTh();
@@ -586,7 +598,7 @@
}
private void footer(SafeHtmlBuilder sb) {
- sb.openTr();
+ sb.openTr().setStyleName(R.css().nohover());
sb.openTh().setStyleName(R.css().pointer()).closeTh();
sb.openTh().setStyleName(R.css().reviewed()).closeTh();
sb.openTh().setStyleName(R.css().status()).closeTh();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
index 08c7d5d..f98e8b4 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
@@ -324,7 +324,7 @@
: null;
}
- final native boolean has_change_number()
+ public final native boolean has_change_number()
/*-{ return this.hasOwnProperty('_change_number') }-*/;
final native boolean has_revision_number()
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
index 3693ced..92b30a0 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
@@ -287,54 +287,59 @@
NativeMap<LabelInfo> all,
NativeMap<JsArrayString> permitted) {
TreeSet<Short> values = new TreeSet<Short>();
+ List<LabelAndValues> labels =
+ new ArrayList<LabelAndValues>(permitted.size());
for (String id : names) {
JsArrayString p = permitted.get(id);
if (p != null) {
+ Set<Short> a = new TreeSet<Short>();
for (int i = 0; i < p.length(); i++) {
- values.add(LabelInfo.parseValue(p.get(i)));
+ a.add(LabelInfo.parseValue(p.get(i)));
}
+ labels.add(new LabelAndValues(all.get(id), a));
+ values.addAll(a);
}
}
List<Short> columns = new ArrayList<Short>(values);
- labelsTable.resize(1 + permitted.size(), 1 + values.size());
+ labelsTable.resize(1 + labels.size(), 1 + values.size());
for (int c = 0; c < columns.size(); c++) {
labelsTable.setText(0, 1 + c, LabelValue.formatValue(columns.get(c)));
labelsTable.getCellFormatter().setStyleName(0, 1 + c, style.label_value());
}
- List<String> checkboxes = new ArrayList<String>(permitted.size());
+ List<LabelAndValues> checkboxes =
+ new ArrayList<LabelAndValues>(labels.size());
int row = 1;
- for (String id : names) {
- Set<Short> vals = all.get(id).value_set();
- if (isCheckBox(vals)) {
- checkboxes.add(id);
+ for (LabelAndValues lv : labels) {
+ if (isCheckBox(lv.info.value_set())) {
+ checkboxes.add(lv);
} else {
- renderRadio(row++, id, columns, vals, all.get(id));
+ renderRadio(row++, columns, lv);
}
}
- for (String id : checkboxes) {
- renderCheckBox(row++, id, all.get(id));
+ for (LabelAndValues lv : checkboxes) {
+ renderCheckBox(row++, lv);
}
}
- private void renderRadio(int row, final String id,
- List<Short> columns,
- Set<Short> values,
- LabelInfo info) {
+ private void renderRadio(int row, List<Short> columns, LabelAndValues lv) {
+ final String id = lv.info.name();
+
labelsTable.setText(row, 0, id);
labelsTable.getCellFormatter().setStyleName(row, 0, style.label_name());
ApprovalInfo self = Gerrit.isSignedIn()
- ? info.for_user(Gerrit.getUserAccount().getId().get())
+ ? lv.info.for_user(Gerrit.getUserAccount().getId().get())
: null;
- final List<RadioButton> group = new ArrayList<RadioButton>(values.size());
+ final List<RadioButton> group =
+ new ArrayList<RadioButton>(lv.permitted.size());
for (int i = 0; i < columns.size(); i++) {
final Short v = columns.get(i);
- if (values.contains(v)) {
+ if (lv.permitted.contains(v)) {
RadioButton b = new RadioButton(id);
- b.setTitle(info.value_text(LabelValue.formatValue(v)));
+ b.setTitle(lv.info.value_text(LabelValue.formatValue(v)));
if ((self != null && v == self.value()) || (self == null && v == 0)) {
b.setValue(true);
}
@@ -364,14 +369,16 @@
}
}
- private void renderCheckBox(int row, final String id, LabelInfo info) {
+ private void renderCheckBox(int row, LabelAndValues lv) {
ApprovalInfo self = Gerrit.isSignedIn()
- ? info.for_user(Gerrit.getUserAccount().getId().get())
+ ? lv.info.for_user(Gerrit.getUserAccount().getId().get())
: null;
+ final String id = lv.info.name();
final CheckBox b = new CheckBox();
b.setText(id);
- b.setTitle(info.value_text("+1"));
+ b.setTitle(lv.info.value_text("+1"));
+ b.setEnabled(lv.permitted.contains((short) 1));
if (self != null && self.value() == 1) {
b.setValue(true);
}
@@ -433,4 +440,14 @@
}
return Natives.asList(l);
}
+
+ private static class LabelAndValues {
+ final LabelInfo info;
+ final Set<Short> permitted;
+
+ LabelAndValues(LabelInfo info, Set<Short> permitted) {
+ this.info = info;
+ this.permitted = permitted;
+ }
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
index c2947cf..4b695d2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
@@ -22,6 +22,12 @@
.table tr {
vertical-align: top;
}
+.table tr:hover {
+ background: rgba(209, 245, 248, 0.32);
+}
+.table tr.nohover:hover {
+ background: transparent;
+}
.status {
padding-right: 4px;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
index d27f29e..df6638d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
@@ -108,7 +108,7 @@
ChangeDetail r = new ChangeDetail();
r.setAllowsAnonymous(rev.has_fetch() && rev.fetch().containsKey("http"));
r.setCanAbandon(can(info.actions(), "abandon"));
- r.setCanEditCommitMessage(can(info.actions(), "message"));
+ r.setCanEditCommitMessage(can(rev.actions(), "message"));
r.setCanCherryPick(can(rev.actions(), "cherrypick"));
r.setCanPublish(can(rev.actions(), "publish"));
r.setCanRebase(can(rev.actions(), "rebase"));
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
index 7e222bb..296e481 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
@@ -345,7 +345,7 @@
List<ChangeInfo> d = new ArrayList<ChangeInfo>();
for (CommitInfo p : Natives.asList(self.commit().parents())) {
ChangeAndCommit pc = m.get(p.commit());
- if (pc != null) {
+ if (pc != null && pc.has_change_number()) {
ChangeInfo i = new ChangeInfo();
load(pc, i);
d.add(i);
@@ -364,7 +364,9 @@
List<ChangeInfo> n = new ArrayList<ChangeInfo>();
for (int i = 0; i < info.changes().length(); i++) {
ChangeAndCommit c = info.changes().get(i);
- if (c.commit() != null && c.commit().parents() != null) {
+ if (c.has_change_number()
+ && c.commit() != null
+ && c.commit().parents() != null) {
for (int j = 0; j < c.commit().parents().length(); j++) {
CommitInfo p = c.commit().parents().get(j);
if (mine.contains(p.commit())) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PublishCommentScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PublishCommentScreen.java
index 96073cc..e08703e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PublishCommentScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PublishCommentScreen.java
@@ -34,7 +34,6 @@
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.changes.ListChangesOption;
-import com.google.gerrit.common.changes.Side;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.SubmitTypeRecord;
import com.google.gerrit.reviewdb.client.Change;
@@ -485,26 +484,12 @@
for (String path : paths) {
JsArray<CommentInfo> comments = drafts.get(path);
for (int i = 0; i < comments.length(); i++) {
- d.add(toComment(path, comments.get(i)));
+ d.add(CommentEditorPanel.toComment(patchSetId, path, comments.get(i)));
}
}
return d;
}
- private PatchLineComment toComment(String path, CommentInfo i) {
- PatchLineComment p = new PatchLineComment(
- new PatchLineComment.Key(
- new Patch.Key(patchSetId, path),
- i.id()),
- i.line(),
- Gerrit.getUserAccount().getId(),
- i.in_reply_to(),
- i.updated());
- p.setMessage(i.message());
- p.setSide((short) (i.side() == Side.PARENT ? 0 : 1));
- return p;
- }
-
private static class ValueRadioButton extends RadioButton {
final LabelInfo label;
final String value;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
index 351442b..0aaa6f6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBoxUi.css
@@ -25,6 +25,11 @@
box-shadow: 3px 3px 3px #888888;
margin-bottom: 5px;
margin-right: 5px;
+ -webkit-touch-callout: initial;
+ -webkit-user-select: initial;
+ -khtml-user-select: initial;
+ -moz-user-select: initial;
+ -ms-user-select: initial;
}
.header { cursor: pointer; }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
index 407108b..17bacc6 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.java
@@ -45,6 +45,7 @@
String range();
String rangeHighlight();
String showTabs();
+ String padding();
}
@UiField
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
index 6c2fde1..05ea366 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml
@@ -24,10 +24,18 @@
@external .cm-searching, .cm-trailingspace, .cm-tab;
.fullscreen {
+ background-color: #f7f7f7;
border-bottom: 1px solid #ddd;
}
- .difftable { max-width: 1484px; }
+ .difftable {
+ max-width: 1484px;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ }
.difftable .CodeMirror-lines { padding: 0; }
.difftable .CodeMirror pre {
padding: 0;
@@ -109,6 +117,10 @@
content: "\00bb";
color: #f00;
}
+ .padding {
+ margin-left: 21px;
+ border-left: 2px solid #d64040;
+ }
</ui:style>
<g:HTMLPanel styleName='{style.difftable}'>
<table class='{style.table}'>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
index a4bfcfb..306109c7 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/Header.ui.xml
@@ -26,7 +26,7 @@
.reviewed input {
margin: 0;
padding: 0;
- vertical-align: bottom;
+ vertical-align: middle;
}
.path {
white-space: no-wrap;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
index 68a24f5..069e204 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesAction.java
@@ -61,7 +61,7 @@
popup.setPopupPositionAndShow(new PositionCallback() {
@Override
public void setPosition(int offsetWidth, int offsetHeight) {
- popup.setPopupPosition(390, 120);
+ popup.setPopupPosition(300, 120);
}
});
current.setFocus(true);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
index 1c92d56..a8c0872 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
@@ -80,6 +80,7 @@
@UiField ToggleButton whitespaceErrors;
@UiField ToggleButton showTabs;
@UiField ToggleButton topMenu;
+ @UiField ToggleButton manualReview;
@UiField ToggleButton expandAllComments;
@UiField Button apply;
@UiField Button save;
@@ -127,6 +128,7 @@
whitespaceErrors.setValue(prefs.showWhitespaceErrors());
showTabs.setValue(prefs.showTabs());
topMenu.setValue(!prefs.hideTopMenu());
+ manualReview.setValue(prefs.manualReview());
expandAllComments.setValue(prefs.expandAllComments());
switch (view.getIntraLineStatus()) {
@@ -244,6 +246,11 @@
view.resizeCodeMirror();
}
+ @UiHandler("manualReview")
+ void onManualReview(ValueChangeEvent<Boolean> e) {
+ prefs.manualReview(e.getValue());
+ }
+
@UiHandler("syntaxHighlighting")
void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
prefs.syntaxHighlighting(e.getValue());
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
index 7a1948c..ed77d09 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
@@ -204,6 +204,13 @@
</g:ToggleButton></td>
</tr>
<tr>
+ <th><ui:msg>Mark Reviewed</ui:msg></th>
+ <td><g:ToggleButton ui:field='manualReview'>
+ <g:upFace><ui:msg>Automatic</ui:msg></g:upFace>
+ <g:downFace><ui:msg>Manual</ui:msg></g:downFace>
+ </g:ToggleButton></td>
+ </tr>
+ <tr>
<th><ui:msg>Expand All Comments</ui:msg></th>
<td><g:ToggleButton ui:field='expandAllComments'>
<g:upFace><ui:msg>Collapse</ui:msg></g:upFace>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
index 4f2fa10..4a8b8a1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
@@ -23,6 +23,7 @@
import com.google.gerrit.client.changes.ChangeList;
import com.google.gerrit.client.changes.CommentApi;
import com.google.gerrit.client.changes.CommentInfo;
+import com.google.gerrit.client.changes.ReviewInfo;
import com.google.gerrit.client.diff.DiffInfo.Region;
import com.google.gerrit.client.diff.DiffInfo.Span;
import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo;
@@ -260,18 +261,24 @@
});
diffTable.sidePanel.adjustGutters(cmB);
- int line = 0;
- if (!diffChunks.isEmpty()) {
- DiffChunkInfo d = diffChunks.get(0);
- CodeMirror cm = getCmFromSide(d.getSide());
- line = d.getStart();
- if (cm.lineAtHeight(height - 20) < line) {
- cm.scrollToY(cm.heightAtLine(line, "local") - 0.5 * height);
+ if (diff.meta_b() != null) {
+ int line = 0;
+ if (!diffChunks.isEmpty()) {
+ DiffChunkInfo d = diffChunks.get(0);
+ CodeMirror cm = getCmFromSide(d.getSide());
+ line = d.getStart();
+ if (cm.lineAtHeight(height - 20) < line) {
+ cm.scrollToY(cm.heightAtLine(line, "local") - 0.5 * height);
+ }
}
+ cmB.setCursor(LineCharacter.create(line));
+ cmB.focus();
+ } else {
+ cmA.setCursor(LineCharacter.create(0));
+ cmA.focus();
}
- cmB.setCursor(LineCharacter.create(line));
- cmB.focus();
+ autoReview();
prefetchNextFile();
}
@@ -1146,6 +1153,7 @@
private PaddingWidgetWrapper addPaddingWidget(CodeMirror cm,
int line, double height, Unit unit, Integer index) {
SimplePanel padding = new SimplePanel();
+ padding.setStyleName(DiffTable.style.padding());
padding.getElement().getStyle().setHeight(height, unit);
Configuration config = Configuration.create()
.set("coverGutter", true)
@@ -1277,6 +1285,7 @@
if (cm.somethingSelected()) {
lineActiveBoxMap.put(handle,
addNewDraft(cm, line, fromTo.getTo().getLine() == line ? fromTo : null));
+ cm.setSelection(cm.getCursor());
} else if (box == null) {
lineActiveBoxMap.put(handle, addNewDraft(cm, line, null));
} else if (box instanceof DraftBox) {
@@ -1398,14 +1407,21 @@
if (res < 0) {
res = -res - (prev ? 1 : 2);
}
-
res = res + (prev ? -1 : 1);
- DiffChunkInfo lookUp = diffChunks.get(getWrapAroundDiffChunkIndex(res));
+ if (res < 0 || diffChunks.size() <= res) {
+ return;
+ }
+
+ DiffChunkInfo lookUp = diffChunks.get(res);
// If edit, skip the deletion chunk and set focus on the insertion one.
if (lookUp.isEdit() && lookUp.getSide() == DisplaySide.A) {
res = res + (prev ? -1 : 1);
+ if (res < 0 || diffChunks.size() <= res) {
+ return;
+ }
}
- DiffChunkInfo target = diffChunks.get(getWrapAroundDiffChunkIndex(res));
+
+ DiffChunkInfo target = diffChunks.get(res);
CodeMirror targetCm = getCmFromSide(target.getSide());
targetCm.setCursor(LineCharacter.create(target.getStart()));
targetCm.focus();
@@ -1461,10 +1477,6 @@
return null;
}
- private int getWrapAroundDiffChunkIndex(int index) {
- return (index + diffChunks.size()) % diffChunks.size();
- }
-
void defer(Runnable thunk) {
if (deferred == null) {
final ArrayList<Runnable> list = new ArrayList<Runnable>();
@@ -1612,6 +1624,25 @@
});
}
+ private void autoReview() {
+ if (Gerrit.isSignedIn() && prefs.autoReview()) {
+ ChangeApi.revision(revision)
+ .view("files")
+ .id(path)
+ .view("reviewed")
+ .background()
+ .put(new AsyncCallback<ReviewInfo>() {
+ @Override
+ public void onSuccess(ReviewInfo result) {
+ header.reviewed.setValue(true, false);
+ }
+ @Override
+ public void onFailure(Throwable caught) {
+ }
+ });
+ }
+ }
+
private void prefetchNextFile() {
String nextPath = header.getNextPath();
if (nextPath != null) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index 1b82573..9c8ec57 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -431,6 +431,11 @@
font-size: 15px;
font-family: verdana;
}
+.loadingPluginsDialog {
+ background: #fff;
+ color: #000;
+ width: auto;
+}
/** Screen **/
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
index fd3e35c..deaeed9 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/AbstractPatchContentTable.java
@@ -18,6 +18,9 @@
import com.google.gerrit.client.FormatUtil;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.changes.CommentApi;
+import com.google.gerrit.client.changes.CommentInfo;
+import com.google.gerrit.client.changes.CommentInput;
import com.google.gerrit.client.changes.PatchTable;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.rpc.GerritCallback;
@@ -937,13 +940,17 @@
CommentEditorPanel p = findOrCreateEditor(newComment, false);
if (p == null) {
enableButtons(false);
- PatchUtil.DETAIL_SVC.saveDraft(newComment,
- new GerritCallback<PatchLineComment>() {
+ final PatchSet.Id psId = newComment.getKey().getParentKey().getParentKey();
+ CommentInput in = CommentEditorPanel.toInput(newComment);
+ CommentApi.createDraft(psId, in,
+ new GerritCallback<CommentInfo>() {
@Override
- public void onSuccess(final PatchLineComment result) {
+ public void onSuccess(CommentInfo result) {
enableButtons(true);
notifyDraftDelta(1);
- findOrCreateEditor(result, true).setOpen(false);
+ findOrCreateEditor(CommentEditorPanel.toComment(
+ psId, newComment.getKey().getParentKey().get(), result),
+ true).setOpen(false);
}
@Override
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/CommentEditorPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/CommentEditorPanel.java
index 9ed3f18..f41b90e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/CommentEditorPanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/CommentEditorPanel.java
@@ -15,10 +15,17 @@
package com.google.gerrit.client.patches;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.changes.CommentApi;
+import com.google.gerrit.client.changes.CommentInfo;
+import com.google.gerrit.client.changes.CommentInput;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.client.ui.CommentPanel;
+import com.google.gerrit.common.changes.Side;
+import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
@@ -236,30 +243,37 @@
cancel.setEnabled(false);
discard.setEnabled(false);
- PatchUtil.DETAIL_SVC.saveDraft(comment,
- new GerritCallback<PatchLineComment>() {
- public void onSuccess(final PatchLineComment result) {
- notifyDraftDelta(isNew() ? 1 : 0);
- comment = result;
- text.setReadOnly(false);
- save.setEnabled(true);
- cancel.setEnabled(true);
- discard.setEnabled(true);
- render();
- onSave.onSuccess(VoidResult.INSTANCE);
- }
+ final PatchSet.Id psId = comment.getKey().getParentKey().getParentKey();
+ final boolean wasNew = isNew();
+ GerritCallback<CommentInfo> cb = new GerritCallback<CommentInfo>() {
+ public void onSuccess(CommentInfo result) {
+ notifyDraftDelta(wasNew ? 1 : 0);
+ comment = toComment(psId, comment.getKey().get(), result);
+ text.setReadOnly(false);
+ save.setEnabled(true);
+ cancel.setEnabled(true);
+ discard.setEnabled(true);
+ render();
+ onSave.onSuccess(VoidResult.INSTANCE);
+ }
- @Override
- public void onFailure(final Throwable caught) {
- text.setReadOnly(false);
- text.setFocus(true);
- save.setEnabled(true);
- cancel.setEnabled(true);
- discard.setEnabled(true);
- super.onFailure(caught);
- onSave.onFailure(caught);
- }
- });
+ @Override
+ public void onFailure(final Throwable caught) {
+ text.setReadOnly(false);
+ text.setFocus(true);
+ save.setEnabled(true);
+ cancel.setEnabled(true);
+ discard.setEnabled(true);
+ super.onFailure(caught);
+ onSave.onFailure(caught);
+ }
+ };
+ CommentInput input = toInput(comment);
+ if (wasNew) {
+ CommentApi.createDraft(psId, input, cb);
+ } else {
+ CommentApi.updateDraft(psId, input.id(), input, cb);
+ }
}
private void notifyDraftDelta(final int delta) {
@@ -283,9 +297,11 @@
cancel.setEnabled(false);
discard.setEnabled(false);
- PatchUtil.DETAIL_SVC.deleteDraft(comment.getKey(),
- new GerritCallback<VoidResult>() {
- public void onSuccess(final VoidResult result) {
+ CommentApi.deleteDraft(
+ comment.getKey().getParentKey().getParentKey(),
+ comment.getKey().get(),
+ new GerritCallback<JavaScriptObject>() {
+ public void onSuccess(JavaScriptObject result) {
notifyDraftDelta(-1);
removeUI();
}
@@ -319,4 +335,33 @@
}
return null;
}
+
+ public static CommentInput toInput(PatchLineComment c) {
+ CommentInput i = CommentInput.createObject().cast();
+ i.setId(c.getKey().get());
+ i.setPath(c.getKey().getParentKey().get());
+ i.setSide(c.getSide() == 0 ? Side.PARENT : Side.REVISION);
+ if (c.getLine() > 0) {
+ i.setLine(c.getLine());
+ }
+ i.setInReplyTo(c.getParentUuid());
+ i.setMessage(c.getMessage());
+ return i;
+ }
+
+ public static PatchLineComment toComment(PatchSet.Id ps,
+ String path,
+ CommentInfo i) {
+ PatchLineComment p = new PatchLineComment(
+ new PatchLineComment.Key(
+ new Patch.Key(ps, path),
+ i.id()),
+ i.line(),
+ Gerrit.getUserAccount().getId(),
+ i.in_reply_to(),
+ i.updated());
+ p.setMessage(i.message());
+ p.setSide((short) (i.side() == Side.PARENT ? 0 : 1));
+ return p;
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
index 683471a..22e96ed 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/SideBySideTable.java
@@ -32,6 +32,7 @@
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
@@ -40,6 +41,7 @@
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
+
import org.eclipse.jgit.diff.Edit;
import java.util.ArrayList;
@@ -76,8 +78,8 @@
}
@Override
- protected void onCellSingleClick(int row, int column) {
- super.onCellSingleClick(row, column);
+ protected void onCellSingleClick(Event event, int row, int column) {
+ super.onCellSingleClick(event, row, column);
if (column == 1 || column == 4) {
onCellDoubleClick(row, column);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
index 82e3107..7bc16fa 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/patches/UnifiedDiffTable.java
@@ -30,6 +30,7 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.UIObject;
import com.google.gwtexpui.safehtml.client.SafeHtml;
@@ -98,8 +99,8 @@
}
@Override
- protected void onCellSingleClick(int row, int column) {
- super.onCellSingleClick(row, column);
+ protected void onCellSingleClick(Event event, int row, int column) {
+ super.onCellSingleClick(event, row, column);
if (column == 1 || column == 2) {
if (!"".equals(table.getText(row, column))) {
onCellDoubleClick(row, column);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/NavigationTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/NavigationTable.java
index 38dda06..3780ef8 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/NavigationTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/NavigationTable.java
@@ -53,7 +53,7 @@
}
final int row = rowOf(td);
if (getRowItem(row) != null) {
- onCellSingleClick(rowOf(td), columnOf(td));
+ onCellSingleClick(event, rowOf(td), columnOf(td));
return;
}
break;
@@ -145,7 +145,7 @@
}
/** Invoked when the user clicks on a table cell. */
- protected void onCellSingleClick(int row, int column) {
+ protected void onCellSingleClick(Event event, int row, int column) {
movePointerTo(row);
}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
index 6ff6f72..28f5096c 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java
@@ -209,6 +209,10 @@
return FromTo.create(getCursor("start"), getCursor("end"));
}
+ public final native void setSelection(LineCharacter lineCh) /*-{
+ this.setSelection(lineCh);
+ }-*/;
+
public final native void setCursor(LineCharacter lineCh) /*-{
this.setCursor(lineCh);
}-*/;
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/mode/mode_map b/gerrit-gwtui/src/main/java/net/codemirror/mode/mode_map
index e448fa9..c3128f6 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/mode/mode_map
+++ b/gerrit-gwtui/src/main/java/net/codemirror/mode/mode_map
@@ -52,4 +52,5 @@
application/xml
application/x-javascript = application/javascript
+text/x-h = text/x-c++hdr
text/x-java-source = text/x-java
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
index e7524141..64d5838 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchDetailServiceImpl.java
@@ -22,36 +22,28 @@
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.patch.PatchScriptFactory;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gwtjsonrpc.common.AsyncCallback;
-import com.google.gwtjsonrpc.common.VoidResult;
-import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
-import java.util.Collections;
-
class PatchDetailServiceImpl extends BaseServiceImplementation implements
PatchDetailService {
private final PatchScriptFactory.Factory patchScriptFactoryFactory;
- private final SaveDraft.Factory saveDraftFactory;
private final ChangeControl.Factory changeControlFactory;
@Inject
PatchDetailServiceImpl(final Provider<ReviewDb> schema,
final Provider<CurrentUser> currentUser,
final PatchScriptFactory.Factory patchScriptFactoryFactory,
- final SaveDraft.Factory saveDraftFactory,
final ChangeControl.Factory changeControlFactory) {
super(schema, currentUser);
this.patchScriptFactoryFactory = patchScriptFactoryFactory;
- this.saveDraftFactory = saveDraftFactory;
this.changeControlFactory = changeControlFactory;
}
@@ -73,36 +65,4 @@
}
}.to(callback);
}
-
- public void saveDraft(final PatchLineComment comment,
- final AsyncCallback<PatchLineComment> callback) {
- saveDraftFactory.create(comment).to(callback);
- }
-
- public void deleteDraft(final PatchLineComment.Key commentKey,
- final AsyncCallback<VoidResult> callback) {
- run(callback, new Action<VoidResult>() {
- public VoidResult run(ReviewDb db) throws OrmException, Failure {
- Change.Id id = commentKey.getParentKey().getParentKey().getParentKey();
- db.changes().beginTransaction(id);
- try {
- final PatchLineComment comment = db.patchComments().get(commentKey);
- if (comment == null) {
- throw new Failure(new NoSuchEntityException());
- }
- if (!getAccountId().equals(comment.getAuthor())) {
- throw new Failure(new NoSuchEntityException());
- }
- if (comment.getStatus() != PatchLineComment.Status.DRAFT) {
- throw new Failure(new IllegalStateException("Comment published"));
- }
- db.patchComments().delete(Collections.singleton(comment));
- db.commit();
- return VoidResult.INSTANCE;
- } finally {
- db.rollback();
- }
- }
- });
- }
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchModule.java
index 4e69b14..83bfcdc 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/PatchModule.java
@@ -16,7 +16,6 @@
import com.google.gerrit.httpd.rpc.RpcServletModule;
import com.google.gerrit.httpd.rpc.UiRpcModule;
-import com.google.gerrit.server.config.FactoryModule;
public class PatchModule extends RpcServletModule {
public PatchModule() {
@@ -25,12 +24,6 @@
@Override
protected void configureServlets() {
- install(new FactoryModule() {
- @Override
- protected void configure() {
- factory(SaveDraft.Factory.class);
- }
- });
rpc(PatchDetailServiceImpl.class);
}
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/SaveDraft.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/SaveDraft.java
deleted file mode 100644
index d44a4cf..0000000
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/patch/SaveDraft.java
+++ /dev/null
@@ -1,118 +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.httpd.rpc.patch;
-
-import com.google.gerrit.httpd.rpc.Handler;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.PatchLineComment;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.ChangeUtil;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.project.ChangeControl;
-import com.google.gerrit.server.project.NoSuchChangeException;
-import com.google.gerrit.server.util.TimeUtil;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-import java.util.Collections;
-
-class SaveDraft extends Handler<PatchLineComment> {
- interface Factory {
- SaveDraft create(PatchLineComment comment);
- }
-
- private final ChangeControl.Factory changeControlFactory;
- private final ReviewDb db;
- private final IdentifiedUser currentUser;
-
- private final PatchLineComment comment;
-
- @Inject
- SaveDraft(final ChangeControl.Factory changeControlFactory,
- final ReviewDb db, final IdentifiedUser currentUser,
- @Assisted final PatchLineComment comment) {
- this.changeControlFactory = changeControlFactory;
- this.db = db;
- this.currentUser = currentUser;
- this.comment = comment;
- }
-
- @Override
- public PatchLineComment call() throws NoSuchChangeException, OrmException {
- if (comment.getStatus() != PatchLineComment.Status.DRAFT) {
- throw new IllegalStateException("Comment published");
- }
-
- final Patch.Key patchKey = comment.getKey().getParentKey();
- final PatchSet.Id patchSetId = patchKey.getParentKey();
- final Change.Id changeId = patchKey.getParentKey().getParentKey();
-
- db.changes().beginTransaction(changeId);
- try {
- changeControlFactory.validateFor(changeId);
- if (db.patchSets().get(patchSetId) == null) {
- throw new NoSuchChangeException(changeId);
- }
-
- final Account.Id me = currentUser.getAccountId();
- if (comment.getKey().get() == null) {
- if (comment.getLine() < 0) {
- throw new IllegalStateException("Comment line must be >= 0, not "
- + comment.getLine());
- }
-
- if (comment.getParentUuid() != null) {
- final PatchLineComment parent =
- db.patchComments().get(
- new PatchLineComment.Key(patchKey, comment.getParentUuid()));
- if (parent == null || parent.getSide() != comment.getSide()) {
- throw new IllegalStateException("Parent comment must be on same side");
- }
- }
- if (comment.getRange() != null
- && comment.getLine() != comment.getRange().getEndLine()) {
- throw new IllegalStateException(
- "Range endLine must be on the same line as the comment");
- }
-
- final PatchLineComment nc =
- new PatchLineComment(new PatchLineComment.Key(patchKey,
- ChangeUtil.messageUUID(db)), comment.getLine(), me,
- comment.getParentUuid(), TimeUtil.nowTs());
- nc.setSide(comment.getSide());
- nc.setMessage(comment.getMessage());
- nc.setRange(comment.getRange());
- db.patchComments().insert(Collections.singleton(nc));
- db.commit();
- return nc;
-
- } else {
- if (!me.equals(comment.getAuthor())) {
- throw new NoSuchChangeException(changeId);
- }
- comment.setWrittenOn(TimeUtil.nowTs());
- db.patchComments().update(Collections.singleton(comment));
- db.commit();
- return comment;
- }
- } finally {
- db.rollback();
- }
- }
-}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessFactory.java
index 8973132..ee4439f 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ProjectAccessFactory.java
@@ -27,10 +27,10 @@
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.NoSuchProjectException;
@@ -113,7 +113,7 @@
md.close();
}
- final RefControl metaConfigControl = pc.controlForRef(GitRepositoryManager.REF_CONFIG);
+ final RefControl metaConfigControl = pc.controlForRef(RefNames.REFS_CONFIG);
List<AccessSection> local = new ArrayList<AccessSection>();
Set<String> ownerOf = new HashSet<String>();
Map<AccountGroup.UUID, Boolean> visibleGroups = new HashMap<>();
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
index 3b1f7f2..18af5a2 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/project/ReviewProjectAccess.java
@@ -26,6 +26,7 @@
import com.google.gerrit.reviewdb.client.PatchSetAncestor;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
@@ -35,7 +36,6 @@
import com.google.gerrit.server.change.MergeabilityChecker;
import com.google.gerrit.server.change.PostReviewers;
import com.google.gerrit.server.config.AllProjectsNameProvider;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.SystemGroupBackend;
@@ -134,7 +134,7 @@
user.getAccountId(),
new Branch.NameKey(
config.getProject().getNameKey(),
- GitRepositoryManager.REF_CONFIG),
+ RefNames.REFS_CONFIG),
TimeUtil.nowTs());
ps.setCreatedOn(change.getCreatedOn());
diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK
index ffa9cf4..9f397fc 100644
--- a/gerrit-pgm/BUCK
+++ b/gerrit-pgm/BUCK
@@ -18,6 +18,7 @@
deps = [
'//gerrit-common:annotations',
'//gerrit-common:server',
+ '//gerrit-reviewdb:server',
'//gerrit-server:server',
'//lib:guava',
'//lib/guice:guice',
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/AllProjectsConfig.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/AllProjectsConfig.java
index 45ca87b..b5f0768 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/AllProjectsConfig.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/AllProjectsConfig.java
@@ -14,8 +14,8 @@
package com.google.gerrit.pgm.init;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.git.VersionedMetaData;
import com.google.inject.Inject;
@@ -59,7 +59,7 @@
@Override
protected String getRefName() {
- return GitRepositoryManager.REF_CONFIG;
+ return RefNames.REFS_CONFIG;
}
public Config load() throws IOException, ConfigInvalidException {
diff --git a/gerrit-plugin-gwt-archetype/src/main/resources/archetype-resources/src/main/java/client/HelloPlugin.java b/gerrit-plugin-gwt-archetype/src/main/resources/archetype-resources/src/main/java/client/HelloPlugin.java
index 24b8136..7a23313 100644
--- a/gerrit-plugin-gwt-archetype/src/main/resources/archetype-resources/src/main/java/client/HelloPlugin.java
+++ b/gerrit-plugin-gwt-archetype/src/main/resources/archetype-resources/src/main/java/client/HelloPlugin.java
@@ -14,7 +14,7 @@
package ${package}.client;
-import com.google.gerrit.plugin.client.Plugin;
+import com.google.gerrit.plugin.client.PluginEntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
@@ -27,10 +27,10 @@
/**
* HelloWorld Plugin.
*/
-public class HelloPlugin extends Plugin {
+public class HelloPlugin extends PluginEntryPoint {
@Override
- public void onModuleLoad() {
+ public void onPluginLoad() {
// Create the dialog box
final DialogBox dialogBox = new DialogBox();
diff --git a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
index b1ff403..e02225b 100644
--- a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
+++ b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/Plugin.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2012 The Android Open Source Project
+// Copyright (C) 2013 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.
@@ -14,21 +14,46 @@
package com.google.gerrit.plugin.client;
-import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
/**
- * Base class for writing Gerrit Web UI plugins
+ * Wrapper around the plugin instance exposed by Gerrit.
*
- * Writing a plugin:
- * <ol>
- * <li>Declare subtype of Plugin</li>
- * <li>Bind WebUiPlugin to GwtPlugin implementation in Gerrit-Module</li>
- * </ol>
+ * Listeners for events generated by the main UI must be registered
+ * through this instance.
*/
-public abstract class Plugin implements EntryPoint {
- public native static void go(String t)
- /*-{ $wnd.Gerrit.go(t) }-*/;
+public final class Plugin extends JavaScriptObject {
+ private static final Plugin self = install(
+ GWT.getModuleBaseURL() + GWT.getModuleName() + ".nocache.js");
- public native static void refresh()
- /*-{ $wnd.Gerrit.refresh() }-*/;
+ /** Obtain the plugin instance wrapper. */
+ public static Plugin get() {
+ return self;
+ }
+
+ /** Installed name of the plugin. */
+ public final String getName() {
+ return getPluginName();
+ }
+
+ /** Installed name of the plugin. */
+ public final native String getPluginName()
+ /*-{ return this.getPluginName() }-*/;
+
+ /** Navigate the UI to the screen identified by the token. */
+ public final native void go(String token)
+ /*-{ return this.go(token) }-*/;
+
+ /** Refresh the current UI. */
+ public final native void refresh()
+ /*-{ return this.refresh() }-*/;
+
+ protected Plugin() {
+ }
+
+ native void _initialized() /*-{ this._success = true }-*/;
+ native void _loaded() /*-{ this._loadedGwt() }-*/;
+ private static native final Plugin install(String u)
+ /*-{ return $wnd.Gerrit.installGwt(u) }-*/;
}
diff --git a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/PluginEntryPoint.java b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/PluginEntryPoint.java
new file mode 100644
index 0000000..ca1cdbf
--- /dev/null
+++ b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/PluginEntryPoint.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2012 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.plugin.client;
+
+import com.google.gwt.core.client.EntryPoint;
+
+/**
+ * Base class for writing Gerrit Web UI plugins
+ *
+ * Writing a plugin:
+ * <ol>
+ * <li>Declare subtype of Plugin</li>
+ * <li>Bind WebUiPlugin to GwtPlugin implementation in Gerrit-Module</li>
+ * </ol>
+ */
+public abstract class PluginEntryPoint implements EntryPoint {
+ /**
+ * The plugin entry point method, called automatically by loading
+ * a module that declares an implementing class as an entry point.
+ */
+ public abstract void onPluginLoad();
+
+ public final void onModuleLoad() {
+ Plugin self = Plugin.get();
+ try {
+ onPluginLoad();
+ self._initialized();
+ } finally {
+ self._loaded();
+ }
+ }
+}
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/PatchSet.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/PatchSet.java
index 54c556d..613978a 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/PatchSet.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/PatchSet.java
@@ -14,6 +14,8 @@
package com.google.gerrit.reviewdb.client;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_CHANGES;
+
import com.google.gwtorm.client.Column;
import com.google.gwtorm.client.IntKey;
@@ -21,8 +23,6 @@
/** A single revision of a {@link Change}. */
public final class PatchSet {
- private static final String REFS_CHANGES = "refs/changes/";
-
/** Is the reference name a change reference? */
public static boolean isRef(final String name) {
if (name == null || !name.startsWith(REFS_CHANGES)) {
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java
new file mode 100644
index 0000000..ede5c26
--- /dev/null
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2013 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.reviewdb.client;
+
+/** Constants and utilities for Gerrit-specific ref names. */
+public class RefNames {
+ public static final String REFS_CHANGES = "refs/changes/";
+
+ /** Note tree listing commits we refuse {@code refs/meta/reject-commits} */
+ public static final String REFS_REJECT_COMMITS = "refs/meta/reject-commits";
+
+ /** Configuration settings for a project {@code refs/meta/config} */
+ public static final String REFS_CONFIG = "refs/meta/config";
+
+ /** Configurations of project-specific dashboards (canned search queries). */
+ public static final String REFS_DASHBOARDS = "refs/meta/dashboards/";
+
+ /**
+ * Prefix applied to merge commit base nodes.
+ * <p>
+ * References in this directory should take the form
+ * {@code refs/cache-automerge/xx/yyyy...} where xx is
+ * the first two digits of the merge commit's object
+ * name, and yyyyy... is the remaining 38. The reference
+ * should point to a treeish that is the automatic merge
+ * result of the merge commit's parents.
+ */
+ public static final String REFS_CACHE_AUTOMERGE = "refs/cache-automerge/";
+
+ private RefNames() {
+ }
+}
diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK
index 5e992cd9..091c9b7 100644
--- a/gerrit-server/BUCK
+++ b/gerrit-server/BUCK
@@ -90,7 +90,6 @@
'//gerrit-common:server',
'//gerrit-cache-h2:cache-h2',
'//gerrit-lucene:lucene',
- '//gerrit-reviewdb:client',
'//gerrit-reviewdb:server',
'//lib:guava',
'//lib:gwtorm',
diff --git a/gerrit-server/src/main/java/com/google/gerrit/rules/PrologCompiler.java b/gerrit-server/src/main/java/com/google/gerrit/rules/PrologCompiler.java
index 4ab3442..ab57059 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/rules/PrologCompiler.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/rules/PrologCompiler.java
@@ -15,9 +15,9 @@
package com.google.gerrit.rules;
import com.google.gerrit.common.Version;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.util.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -79,7 +79,7 @@
}
public Status call() throws IOException, CompileException {
- ObjectId metaConfig = git.resolve(GitRepositoryManager.REF_CONFIG);
+ ObjectId metaConfig = git.resolve(RefNames.REFS_CONFIG);
if (metaConfig == null) {
return Status.NO_RULES;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/rules/RulesCache.java b/gerrit-server/src/main/java/com/google/gerrit/rules/RulesCache.java
index dad53b9..4a3cd9a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/rules/RulesCache.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/rules/RulesCache.java
@@ -20,6 +20,7 @@
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -66,7 +67,7 @@
* <p>
* Rules are loaded from the {@code site_path/cache/rules/rules-SHA1.jar}, where
* {@code SHA1} is the SHA1 of the Prolog {@code rules.pl} in a project's
- * {@link GitRepositoryManager#REF_CONFIG} branch.
+ * {@link RefNames#REFS_CONFIG} branch.
*/
@Singleton
public class RulesCache {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/access/ListAccess.java b/gerrit-server/src/main/java/com/google/gerrit/server/access/ListAccess.java
index 4002c1a..3a0a27d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/access/ListAccess.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/access/ListAccess.java
@@ -29,11 +29,11 @@
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.GroupJson;
@@ -154,7 +154,7 @@
public ProjectAccessInfo(ProjectControl pc, ProjectConfig config) {
final RefControl metaConfigControl =
- pc.controlForRef(GitRepositoryManager.REF_CONFIG);
+ pc.controlForRef(RefNames.REFS_CONFIG);
local = Maps.newHashMap();
ownerOf = Sets.newHashSet();
Map<AccountGroup.UUID, Boolean> visibleGroups =
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
index 23e508f..d804f38 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetRelated.java
@@ -92,7 +92,6 @@
throws OrmException, IOException {
Map<Change.Id, Change> changes = allOpenChanges(rsrc);
Map<PatchSet.Id, PatchSet> patchSets = allPatchSets(changes.keySet());
- List<ChangeAndCommit> list = children(rsrc, rw, changes, patchSets);
Map<String, PatchSet> commits = Maps.newHashMap();
for (PatchSet p : patchSets.values()) {
@@ -112,11 +111,19 @@
}
}
+ Set<Change.Id> added = Sets.newHashSet();
+ List<ChangeAndCommit> parents = Lists.newArrayList();
for (RevCommit c; (c = rw.next()) != null;) {
PatchSet p = commits.get(c.name());
- Change g = p != null ? changes.get(p.getId().getParentKey()) : null;
- list.add(new ChangeAndCommit(g, p, c));
+ Change g = null;
+ if (p != null) {
+ g = changes.get(p.getId().getParentKey());
+ added.add(p.getId().getParentKey());
+ }
+ parents.add(new ChangeAndCommit(g, p, c));
}
+ List<ChangeAndCommit> list = children(rsrc, rw, changes, patchSets, added);
+ list.addAll(parents);
if (list.size() == 1) {
ChangeAndCommit r = list.get(0);
@@ -155,7 +162,8 @@
}
private List<ChangeAndCommit> children(RevisionResource rsrc, RevWalk rw,
- Map<Change.Id, Change> changes, Map<PatchSet.Id, PatchSet> patchSets)
+ Map<Change.Id, Change> changes, Map<PatchSet.Id, PatchSet> patchSets,
+ Set<Change.Id> added)
throws OrmException, IOException {
// children is a map of parent commit name to PatchSet built on it.
Multimap<String, PatchSet.Id> children = allChildren(changes.keySet());
@@ -192,7 +200,9 @@
if (!c.has(seenCommit)) {
c.add(seenCommit);
q.addFirst(ps.getRevision().get());
- graph.add(new ChangeAndCommit(change, ps, c));
+ if (added.add(ps.getId().getParentKey())) {
+ graph.add(new ChangeAndCommit(change, ps, c));
+ }
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
index 53c6e79..c1f8598 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
@@ -28,11 +28,11 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.Mergeable.MergeableInfo;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.git.WorkQueue.Executor;
@@ -110,11 +110,11 @@
@Override
public void onGitReferenceUpdated(GitReferenceUpdatedListener.Event event) {
String ref = event.getRefName();
- if (ref.startsWith(Constants.R_HEADS) || ref.equals(GitRepositoryManager.REF_CONFIG)) {
+ if (ref.startsWith(Constants.R_HEADS) || ref.equals(RefNames.REFS_CONFIG)) {
executor.submit(new BranchUpdateTask(schemaFactory,
new Project.NameKey(event.getProjectName()), ref));
}
- if (ref.equals(GitRepositoryManager.REF_CONFIG)) {
+ if (ref.equals(RefNames.REFS_CONFIG)) {
Project.NameKey p = new Project.NameKey(event.getProjectName());
try {
ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
@@ -124,7 +124,7 @@
new ProjectUpdateTask(schemaFactory, p).call();
} catch (Exception e) {
String msg = "Failed to update mergeability flags for project " + p.get()
- + " on update of " + GitRepositoryManager.REF_CONFIG;
+ + " on update of " + RefNames.REFS_CONFIG;
log.error(msg, e);
Throwables.propagateIfPossible(e);
throw new RuntimeException(msg, e);
@@ -132,7 +132,7 @@
}
} catch (ConfigInvalidException | IOException e) {
String msg = "Failed to update mergeability flags for project " + p.get()
- + " on update of " + GitRepositoryManager.REF_CONFIG;
+ + " on update of " + RefNames.REFS_CONFIG;
log.error(msg, e);
throw new RuntimeException(msg, e);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
index d54d64a..2ee3ad0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
@@ -49,6 +49,7 @@
import com.google.gerrit.server.account.AccountsCollection;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -387,7 +388,7 @@
// User requested delete of this label.
if (c != null) {
if (c.getValue() != 0) {
- labelDelta.add("-" + normName);
+ addLabelDelta(normName, (short) 0);
}
del.add(c);
}
@@ -395,7 +396,7 @@
c.setValue(ent.getValue());
c.setGranted(timestamp);
upd.add(c);
- labelDelta.add(format(normName, c.getValue()));
+ addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
} else if (c != null && c.getValue() == ent.getValue()) {
current.put(normName, c);
@@ -407,7 +408,7 @@
ent.getValue(), TimeUtil.nowTs());
c.setGranted(timestamp);
ins.add(c);
- labelDelta.add(format(normName, c.getValue()));
+ addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
}
}
@@ -467,14 +468,8 @@
return current;
}
- private static String format(String name, short value) {
- StringBuilder sb = new StringBuilder(name.length() + 2);
- sb.append(name);
- if (value >= 0) {
- sb.append('+');
- }
- sb.append(value);
- return sb.toString();
+ private void addLabelDelta(String name, short value) {
+ labelDelta.add(new LabelVote(name, value).format());
}
private boolean insertMessage(RevisionResource rsrc, String msg)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
index 6859262..7a64155 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/BanCommit.java
@@ -14,7 +14,7 @@
package com.google.gerrit.server.git;
-import static com.google.gerrit.server.git.GitRepositoryManager.REF_REJECT_COMMITS;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_REJECT_COMMITS;
import com.google.gerrit.common.errors.PermissionDeniedException;
import com.google.gerrit.reviewdb.client.Project;
@@ -96,7 +96,7 @@
NotesBranchUtil notesBranchUtil = notesBranchUtilFactory.create(project,
repo, inserter);
NoteMap newlyCreated =
- notesBranchUtil.commitNewNotes(banCommitNotes, REF_REJECT_COMMITS,
+ notesBranchUtil.commitNewNotes(banCommitNotes, REFS_REJECT_COMMITS,
createPersonIdent(), buildCommitMessage(commitsToBan, reason));
for (Note n : banCommitNotes) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeCache.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeCache.java
index 32dc303..eb4acfc 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeCache.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ChangeCache.java
@@ -19,6 +19,7 @@
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gwtorm.server.SchemaFactory;
@@ -72,7 +73,7 @@
@Override
public void onGitReferenceUpdated(GitReferenceUpdatedListener.Event event) {
- if (event.getRefName().startsWith("refs/changes/")) {
+ if (event.getRefName().startsWith(RefNames.REFS_CHANGES)) {
cache.invalidate(new Project.NameKey(event.getProjectName()));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/GitRepositoryManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/GitRepositoryManager.java
index 0118404..ffb91ce 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/GitRepositoryManager.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/GitRepositoryManager.java
@@ -31,27 +31,6 @@
* environment.
*/
public interface GitRepositoryManager {
- /** Note tree listing commits we refuse {@code refs/meta/reject-commits} */
- public static final String REF_REJECT_COMMITS = "refs/meta/reject-commits";
-
- /** Configuration settings for a project {@code refs/meta/config} */
- public static final String REF_CONFIG = "refs/meta/config";
-
- /** Configurations of project-specific dashboards (canned search queries). */
- public static String REFS_DASHBOARDS = "refs/meta/dashboards/";
-
- /**
- * Prefix applied to merge commit base nodes.
- * <p>
- * References in this directory should take the form
- * {@code refs/cache-automerge/xx/yyyy...} where xx is
- * the first two digits of the merge commit's object
- * name, and yyyyy... is the remaining 38. The reference
- * should point to a treeish that is the automatic merge
- * result of the merge commit's parents.
- */
- public static final String REFS_CACHE_AUTOMERGE = "refs/cache-automerge/";
-
/**
* Get (or open) a repository by name.
*
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index ee610fc..16f8ee2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -39,6 +39,7 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -579,7 +580,7 @@
}
if (mergeTip != null && (branchTip == null || branchTip != mergeTip)) {
- if (GitRepositoryManager.REF_CONFIG.equals(branchUpdate.getName())) {
+ if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
try {
ProjectConfig cfg =
new ProjectConfig(destProject.getProject().getNameKey());
@@ -606,7 +607,7 @@
mergeTip);
}
- if (GitRepositoryManager.REF_CONFIG.equals(branchUpdate.getName())) {
+ if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
projectCache.evict(destProject.getProject());
destProject = projectCache.get(destProject.getProject().getNameKey());
repoManager.setProjectDescription(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 3a29587..97ae746 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -40,6 +40,7 @@
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.State;
@@ -370,7 +371,7 @@
@Override
protected String getRefName() {
- return GitRepositoryManager.REF_CONFIG;
+ return RefNames.REFS_CONFIG;
}
@Override
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectLevelConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectLevelConfig.java
index fc95608..476ccae 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectLevelConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectLevelConfig.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.git;
import com.google.common.collect.Iterables;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.project.ProjectState;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -38,7 +39,7 @@
@Override
protected String getRefName() {
- return GitRepositoryManager.REF_CONFIG;
+ return RefNames.REFS_CONFIG;
}
@Override
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 611ce52..b7b34b1 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
@@ -14,6 +14,7 @@
package com.google.gerrit.server.git;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_CHANGES;
import static com.google.gerrit.server.git.MultiProgressMonitor.UNKNOWN;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromApprovals;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
@@ -58,6 +59,7 @@
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
@@ -156,8 +158,8 @@
private static final Logger log =
LoggerFactory.getLogger(ReceiveCommits.class);
- public static final Pattern NEW_PATCHSET =
- Pattern.compile("^refs/changes/(?:[0-9][0-9]/)?([1-9][0-9]*)(?:/new)?$");
+ public static final Pattern NEW_PATCHSET = Pattern.compile(
+ "^" + REFS_CHANGES + "(?:[0-9][0-9]/)?([1-9][0-9]*)(?:/new)?$");
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
@@ -168,12 +170,12 @@
private enum Error {
CONFIG_UPDATE("You are not allowed to perform this operation.\n"
+ "Configuration changes can only be pushed by project owners\n"
- + "who also have 'Push' rights on " + GitRepositoryManager.REF_CONFIG),
+ + "who also have 'Push' rights on " + RefNames.REFS_CONFIG),
UPDATE("You are not allowed to perform this operation.\n"
+ "To push into this reference you need 'Push' rights."),
DELETE("You need 'Push' rights with the 'Force Push'\n"
+ "flag set to delete references."),
- DELETE_CHANGES("Cannot delete from 'refs/changes'"),
+ DELETE_CHANGES("Cannot delete from '" + REFS_CHANGES + "'"),
CODE_REVIEW("You need 'Push' rights to upload code review requests.\n"
+ "Verify that you are pushing to the right branch.");
@@ -397,8 +399,8 @@
Map<String, Ref> filteredRefs = Maps.newHashMapWithExpectedSize(refs.size());
for (Map.Entry<String, Ref> e : refs.entrySet()) {
String name = e.getKey();
- if (!name.startsWith("refs/changes/")
- && !name.startsWith(GitRepositoryManager.REFS_CACHE_AUTOMERGE)) {
+ if (!name.startsWith(REFS_CHANGES)
+ && !name.startsWith(RefNames.REFS_CACHE_AUTOMERGE)) {
filteredRefs.put(name, e.getValue());
}
}
@@ -914,8 +916,8 @@
validateNewCommits(ctl, cmd);
batch.addCommand(cmd);
} else {
- if (GitRepositoryManager.REF_CONFIG.equals(ctl.getRefName())) {
- errors.put(Error.CONFIG_UPDATE, GitRepositoryManager.REF_CONFIG);
+ if (RefNames.REFS_CONFIG.equals(ctl.getRefName())) {
+ errors.put(Error.CONFIG_UPDATE, RefNames.REFS_CONFIG);
} else {
errors.put(Error.UPDATE, ctl.getRefName());
}
@@ -944,13 +946,13 @@
private void parseDelete(final ReceiveCommand cmd) {
RefControl ctl = projectControl.controlForRef(cmd.getRefName());
- if (ctl.getRefName().startsWith("refs/changes/")) {
+ if (ctl.getRefName().startsWith(REFS_CHANGES)) {
errors.put(Error.DELETE_CHANGES, ctl.getRefName());
reject(cmd, "cannot delete changes");
} else if (ctl.canDelete()) {
batch.addCommand(cmd);
} else {
- if (GitRepositoryManager.REF_CONFIG.equals(ctl.getRefName())) {
+ if (RefNames.REFS_CONFIG.equals(ctl.getRefName())) {
reject(cmd, "cannot delete project configuration");
} else {
errors.put(Error.DELETE, ctl.getRefName());
@@ -1222,7 +1224,7 @@
*/
private NoteMap loadRejectCommitsMap() throws IOException {
try {
- Ref ref = repo.getRef(GitRepositoryManager.REF_REJECT_COMMITS);
+ Ref ref = repo.getRef(RefNames.REFS_REJECT_COMMITS);
if (ref == null) {
return NoteMap.newEmptyMap();
}
@@ -1232,7 +1234,7 @@
return NoteMap.read(rw.getObjectReader(), map);
} catch (IOException badMap) {
throw new IOException("Cannot load "
- + GitRepositoryManager.REF_REJECT_COMMITS, badMap);
+ + RefNames.REFS_REJECT_COMMITS, badMap);
}
}
@@ -1424,7 +1426,7 @@
for (Ref ref : allRefs.values()) {
if (ref.getObjectId() == null) {
continue;
- } else if (ref.getName().startsWith("refs/changes/")) {
+ } else if (ref.getName().startsWith(REFS_CHANGES)) {
existing.add(ref.getObjectId());
} else if (ref.getName().startsWith(R_HEADS)
|| (forRef != null && forRef.equals(ref.getName()))) {
@@ -1708,6 +1710,7 @@
if (newCommit == priorCommit) {
// Ignore requests to make the change its current state.
skip = true;
+ reject(inputCommand, "commit already exists");
return false;
}
@@ -2057,7 +2060,7 @@
&& ctl.canUploadMerges()
&& !projectControl.getProjectState().isUseSignedOffBy()
&& Iterables.isEmpty(rejectCommits)
- && !GitRepositoryManager.REF_CONFIG.equals(ctl.getRefName())
+ && !RefNames.REFS_CONFIG.equals(ctl.getRefName())
&& !(MagicBranch.isMagicBranch(cmd.getRefName())
|| NEW_PATCHSET.matcher(cmd.getRefName()).matches())) {
return;
@@ -2233,7 +2236,7 @@
private SetMultimap<ObjectId, Ref> changeRefsById() throws IOException {
if (refsById == null) {
refsById = HashMultimap.create();
- for (Ref r : repo.getRefDatabase().getRefs("refs/changes/").values()) {
+ for (Ref r : repo.getRefDatabase().getRefs(REFS_CHANGES).values()) {
if (PatchSet.isRef(r.getName())) {
refsById.put(r.getObjectId(), r);
}
@@ -2340,6 +2343,6 @@
}
private static boolean isConfig(final ReceiveCommand cmd) {
- return cmd.getRefName().equals(GitRepositoryManager.REF_CONFIG);
+ return cmd.getRefName().equals(RefNames.REFS_CONFIG);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommitsAdvertiseRefsHook.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommitsAdvertiseRefsHook.java
index f34ce8b..7ae8271 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommitsAdvertiseRefsHook.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommitsAdvertiseRefsHook.java
@@ -21,6 +21,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.util.MagicBranch;
import com.google.gwtorm.server.OrmException;
@@ -164,8 +165,8 @@
}
private static boolean skip(String name) {
- return name.startsWith("refs/changes/")
- || name.startsWith(GitRepositoryManager.REFS_CACHE_AUTOMERGE)
+ return name.startsWith(RefNames.REFS_CHANGES)
+ || name.startsWith(RefNames.REFS_CACHE_AUTOMERGE)
|| MagicBranch.isMagicBranch(name);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/VisibleRefFilter.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/VisibleRefFilter.java
index 14aae94..343b49c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/VisibleRefFilter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/VisibleRefFilter.java
@@ -19,9 +19,11 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gwtorm.server.OrmException;
+
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
@@ -68,9 +70,9 @@
public Map<String, Ref> filter(Map<String, Ref> refs, boolean filterTagsSeperately) {
if (projectCtl.allRefsAreVisibleExcept(
- ImmutableSet.of(GitRepositoryManager.REF_CONFIG))) {
+ ImmutableSet.of(RefNames.REFS_CONFIG))) {
Map<String, Ref> r = Maps.newHashMap(refs);
- r.remove(GitRepositoryManager.REF_CONFIG);
+ r.remove(RefNames.REFS_CONFIG);
return r;
}
@@ -79,7 +81,7 @@
final List<Ref> deferredTags = new ArrayList<Ref>();
for (Ref ref : refs.values()) {
- if (ref.getName().startsWith(GitRepositoryManager.REFS_CACHE_AUTOMERGE)) {
+ if (ref.getName().startsWith(RefNames.REFS_CACHE_AUTOMERGE)) {
continue;
} else if (PatchSet.isRef(ref.getName())) {
// Reference to a patch set is visible if the change is visible.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
index 05dbf0e..3c6c9ea 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -18,12 +18,12 @@
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.registration.DynamicSet;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.events.CommitReceivedEvent;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.git.ReceiveCommits;
import com.google.gerrit.server.git.ValidationError;
@@ -311,7 +311,7 @@
CommitReceivedEvent receiveEvent) throws CommitValidationException {
IdentifiedUser currentUser = (IdentifiedUser) refControl.getCurrentUser();
- if (GitRepositoryManager.REF_CONFIG.equals(refControl.getRefName())) {
+ if (RefNames.REFS_CONFIG.equals(refControl.getRefName())) {
List<CommitValidationMessage> messages =
new LinkedList<CommitValidationMessage>();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
index 6eed909..0370d36 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
@@ -22,12 +22,12 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CommitMergeStatus;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
@@ -96,7 +96,7 @@
final Branch.NameKey destBranch,
final PatchSet.Id patchSetId)
throws MergeValidationException {
- if (GitRepositoryManager.REF_CONFIG.equals(destBranch.get())) {
+ if (RefNames.REFS_CONFIG.equals(destBranch.get())) {
final Project.NameKey newParent;
try {
ProjectConfig cfg =
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
index 7d521f2..2cda334 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
@@ -18,6 +18,7 @@
import com.google.common.cache.CacheLoader;
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
@@ -249,7 +250,7 @@
public static RevTree automerge(Repository repo, RevWalk rw, RevCommit b,
boolean save) throws IOException {
String hash = b.name();
- String refName = GitRepositoryManager.REFS_CACHE_AUTOMERGE
+ String refName = RefNames.REFS_CACHE_AUTOMERGE
+ hash.substring(0, 2)
+ "/"
+ hash.substring(2);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java
index 6e5ef65..3df8e2f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/DashboardsCollection.java
@@ -14,7 +14,7 @@
package com.google.gerrit.server.project;
-import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetDashboard.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetDashboard.java
index fcd2284..8acc29e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetDashboard.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetDashboard.java
@@ -14,7 +14,7 @@
package com.google.gerrit.server.project;
-import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListBranches.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListBranches.java
index 7ed5b5f..92f71e5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListBranches.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListBranches.java
@@ -18,6 +18,7 @@
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
@@ -115,7 +116,7 @@
if (refControl.isVisible()) {
if (ref.getName().startsWith(Constants.R_HEADS)) {
branches.add(createBranchInfo(ref, refControl, targets));
- } else if (GitRepositoryManager.REF_CONFIG.equals(ref.getName())) {
+ } else if (RefNames.REFS_CONFIG.equals(ref.getName())) {
configBranch = createBranchInfo(ref, refControl, targets);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListDashboards.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListDashboards.java
index e3247fc..fbfcc8f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListDashboards.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListDashboards.java
@@ -14,7 +14,7 @@
package com.google.gerrit.server.project;
-import static com.google.gerrit.server.git.GitRepositoryManager.REFS_DASHBOARDS;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
index 3d3943c..6cfc7b4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
@@ -26,6 +26,7 @@
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.OutputFormat;
import com.google.gerrit.server.StringUtil;
@@ -85,7 +86,7 @@
Ref head = git.getRef(Constants.HEAD);
return head != null
&& head.isSymbolic()
- && GitRepositoryManager.REF_CONFIG.equals(head.getLeaf().getName());
+ && RefNames.REFS_CONFIG.equals(head.getLeaf().getName());
}
},
ALL {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java
index 8a6303f..ca006de 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PerformCreateProject.java
@@ -26,6 +26,7 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
@@ -109,7 +110,7 @@
final Project.NameKey nameKey = createProjectArgs.getProject();
try {
final String head =
- createProjectArgs.permissionsOnly ? GitRepositoryManager.REF_CONFIG
+ createProjectArgs.permissionsOnly ? RefNames.REFS_CONFIG
: createProjectArgs.branch.get(0);
final Repository repo = repoManager.createRepository(nameKey);
try {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
index cbb56b3..3b6ce91 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
@@ -27,6 +27,7 @@
import com.google.inject.Singleton;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -59,22 +60,23 @@
* priority order (project specific definitions must appear before
* inherited ones).
* @param ref reference being accessed.
- * @param username if the reference is a per-user reference, access sections
- * using the parameter variable "${username}" will first have {@code
- * username} inserted into them before seeing if they apply to the
- * reference named by {@code ref}. If null, per-user references are
- * ignored.
+ * @param usernames if the reference is a per-user reference, access sections
+ * using the parameter variable "${username}" will first have each of
+ * {@code usernames} inserted into them before seeing if they apply to
+ * the reference named by {@code ref}. If null or empty, per-user
+ * references are ignored.
* @return map of permissions that apply to this reference, keyed by
* permission name.
*/
PermissionCollection filter(Iterable<SectionMatcher> matcherList,
- String ref, String username) {
+ String ref, Collection<String> usernames) {
if (isRE(ref)) {
ref = RefControl.shortestExample(ref);
} else if (ref.endsWith("/*")) {
ref = ref.substring(0, ref.length() - 1);
}
+ boolean hasUsernames = usernames != null && !usernames.isEmpty();
boolean perUser = false;
Map<AccessSection, Project.NameKey> sectionToProject = Maps.newLinkedHashMap();
for (SectionMatcher sm : matcherList) {
@@ -90,12 +92,17 @@
// that will never be shared with non-user references, and the per-user
// references are usually less frequent than the non-user references.
//
- if (username != null && !perUser
- && sm.matcher instanceof RefPatternMatcher.ExpandParameters) {
- perUser = ((RefPatternMatcher.ExpandParameters) sm.matcher).matchPrefix(ref);
- }
-
- if (sm.match(ref, username)) {
+ if (hasUsernames) {
+ if (!perUser && sm.matcher instanceof RefPatternMatcher.ExpandParameters) {
+ perUser = ((RefPatternMatcher.ExpandParameters) sm.matcher).matchPrefix(ref);
+ }
+ for (String username : usernames) {
+ if (sm.match(ref, username)) {
+ sectionToProject.put(sm.section, sm.project);
+ break;
+ }
+ }
+ } else if (sm.match(ref, null)) {
sectionToProject.put(sm.section, sm.project);
}
}
@@ -140,21 +147,20 @@
}
}
- return new PermissionCollection(permissions, ruleProps,
- perUser ? username : null);
+ return new PermissionCollection(permissions, ruleProps, perUser);
}
}
private final Map<String, List<PermissionRule>> rules;
private final Map<PermissionRule, ProjectRef> ruleProps;
- private final String username;
+ private final boolean perUser;
private PermissionCollection(Map<String, List<PermissionRule>> rules,
Map<PermissionRule, ProjectRef> ruleProps,
- String username) {
+ boolean perUser) {
this.rules = rules;
this.ruleProps = ruleProps;
- this.username = username;
+ this.perUser = perUser;
}
/**
@@ -162,7 +168,7 @@
* this collection, making the results user specific.
*/
public boolean isUserSpecific() {
- return username != null;
+ return perUser;
}
/**
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
index 30cfc2b..1156677 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.project;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.PageLinks;
@@ -191,8 +192,15 @@
}
RefControl ctl = refControls.get(refName);
if (ctl == null) {
+ ImmutableList.Builder<String> usernames = ImmutableList.<String> builder();
+ if (user.getUserName() != null) {
+ usernames.add(user.getUserName());
+ }
+ if (user instanceof IdentifiedUser) {
+ usernames.addAll(((IdentifiedUser) user).getEmailAddresses());
+ }
PermissionCollection relevant =
- permissionFilter.filter(access(), refName, user.getUserName());
+ permissionFilter.filter(access(), refName, usernames.build());
ctl = new RefControl(this, refName, relevant);
refControls.put(refName, ctl);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
index 2e79e2f..eceb509 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java
@@ -30,6 +30,7 @@
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.RulesCache;
@@ -164,7 +165,7 @@
try {
Repository git = gitMgr.openRepository(getProject().getNameKey());
try {
- Ref ref = git.getRef(GitRepositoryManager.REF_CONFIG);
+ Ref ref = git.getRef(RefNames.REFS_CONFIG);
if (ref == null || ref.getObjectId() == null) {
return true;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
index 0397748..5b21532 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
@@ -23,10 +23,10 @@
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.common.errors.InvalidNameException;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.InternalUser;
-import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.group.SystemGroupBackend;
import dk.brics.automaton.RegExp;
@@ -161,7 +161,7 @@
/** @return true if this user can submit patch sets to this ref */
public boolean canSubmit() {
- if (GitRepositoryManager.REF_CONFIG.equals(refName)) {
+ if (RefNames.REFS_CONFIG.equals(refName)) {
// Always allow project owners to submit configuration changes.
// Submitting configuration changes modifies the access control
// rules. Allowing this to be done by a non-project-owner opens
@@ -175,7 +175,7 @@
/** @return true if the user can update the reference as a fast-forward. */
public boolean canUpdate() {
- if (GitRepositoryManager.REF_CONFIG.equals(refName)
+ if (RefNames.REFS_CONFIG.equals(refName)
&& !projectControl.isOwner()) {
// Pushing requires being at least project owner, in addition to push.
// Pushing configuration changes modifies the access control
@@ -211,7 +211,7 @@
}
private boolean canPushWithForce() {
- if (!canWrite() || (GitRepositoryManager.REF_CONFIG.equals(refName)
+ if (!canWrite() || (RefNames.REFS_CONFIG.equals(refName)
&& !projectControl.isOwner())) {
// Pushing requires being at least project owner, in addition to push.
// Pushing configuration changes modifies the access control
@@ -294,7 +294,7 @@
* @return {@code true} if the user specified can delete a Git ref.
*/
public boolean canDelete() {
- if (!canWrite() || (GitRepositoryManager.REF_CONFIG.equals(refName))) {
+ if (!canWrite() || (RefNames.REFS_CONFIG.equals(refName))) {
// Never allow removal of the refs/meta/config branch.
// Deleting the branch would destroy all Gerrit specific
// metadata about the project, including its access rules.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
index 0c8ecb8..dcf6841 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
@@ -105,7 +105,7 @@
String u;
if (isRE(template.getPattern())) {
- u = username.replace(".", "\\.");
+ u = Pattern.quote(username);
} else {
u = username;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
index b3ea6b4..4674cf4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/LabelPredicate.java
@@ -23,6 +23,7 @@
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.OrPredicate;
import com.google.gerrit.server.query.Predicate;
+import com.google.gerrit.server.util.LabelVote;
import com.google.inject.Provider;
import java.util.List;
@@ -75,25 +76,39 @@
ProjectCache projectCache, ChangeControl.GenericFactory ccFactory,
IdentifiedUser.GenericFactory userFactory, Provider<ReviewDb> dbProvider,
String value, Set<Account.Id> accounts, AccountGroup.UUID group) {
- String label;
- Test test;
- int expVal;
- Matcher m1 = Pattern.compile("(=|>=|<=)([+-]?\\d+)$").matcher(value);
- Matcher m2 = Pattern.compile("([+-]\\d+)$").matcher(value);
- if (m1.find()) {
- label = value.substring(0, m1.start());
- test = Test.op(m1.group(1));
- expVal = value(m1.group(2));
+ String label = null;
+ Test test = null;
+ int expVal = 0;
- } else if (m2.find()) {
- label = value.substring(0, m2.start());
+ try {
+ LabelVote v = LabelVote.parse(value);
test = Test.EQ;
- expVal = value(m2.group(1));
+ label = v.getLabel();
+ expVal = v.getValue();
+ } catch (IllegalArgumentException e) {
+ // Try next format.
+ }
- } else {
- label = value;
+ try {
+ LabelVote v = LabelVote.parseWithEquals(value);
test = Test.EQ;
- expVal = 1;
+ label = v.getLabel();
+ expVal = v.getValue();
+ } catch (IllegalArgumentException e) {
+ // Try next format.
+ }
+
+ if (label == null) {
+ Matcher m = Pattern.compile("(>=|<=)([+-]?\\d+)$").matcher(value);
+ if (m.find()) {
+ label = value.substring(0, m.start());
+ test = Test.op(m.group(1));
+ expVal = value(m.group(2));
+ } else {
+ label = value;
+ test = Test.EQ;
+ expVal = 1;
+ }
}
List<Predicate<ChangeData>> r = Lists.newArrayListWithCapacity(2 * MAX_LABEL_VALUE);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java
index 6c4569b..99ed71f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/AllProjectsCreator.java
@@ -29,6 +29,7 @@
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.config.AllProjectsName;
@@ -97,7 +98,7 @@
initAllProjects(git);
RefUpdate u = git.updateRef(Constants.HEAD);
- u.link(GitRepositoryManager.REF_CONFIG);
+ u.link(RefNames.REFS_CONFIG);
} catch (RepositoryNotFoundException err) {
String name = allProjectsName.get();
throw new IOException("Cannot create repository " + name, err);
@@ -131,7 +132,7 @@
AccessSection all = config.getAccessSection(AccessSection.ALL, true);
AccessSection heads = config.getAccessSection(AccessSection.HEADS, true);
AccessSection tags = config.getAccessSection("refs/tags/*", true);
- AccessSection meta = config.getAccessSection(GitRepositoryManager.REF_CONFIG, true);
+ AccessSection meta = config.getAccessSection(RefNames.REFS_CONFIG, true);
AccessSection magic = config.getAccessSection("refs/for/" + AccessSection.ALL, true);
grant(config, cap, GlobalCapability.ADMINISTRATE_SERVER, admin);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_53.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_53.java
index e5f6992..cbcda9f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_53.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_53.java
@@ -32,6 +32,7 @@
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
@@ -186,7 +187,7 @@
// Grant out read on the config branch by default.
//
if (config.getProject().getNameKey().equals(systemConfig.wildProjectName)) {
- AccessSection meta = config.getAccessSection(GitRepositoryManager.REF_CONFIG, true);
+ AccessSection meta = config.getAccessSection(RefNames.REFS_CONFIG, true);
Permission read = meta.getPermission(READ, true);
read.getRule(config.resolve(projectOwners), true);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_56.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_56.java
index 3ba77ec..bcd5f40 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_56.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_56.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.schema;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
@@ -44,8 +45,8 @@
keysOne = new HashSet<String>();
keysTwo = new HashSet<String>();
- keysOne.add(GitRepositoryManager.REF_CONFIG);
- keysTwo.add(GitRepositoryManager.REF_CONFIG);
+ keysOne.add(RefNames.REFS_CONFIG);
+ keysTwo.add(RefNames.REFS_CONFIG);
keysTwo.add(Constants.HEAD);
}
@@ -73,10 +74,10 @@
try {
RefUpdate update = git.updateRef(Constants.HEAD);
update.disableRefLog();
- update.link(GitRepositoryManager.REF_CONFIG);
+ update.link(RefNames.REFS_CONFIG);
} catch (IOException err) {
ui.message("warning: " + name.get() + ": Cannot update HEAD to "
- + GitRepositoryManager.REF_CONFIG + ": " + err.getMessage());
+ + RefNames.REFS_CONFIG + ": " + err.getMessage());
}
}
} finally {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/util/LabelVote.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/LabelVote.java
new file mode 100644
index 0000000..b8d942d
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/LabelVote.java
@@ -0,0 +1,109 @@
+// Copyright (C) 2013 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 com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+import com.google.gerrit.common.data.LabelType;
+
+/** A single vote on a label, consisting of a label name and a value. */
+public class LabelVote {
+ public static LabelVote parse(String text) {
+ checkArgument(!Strings.isNullOrEmpty(text), "Empty label vote");
+ if (text.charAt(0) == '-') {
+ return new LabelVote(text.substring(1), (short) 0);
+ }
+ short sign = 0;
+ int i;
+ for (i = text.length() - 1; i >= 0; i--) {
+ int c = text.charAt(i);
+ if (c == '-') {
+ sign = (short) -1;
+ break;
+ } else if (c == '+') {
+ sign = (short) 1;
+ break;
+ } else if (!('0' <= c && c <= '9')) {
+ break;
+ }
+ }
+ if (sign == 0) {
+ return new LabelVote(text, (short) 1);
+ }
+ return new LabelVote(text.substring(0, i),
+ (short)(sign * Short.parseShort(text.substring(i + 1))));
+ }
+
+ public static LabelVote parseWithEquals(String text) {
+ checkArgument(!Strings.isNullOrEmpty(text), "Empty label vote");
+ int e = text.lastIndexOf('=');
+ checkArgument(e >= 0, "Label vote missing '=': %s", text);
+ return new LabelVote(text.substring(0, e),
+ Short.parseShort(text.substring(e + 1), text.length()));
+ }
+
+ private final String name;
+ private final short value;
+
+ public LabelVote(String name, short value) {
+ this.name = LabelType.checkName(name);
+ this.value = value;
+ }
+
+ public String getLabel() {
+ return name;
+ }
+
+ public short getValue() {
+ return value;
+ }
+
+ public String format() {
+ if (value == (short) 0) {
+ return '-' + name;
+ } else if (value == (short) 1) {
+ return name;
+ } else if (value < 0) {
+ return name + value;
+ } else {
+ return name + '+' + value;
+ }
+ }
+
+ public String formatWithEquals() {
+ if (value <= (short) 0) {
+ return name + '=' + value;
+ } else {
+ return name + "=+" + value;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof LabelVote) {
+ LabelVote l = (LabelVote) o;
+ return Objects.equal(name, l.name)
+ && value == l.value;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return format();
+ }
+}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
index 0d5207a..1a9f74b 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
@@ -28,6 +28,7 @@
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -208,12 +209,12 @@
md.setMessage("Edit\n");
cfg.commit(md);
- Ref ref = db.getRef(GitRepositoryManager.REF_CONFIG);
+ Ref ref = db.getRef(RefNames.REFS_CONFIG);
return util.getRevWalk().parseCommit(ref.getObjectId());
}
private void update(RevCommit rev) throws Exception {
- RefUpdate u = db.updateRef(GitRepositoryManager.REF_CONFIG);
+ RefUpdate u = db.updateRef(RefNames.REFS_CONFIG);
u.disableRefLog();
u.setNewObjectId(rev);
switch (u.forceUpdate()) {
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
index 64ce398..594580f 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
@@ -247,6 +247,18 @@
}
@Test
+ public void testUsernameEmailPatternWithRegex() {
+ grant(local, READ, DEVS, "^refs/sb/${username}/heads/.*");
+
+ ProjectControl u = util.user(local, "d.v@ger-rit.org", DEVS);
+ ProjectControl d = util.user(local, "dev@ger-rit.org", DEVS);
+ assertFalse("u can't read",
+ u.controlForRef("refs/sb/dev@ger-rit.org/heads/foobar").isVisible());
+ assertTrue("d can read",
+ d.controlForRef("refs/sb/dev@ger-rit.org/heads/foobar").isVisible());
+ }
+
+ @Test
public void testSortWithRegex() {
grant(local, READ, DEVS, "^refs/heads/.*");
grant(util.getParentConfig(), READ, ANONYMOUS_USERS, "^refs/heads/.*-QA-.*");
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/util/LabelVoteTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/util/LabelVoteTest.java
new file mode 100644
index 0000000..d7ae61a
--- /dev/null
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/util/LabelVoteTest.java
@@ -0,0 +1,90 @@
+// Copyright (C) 2013 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.assertEquals;
+
+import org.junit.Test;
+
+public class LabelVoteTest {
+ @Test
+ public void parse() {
+ LabelVote l;
+ l = LabelVote.parse("Code-Review-2");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) -2, l.getValue());
+ l = LabelVote.parse("Code-Review-1");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) -1, l.getValue());
+ l = LabelVote.parse("-Code-Review");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 0, l.getValue());
+ l = LabelVote.parse("Code-Review");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 1, l.getValue());
+ l = LabelVote.parse("Code-Review+2");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 2, l.getValue());
+ }
+
+ @Test
+ public void format() {
+ assertEquals("Code-Review-2", LabelVote.parse("Code-Review-2").format());
+ assertEquals("Code-Review-1", LabelVote.parse("Code-Review-1").format());
+ assertEquals("-Code-Review", LabelVote.parse("-Code-Review").format());
+ assertEquals("Code-Review", LabelVote.parse("Code-Review").format());
+ assertEquals("Code-Review+2", LabelVote.parse("Code-Review+2").format());
+ }
+
+ @Test
+ public void parseWithEquals() {
+ LabelVote l;
+ l = LabelVote.parseWithEquals("Code-Review=-2");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) -2, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=-1");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) -1, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=0");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 0, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=1");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 1, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=+1");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 1, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=2");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 2, l.getValue());
+ l = LabelVote.parseWithEquals("Code-Review=+2");
+ assertEquals("Code-Review", l.getLabel());
+ assertEquals((short) 2, l.getValue());
+ }
+
+ @Test
+ public void formatWithEquals() {
+ assertEquals("Code-Review=-2",
+ LabelVote.parseWithEquals("Code-Review=-2").formatWithEquals());
+ assertEquals("Code-Review=-1",
+ LabelVote.parseWithEquals("Code-Review=-1").formatWithEquals());
+ assertEquals("Code-Review=0",
+ LabelVote.parseWithEquals("Code-Review=0").formatWithEquals());
+ assertEquals("Code-Review=+1",
+ LabelVote.parseWithEquals("Code-Review=+1").formatWithEquals());
+ assertEquals("Code-Review=+2",
+ LabelVote.parseWithEquals("Code-Review=+2").formatWithEquals());
+ }
+}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
index a257a97..8837eec 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ReviewCommand.java
@@ -14,9 +14,7 @@
package com.google.gerrit.sshd.commands;
-import com.google.common.base.Splitter;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
@@ -41,6 +39,7 @@
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.util.cli.CmdLineParser;
@@ -117,18 +116,8 @@
@Option(name = "--label", aliases = "-l", usage = "custom label(s) to assign", metaVar = "LABEL=VALUE")
void addLabel(final String token) {
- List<String> parts = ImmutableList.copyOf(Splitter.on('=').split(token));
- if (parts.size() != 2) {
- throw new IllegalArgumentException("invalid custom label " + token);
- }
- short value;
- try {
- value = Short.parseShort(parts.get(1));
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("invalid custom label value "
- + parts.get(1));
- }
- customLabels.put(parts.get(0), value);
+ LabelVote v = LabelVote.parse(token);
+ customLabels.put(v.getLabel(), v.getValue());
}
@Inject
diff --git a/lib/BUCK b/lib/BUCK
index 2469692..9902422 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -24,9 +24,9 @@
maven_jar(
name = 'gwtorm',
- id = 'gwtorm:gwtorm:1.7',
- bin_sha1 = 'ee3b316a023f1422dd4b6654a3d51d0e5690809c',
- src_sha1 = 'a145bde4cc87a4ff4cec283880e2a03be32cc868',
+ id = 'gwtorm:gwtorm:1.8',
+ bin_sha1 = '0ec006f69f7b8aa48e22d4bdecea820fd53c0b4b',
+ src_sha1 = 'b0e347a3053328f029c93ac347a4761a98293073',
license = 'Apache2.0',
deps = [':protobuf'],
repository = GERRIT,
@@ -34,9 +34,9 @@
maven_jar(
name = 'gwtjsonrpc',
- id = 'gwtjsonrpc:gwtjsonrpc:1.3',
- bin_sha1 = '1717ba11ab0c5160798c80085220a63f864691d3',
- src_sha1 = '9e01c5d7bd54f8e70066450b372a43c16404789e',
+ id = 'gwtjsonrpc:gwtjsonrpc:1.4',
+ bin_sha1 = '7500577cbf3afc3395ce15a2f5bccc4b02b0d497',
+ src_sha1 = '589e8eeb4663ee7ba330275ccfac2d6b2c6f28db',
license = 'Apache2.0',
repository = GERRIT,
)
diff --git a/plugins/cookbook-plugin b/plugins/cookbook-plugin
index 701846c..9160d60 160000
--- a/plugins/cookbook-plugin
+++ b/plugins/cookbook-plugin
@@ -1 +1 @@
-Subproject commit 701846c29e3ebbc32199ce1f24767ccb8a875ce6
+Subproject commit 9160d607f4134cc9ee1165dea56b98a5452fe8de
diff --git a/plugins/download-commands b/plugins/download-commands
index fe2bc6b..6287d6a 160000
--- a/plugins/download-commands
+++ b/plugins/download-commands
@@ -1 +1 @@
-Subproject commit fe2bc6be5ef964a5df247a85f82c0155dc2f8876
+Subproject commit 6287d6a8941f68ba8a3a8c27f2a979c02ede489a
diff --git a/plugins/replication b/plugins/replication
index 400f47b..330228e 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 400f47b99183a9141a192956bac6863f1c2fc14d
+Subproject commit 330228ed74629db4ed43e48d2d10925c0d7d2ff8