Merge branch 'stable-2.5'

* stable-2.5:
  Describe submit filter in the prolog-cookbook.
  Write a Cookbook for Prolog submit rules
  Fix message if pushing tag is rejected because tagger is somebody else
  Make commands to download patch sets configurable
  Show dependency list when change is needed by a draft change
  Create a draft patch set when a draft patch set is rebased
  Allow users of ChangeTable to control styling of change rows
  Fix displaying of file diff if draft patch has been deleted
  set-account command: Do not close ReviewDb that was injected
  Update HTTP password from SSH commands.
This commit is contained in:
Shawn O. Pearce 2012-09-17 09:47:21 -07:00
commit 4606d62a81
11 changed files with 179 additions and 65 deletions

View File

@ -1012,6 +1012,10 @@ Default is `30 seconds`.
----
[download]
command = checkout
command = cherry_pick
command = pull
command = format_patch
scheme = ssh
scheme = http
scheme = anon_http
@ -1021,6 +1025,34 @@ Default is `30 seconds`.
The download section configures the allowed download methods.
[[download.command]]download.command::
+
Commands that should be offered to download changes.
+
Multiple commands are supported:
+
* `checkout`
+
Command to fetch and checkout the patch set.
+
* `cherry_pick`
+
Command to fetch the patch set and to cherry-pick it onto the current
commit.
+
* `pull`
+
Command to pull the patch set.
+
* `format_patch`
+
Command to fetch the patch set and to feed it into the `format-patch`
command.
+
If `download.command` is not specified, all download commands are
offered.
[[download.scheme]]download.scheme::
+
Schemes that should be used to download changes.
@ -1053,7 +1085,7 @@ generally worked on with the repo multi-repository tool. This is
not default, as not all instances will deploy repo.
+
If download.scheme is not specified, SSH, HTTP and Anonymous HTTP
If `download.scheme` is not specified, SSH, HTTP and Anonymous HTTP
downloads are allowed.
[[gerrit]]Section gerrit

View File

@ -17,6 +17,7 @@ package com.google.gerrit.common.data;
import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Account.FieldName;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.client.Project;
@ -38,6 +39,7 @@ public class GerritConfig implements Cloneable {
protected boolean allowRegisterNewEmail;
protected AuthType authType;
protected Set<DownloadScheme> downloadSchemes;
protected Set<DownloadCommand> downloadCommands;
protected String gitDaemonUrl;
protected String gitHttpUrl;
protected String sshdAddress;
@ -114,6 +116,14 @@ public class GerritConfig implements Cloneable {
downloadSchemes = s;
}
public Set<DownloadCommand> getDownloadCommands() {
return downloadCommands;
}
public void setDownloadCommands(final Set<DownloadCommand> downloadCommands) {
this.downloadCommands = downloadCommands;
}
public GitwebConfig getGitwebLink() {
return gitweb;
}

View File

@ -183,6 +183,23 @@ public class ChangeScreen extends Screen
}
};
dependsOn = new ChangeTable.Section(Util.C.changeScreenDependsOn());
dependsOn.setChangeRowFormatter(new ChangeTable.ChangeRowFormatter() {
@Override
public String getRowStyle(ChangeInfo c) {
if (! c.isLatest() || Change.Status.ABANDONED.equals(c.getStatus())) {
return Gerrit.RESOURCES.css().outdated();
}
return null;
}
@Override
public String getDisplayText(final ChangeInfo c, final String displayText) {
if (! c.isLatest()) {
return displayText + " [OUTDATED]";
}
return displayText;
}
});
neededBy = new ChangeTable.Section(Util.C.changeScreenNeededBy());
dependencies.addSection(dependsOn);
dependencies.addSection(neededBy);
@ -310,7 +327,8 @@ public class ChangeScreen extends Screen
if (detail.getNeededBy() != null) {
for (final ChangeInfo ci : detail.getNeededBy()) {
if ((ci.getStatus() == Change.Status.NEW) ||
(ci.getStatus() == Change.Status.SUBMITTED)) {
(ci.getStatus() == Change.Status.SUBMITTED) ||
(ci.getStatus() == Change.Status.DRAFT)) {
depsOpen = true;
}
}

View File

@ -191,7 +191,8 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
}
}
private void populateChangeRow(final int row, final ChangeInfo c) {
private void populateChangeRow(final int row, final ChangeInfo c,
final ChangeRowFormatter changeRowFormatter) {
ChangeCache cache = ChangeCache.get(c.getId());
cache.getChangeInfoCache().set(c);
@ -206,13 +207,12 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
if (c.getStatus() != null && c.getStatus() != Change.Status.NEW) {
s += " (" + c.getStatus().name() + ")";
}
if (! c.isLatest()) {
s += " [OUTDATED]";
table.getRowFormatter().addStyleName(row, Gerrit.RESOURCES.css().outdated());
} else if (Change.Status.ABANDONED.equals(c.getStatus())) {
table.getRowFormatter().addStyleName(row, Gerrit.RESOURCES.css().outdated());
} else {
table.getRowFormatter().removeStyleName(row, Gerrit.RESOURCES.css().outdated());
if (changeRowFormatter != null) {
final String rowStyle = changeRowFormatter.getRowStyle(c);
if (rowStyle != null) {
table.getRowFormatter().addStyleName(row, rowStyle);
}
s = changeRowFormatter.getDisplayText(c, s);
}
table.setWidget(row, C_SUBJECT, new TableChangeLink(s, c));
@ -222,6 +222,7 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
table.setWidget(row, C_BRANCH, new BranchLink(c.getProject().getKey(), c
.getStatus(), c.getBranch(), c.getTopic()));
table.setText(row, C_LAST_UPDATE, shortFormat(c.getLastUpdatedOn()));
setRowItem(row, c);
}
@ -418,6 +419,8 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
int dataBegin;
int rows;
private ChangeRowFormatter changeRowFormatter;
public Section() {
this(null, ApprovalViewType.NONE, null);
}
@ -440,6 +443,10 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
}
}
public void setChangeRowFormatter(final ChangeRowFormatter changeRowFormatter) {
this.changeRowFormatter = changeRowFormatter;
}
public void display(final List<ChangeInfo> changeList) {
final int sz = changeList != null ? changeList.size() : 0;
final boolean hadData = rows > 0;
@ -469,7 +476,7 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
for (int i = 0; i < sz; i++) {
ChangeInfo c = changeList.get(i);
parent.populateChangeRow(dataBegin + i, c);
parent.populateChangeRow(dataBegin + i, c, changeRowFormatter);
cids.add(c.getId());
}
@ -488,4 +495,25 @@ public class ChangeTable extends NavigationTable<ChangeInfo> {
}
}
}
public static interface ChangeRowFormatter {
/**
* Returns the name of the CSS style that should be applied to the change
* row.
*
* @param c the change for which the styling should be returned
* @return the name of the CSS style that should be applied to the change
* row
*/
String getRowStyle(ChangeInfo c);
/**
* Returns the text that should be displayed for the change.
*
* @param c the change for which the display text should be returned
* @param displayText the current display text
* @return the new display text
*/
String getDisplayText(ChangeInfo c, String displayText);
}
}

View File

@ -209,6 +209,7 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
final DownloadCommandPanel commands = new DownloadCommandPanel();
final DownloadUrlPanel urls = new DownloadUrlPanel(commands);
final Set<DownloadScheme> allowedSchemes = Gerrit.getConfig().getDownloadSchemes();
final Set<DownloadCommand> allowedCommands = Gerrit.getConfig().getDownloadCommands();
copyLabel.setStyleName(Gerrit.RESOURCES.css().downloadLinkCopyLabel());
@ -323,39 +324,52 @@ class PatchSetComplexDisclosurePanel extends ComplexDisclosurePanel
}
if (!urls.isEmpty()) {
commands.add(new DownloadCommandLink(DownloadCommand.CHECKOUT, "checkout") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git checkout FETCH_HEAD");
}
});
commands.add(new DownloadCommandLink(DownloadCommand.PULL, "pull") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git pull " + link.urlData);
}
});
commands.add(new DownloadCommandLink(DownloadCommand.CHERRY_PICK,
"cherry-pick") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git cherry-pick FETCH_HEAD");
}
});
commands.add(new DownloadCommandLink(DownloadCommand.FORMAT_PATCH,
"patch") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git format-patch -1 --stdout FETCH_HEAD");
}
});
if (allowedCommands.contains(DownloadCommand.CHECKOUT)
|| allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
commands.add(new DownloadCommandLink(DownloadCommand.CHECKOUT,
"checkout") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git checkout FETCH_HEAD");
}
});
}
if (allowedCommands.contains(DownloadCommand.PULL)
|| allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
commands.add(new DownloadCommandLink(DownloadCommand.PULL, "pull") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git pull " + link.urlData);
}
});
}
if (allowedCommands.contains(DownloadCommand.CHERRY_PICK)
|| allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
commands.add(new DownloadCommandLink(DownloadCommand.CHERRY_PICK,
"cherry-pick") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git cherry-pick FETCH_HEAD");
}
});
}
if (allowedCommands.contains(DownloadCommand.FORMAT_PATCH)
|| allowedCommands.contains(DownloadCommand.DEFAULT_DOWNLOADS)) {
commands.add(new DownloadCommandLink(DownloadCommand.FORMAT_PATCH,
"patch") {
@Override
void setCurrentUrl(DownloadUrlLink link) {
urls.setVisible(true);
copyLabel.setText("git fetch " + link.urlData
+ " && git format-patch -1 --stdout FETCH_HEAD");
}
});
}
}
final FlowPanel fp = new FlowPanel();

View File

@ -35,8 +35,8 @@ import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwtorm.client.KeyUtil;
import java.util.LinkedList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
public class PatchSetSelectBox extends Composite {
interface Binder extends UiBinder<HTMLPanel, PatchSetSelectBox> {
@ -63,7 +63,7 @@ public class PatchSetSelectBox extends Composite {
PatchSet.Id idActive;
Side side;
PatchScreen.Type screenType;
List<Anchor> links;
Map<Integer, Anchor> links;
@UiField
HTMLPanel linkPanel;
@ -88,7 +88,7 @@ public class PatchSetSelectBox extends Composite {
this.idSideA = idSideA;
this.idSideB = idSideB;
this.idActive = (side == Side.A) ? idSideA : idSideB;
this.links = new LinkedList<Anchor>();
this.links = new HashMap<Integer, Anchor>();
linkPanel.clear();
@ -105,7 +105,7 @@ public class PatchSetSelectBox extends Composite {
baseLink = createLink(PatchUtil.C.patchBase(), null);
}
links.add(baseLink);
links.put(0, baseLink);
if (screenType == PatchScreen.Type.UNIFIED || side == Side.A) {
linkPanel.add(baseLink);
}
@ -117,7 +117,7 @@ public class PatchSetSelectBox extends Composite {
for (Patch patch : script.getHistory()) {
PatchSet.Id psId = patch.getKey().getParentKey();
Anchor anchor = createLink(Integer.toString(psId.get()), psId);
links.add(anchor);
links.put(psId.get(), anchor);
linkPanel.add(anchor);
}

View File

@ -22,7 +22,7 @@ import com.google.gerrit.server.account.Realm;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AnonymousCowardName;
import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.config.DownloadSchemeConfig;
import com.google.gerrit.server.config.DownloadConfig;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.contact.ContactStore;
import com.google.gerrit.server.mail.EmailSender;
@ -48,7 +48,7 @@ class GerritConfigProvider implements Provider<GerritConfig> {
private final Realm realm;
private final Config cfg;
private final AuthConfig authConfig;
private final DownloadSchemeConfig schemeConfig;
private final DownloadConfig downloadConfig;
private final GitWebConfig gitWebConfig;
private final AllProjectsName wildProject;
private final SshInfo sshInfo;
@ -63,12 +63,12 @@ class GerritConfigProvider implements Provider<GerritConfig> {
GerritConfigProvider(final Realm r, @GerritServerConfig final Config gsc,
final AuthConfig ac, final GitWebConfig gwc, final AllProjectsName wp,
final SshInfo si, final ApprovalTypes at, final ContactStore cs,
final ServletContext sc, final DownloadSchemeConfig dc,
final ServletContext sc, final DownloadConfig dc,
final @AnonymousCowardName String acn) {
realm = r;
cfg = gsc;
authConfig = ac;
schemeConfig = dc;
downloadConfig = dc;
gitWebConfig = gwc;
sshInfo = si;
wildProject = wp;
@ -111,7 +111,8 @@ class GerritConfigProvider implements Provider<GerritConfig> {
config.setGitDaemonUrl(cfg.getString("gerrit", null, "canonicalgiturl"));
config.setGitHttpUrl(cfg.getString("gerrit", null, "gitHttpUrl"));
config.setUseContactInfo(contactStore != null && contactStore.isEnabled());
config.setDownloadSchemes(schemeConfig.getDownloadScheme());
config.setDownloadSchemes(downloadConfig.getDownloadSchemes());
config.setDownloadCommands(downloadConfig.getDownloadCommands());
config.setAuthType(authConfig.getAuthType());
config.setWildProject(wildProject);
config.setApprovalTypes(approvalTypes);

View File

@ -32,7 +32,7 @@ public final class AccountGeneralPreferences {
/** Preferred method to download a change. */
public static enum DownloadCommand {
REPO_DOWNLOAD, PULL, CHECKOUT, CHERRY_PICK, FORMAT_PATCH;
REPO_DOWNLOAD, PULL, CHECKOUT, CHERRY_PICK, FORMAT_PATCH, DEFAULT_DOWNLOADS;
}
public static enum DateFormat {

View File

@ -353,6 +353,7 @@ public class ChangeUtil {
newPatchSet.setCreatedOn(new Timestamp(System.currentTimeMillis()));
newPatchSet.setUploader(user.getAccountId());
newPatchSet.setRevision(new RevId(rebasedCommit.name()));
newPatchSet.setDraft(originalPatchSet.isDraft());
final PatchSetInfo info =
patchSetInfoFactory.get(rebasedCommit, newPatchSet.getId());

View File

@ -14,8 +14,9 @@
package com.google.gerrit.server.config;
import com.google.gerrit.reviewdb.client.SystemConfig;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
import com.google.gerrit.reviewdb.client.SystemConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@ -28,22 +29,33 @@ import java.util.Set;
/** Download protocol from {@code gerrit.config}. */
@Singleton
public class DownloadSchemeConfig {
public class DownloadConfig {
private final Set<DownloadScheme> downloadSchemes;
private final Set<DownloadCommand> downloadCommands;
@Inject
DownloadSchemeConfig(@GerritServerConfig final Config cfg,
DownloadConfig(@GerritServerConfig final Config cfg,
final SystemConfig s) {
List<DownloadScheme> all =
List<DownloadScheme> allSchemes =
ConfigUtil.getEnumList(cfg, "download", null, "scheme",
DownloadScheme.DEFAULT_DOWNLOADS);
downloadSchemes =
Collections.unmodifiableSet(new HashSet<DownloadScheme>(all));
Collections.unmodifiableSet(new HashSet<DownloadScheme>(allSchemes));
List<DownloadCommand> allCommands =
ConfigUtil.getEnumList(cfg, "download", null, "command",
DownloadCommand.DEFAULT_DOWNLOADS);
downloadCommands =
Collections.unmodifiableSet(new HashSet<DownloadCommand>(allCommands));
}
/** Scheme used to download. */
public Set<DownloadScheme> getDownloadScheme() {
public Set<DownloadScheme> getDownloadSchemes() {
return downloadSchemes;
}
/** Command used to download. */
public Set<DownloadCommand> getDownloadCommands() {
return downloadCommands;
}
}

View File

@ -182,8 +182,6 @@ final class SetAccountCommand extends BaseCommand {
if (sshKeysUpdated) {
sshKeyCache.evict(account.getUserName());
}
db.close();
}
private void addSshKeys(final List<String> keys, final Account account)