Merge changes Ib5711baa,I730e37bc
* changes: Support inheriting project submit type Clarify behavior of "default" submit types
This commit is contained in:
@@ -3748,12 +3748,15 @@ Path must be absolute.
|
||||
[[repository.name.defaultSubmitType]]repository.<name>.defaultSubmitType::
|
||||
+
|
||||
The default submit type for newly created projects. Supported values
|
||||
are `MERGE_IF_NECESSARY`, `FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`,
|
||||
are `INHERIT`, `MERGE_IF_NECESSARY`, `FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`,
|
||||
`REBASE_ALWAYS`, `MERGE_ALWAYS` and `CHERRY_PICK`.
|
||||
+
|
||||
For more details see link:project-configuration.html#submit_type[Submit Types].
|
||||
+
|
||||
By default, `MERGE_IF_NECESSARY`.
|
||||
This submit type is only applied at project creation time if a submit type is
|
||||
omitted from the link:rest-api-projects.html#project-input[ProjectInput]. If the
|
||||
submit type is unset in the project config at runtime, it defaults to
|
||||
link:project-configuration.html#merge_if_necessary[`MERGE_IF_NECESSARY`].
|
||||
|
||||
[[repository.name.ownerGroup]]repository.<name>.ownerGroup::
|
||||
+
|
||||
|
@@ -57,6 +57,12 @@ modified by any project owner through the project console, `Projects` >
|
||||
its dependencies are also submitted, with exceptions documented below.
|
||||
The following submit types are supported:
|
||||
|
||||
[[submit_type_inherit]]
|
||||
* Inherit
|
||||
+
|
||||
Inherit the submit type from the parent project. In `All-Projects`, this
|
||||
is equivalent to link:#merge_if_necessary[Merge If Necessary].
|
||||
|
||||
[[fast_forward_only]]
|
||||
* Fast Forward Only
|
||||
+
|
||||
@@ -70,7 +76,8 @@ tip of the destination branch at submit time.
|
||||
[[merge_if_necessary]]
|
||||
* Merge If Necessary
|
||||
+
|
||||
This is the default for a new project.
|
||||
This is the default for new projects, unless overridden by a global
|
||||
link:config-gerrit.html#repository.name.defaultSubmitType[`defaultSubmitType` option].
|
||||
+
|
||||
If the change being submitted is a strict superset of the destination
|
||||
branch, then the branch is fast-forwarded to the change. If not,
|
||||
|
@@ -494,7 +494,7 @@ link:#project-input[ProjectInput].
|
||||
|
||||
{
|
||||
"description": "This is a demo project.",
|
||||
"submit_type": "CHERRY_PICK",
|
||||
"submit_type": "INHERIT",
|
||||
"owners": [
|
||||
"MyProject-Owners"
|
||||
]
|
||||
@@ -821,7 +821,12 @@ read access to `refs/meta/config`.
|
||||
"configured_value": "15m",
|
||||
"inherited_value": "20m"
|
||||
},
|
||||
"submit_type": "MERGE_IF_NECESSARY",
|
||||
"submit_type": "INHERIT",
|
||||
"default_submit_type": {
|
||||
"value": "MERGE_IF_NECESSARY",
|
||||
"configured_value": "INHERIT",
|
||||
"inherited_value": "MERGE_IF_NECESSARY"
|
||||
},
|
||||
"state": "ACTIVE",
|
||||
"commentlinks": {},
|
||||
"plugin_config": {
|
||||
@@ -933,6 +938,11 @@ ConfigInfo] entity.
|
||||
"inherited_value": "20m"
|
||||
},
|
||||
"submit_type": "REBASE_IF_NECESSARY",
|
||||
"default_submit_type": {
|
||||
"value": "REBASE_IF_NECESSARY",
|
||||
"configured_value": "INHERIT",
|
||||
"inherited_value": "REBASE_IF_NECESSARY"
|
||||
},
|
||||
"state": "ACTIVE",
|
||||
"commentlinks": {}
|
||||
}
|
||||
@@ -2846,10 +2856,12 @@ all new changes are set as private by default.
|
||||
The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size
|
||||
limit] of this project as a link:#max-object-size-limit-info[
|
||||
MaxObjectSizeLimitInfo] entity.
|
||||
|`default_submit_type` ||
|
||||
link:#submit-type-info[SubmitTypeInfo] that describes the default submit type of
|
||||
the project, when not overridden at the change level.
|
||||
|`submit_type` ||
|
||||
The default submit type of the project, can be `MERGE_IF_NECESSARY`,
|
||||
`FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`, `REBASE_ALWAYS`, `MERGE_ALWAYS` or
|
||||
`CHERRY_PICK`.
|
||||
Deprecated; equivalent to link:#submit-type-info[`value`] in
|
||||
`default_submit_type`.
|
||||
|`match_author_to_committer_date` |optional|
|
||||
link:#inherited-boolean-info[InheritedBooleanInfo] that indicates whether
|
||||
a change's author date will be changed to match its submitter date upon submit.
|
||||
@@ -3327,6 +3339,27 @@ statistics of a Git repository.
|
||||
|`size_of_packed_objects` |Size of packed objects in bytes.
|
||||
|======================================
|
||||
|
||||
[[submit-type-info]]
|
||||
=== SubmitTypeInfo
|
||||
Information about the link:project-configuration.html#submit_type[default submit
|
||||
type of a project], taking into account project inheritance.
|
||||
|
||||
Valid values for each field are `MERGE_IF_NECESSARY`, `FAST_FORWARD_ONLY`,
|
||||
`REBASE_IF_NECESSARY`, `REBASE_ALWAYS`, `MERGE_ALWAYS` or `CHERRY_PICK`, plus
|
||||
`INHERIT` where applicable.
|
||||
|
||||
[options="header",cols="1,6"]
|
||||
|===============================
|
||||
|Field Name |Description
|
||||
|`value` |
|
||||
The effective submit type value. Never `INHERIT`.
|
||||
|`configured_value` |
|
||||
The configured value, can be one of the submit types, or `INHERIT` to inherit
|
||||
from the parent project.
|
||||
|`inherited_value` |
|
||||
The effective value that would be inherited from the parent. Never `INHERIT`.
|
||||
|===============================
|
||||
|
||||
[[tag-info]]
|
||||
=== TagInfo
|
||||
The `TagInfo` entity contains information about a tag.
|
||||
|
@@ -133,6 +133,8 @@ public interface AdminConstants extends Constants {
|
||||
|
||||
String headingProjectSubmitType();
|
||||
|
||||
String projectSubmitType_INHERIT();
|
||||
|
||||
String projectSubmitType_FAST_FORWARD_ONLY();
|
||||
|
||||
String projectSubmitType_MERGE_ALWAYS();
|
||||
|
@@ -57,6 +57,7 @@ headingAgreements = Contributor Agreements
|
||||
headingAuditLog = Audit Log
|
||||
|
||||
headingProjectSubmitType = Submit Type
|
||||
projectSubmitType_INHERIT = Inherit
|
||||
projectSubmitType_FAST_FORWARD_ONLY = Fast Forward Only
|
||||
projectSubmitType_MERGE_IF_NECESSARY = Merge if Necessary
|
||||
projectSubmitType_REBASE_ALWAYS = Rebase Always
|
||||
|
@@ -30,6 +30,7 @@ import com.google.gerrit.client.projects.ConfigInfo;
|
||||
import com.google.gerrit.client.projects.ConfigInfo.ConfigParameterInfo;
|
||||
import com.google.gerrit.client.projects.ConfigInfo.ConfigParameterValue;
|
||||
import com.google.gerrit.client.projects.ConfigInfo.InheritedBooleanInfo;
|
||||
import com.google.gerrit.client.projects.ConfigInfo.SubmitTypeInfo;
|
||||
import com.google.gerrit.client.projects.ProjectApi;
|
||||
import com.google.gerrit.client.rpc.CallbackGroup;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
@@ -335,13 +336,15 @@ public class ProjectInfoScreen extends ProjectScreen {
|
||||
grid.addHtml(AdminConstants.I.useSignedOffBy(), signedOffBy);
|
||||
}
|
||||
|
||||
private void setSubmitType(SubmitType newSubmitType) {
|
||||
private void setSubmitType(SubmitTypeInfo newSubmitType) {
|
||||
int index = -1;
|
||||
if (submitType != null) {
|
||||
if (newSubmitType != null) {
|
||||
for (int i = 0; i < submitType.getItemCount(); i++) {
|
||||
if (newSubmitType.name().equals(submitType.getValue(i))) {
|
||||
if (submitType.getValue(i).equals(SubmitType.INHERIT.name())) {
|
||||
submitType.setItemText(i, getInheritString(newSubmitType));
|
||||
}
|
||||
if (newSubmitType.configuredValue().name().equals(submitType.getValue(i))) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
submitType.setSelectedIndex(index);
|
||||
@@ -349,6 +352,13 @@ public class ProjectInfoScreen extends ProjectScreen {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getInheritString(SubmitTypeInfo submitType) {
|
||||
return Util.toLongString(SubmitType.INHERIT)
|
||||
+ " ("
|
||||
+ Util.toLongString(submitType.inheritedValue())
|
||||
+ ")";
|
||||
}
|
||||
|
||||
private void setState(ProjectState newState) {
|
||||
if (state != null) {
|
||||
for (int i = 0; i < state.getItemCount(); i++) {
|
||||
@@ -419,7 +429,7 @@ public class ProjectInfoScreen extends ProjectScreen {
|
||||
setBool(privateByDefault, result.privateByDefault());
|
||||
setBool(enableReviewerByEmail, result.enableReviewerByEmail());
|
||||
setBool(matchAuthorToCommitterDate, result.matchAuthorToCommitterDate());
|
||||
setSubmitType(result.submitType());
|
||||
setSubmitType(result.defaultSubmitType());
|
||||
setState(result.state());
|
||||
maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue());
|
||||
if (result.maxObjectSizeLimit().inheritedValue() != null) {
|
||||
|
@@ -35,6 +35,8 @@ public class Util {
|
||||
return "";
|
||||
}
|
||||
switch (type) {
|
||||
case INHERIT:
|
||||
return AdminConstants.I.projectSubmitType_INHERIT();
|
||||
case FAST_FORWARD_ONLY:
|
||||
return AdminConstants.I.projectSubmitType_FAST_FORWARD_ONLY();
|
||||
case MERGE_IF_NECESSARY:
|
||||
|
@@ -70,6 +70,8 @@ public class ConfigInfo extends JavaScriptObject {
|
||||
return SubmitType.valueOf(submitTypeRaw());
|
||||
}
|
||||
|
||||
public final native SubmitTypeInfo defaultSubmitType() /*-{ return this.default_submit_type; }-*/;
|
||||
|
||||
public final native NativeMap<NativeMap<ConfigParameterInfo>> pluginConfig()
|
||||
/*-{ return this.plugin_config || {}; }-*/ ;
|
||||
|
||||
@@ -232,4 +234,26 @@ public class ConfigInfo extends JavaScriptObject {
|
||||
|
||||
protected ConfigParameterValue() {}
|
||||
}
|
||||
|
||||
public static class SubmitTypeInfo extends JavaScriptObject {
|
||||
public final SubmitType value() {
|
||||
return SubmitType.valueOf(valueRaw());
|
||||
}
|
||||
|
||||
public final SubmitType configuredValue() {
|
||||
return SubmitType.valueOf(configuredValueRaw());
|
||||
}
|
||||
|
||||
public final SubmitType inheritedValue() {
|
||||
return SubmitType.valueOf(inheritedValueRaw());
|
||||
}
|
||||
|
||||
private final native String valueRaw() /*-{ return this.value; }-*/;
|
||||
|
||||
private final native String configuredValueRaw() /*-{ return this.configured_value; }-*/;
|
||||
|
||||
private final native String inheritedValueRaw() /*-{ return this.inherited_value; }-*/;
|
||||
|
||||
protected SubmitTypeInfo() {}
|
||||
}
|
||||
}
|
||||
|
@@ -176,7 +176,9 @@ public class ProjectApi {
|
||||
in.setRejectImplicitMerges(rejectImplicitMerges);
|
||||
in.setPrivateByDefault(privateByDefault);
|
||||
in.setMaxObjectSizeLimit(maxObjectSizeLimit);
|
||||
if (submitType != null) {
|
||||
in.setSubmitType(submitType);
|
||||
}
|
||||
in.setState(state);
|
||||
in.setPluginConfigValues(pluginConfigValues);
|
||||
in.setEnableReviewerByEmail(enableReviewerByEmail);
|
||||
|
@@ -48,6 +48,9 @@ public class SubmitTypeRecord {
|
||||
public final String errorMessage;
|
||||
|
||||
private SubmitTypeRecord(Status status, SubmitType type, String errorMessage) {
|
||||
if (type == SubmitType.INHERIT) {
|
||||
throw new IllegalArgumentException("Cannot output submit type " + type);
|
||||
}
|
||||
this.status = status;
|
||||
this.type = type;
|
||||
this.errorMessage = errorMessage;
|
||||
|
@@ -38,7 +38,9 @@ public class ConfigInfo {
|
||||
public InheritedBooleanInfo rejectEmptyCommit;
|
||||
|
||||
public MaxObjectSizeLimitInfo maxObjectSizeLimit;
|
||||
@Deprecated // Equivalent to defaultSubmitType.value
|
||||
public SubmitType submitType;
|
||||
public SubmitTypeInfo defaultSubmitType;
|
||||
public ProjectState state;
|
||||
public Map<String, Map<String, ConfigParameterInfo>> pluginConfig;
|
||||
public Map<String, ActionInfo> actions;
|
||||
@@ -73,4 +75,10 @@ public class ConfigInfo {
|
||||
public List<String> permittedValues;
|
||||
public List<String> values;
|
||||
}
|
||||
|
||||
public static class SubmitTypeInfo {
|
||||
public SubmitType value;
|
||||
public SubmitType configuredValue;
|
||||
public SubmitType inheritedValue;
|
||||
}
|
||||
}
|
||||
|
@@ -15,10 +15,11 @@
|
||||
package com.google.gerrit.extensions.client;
|
||||
|
||||
public enum SubmitType {
|
||||
INHERIT,
|
||||
FAST_FORWARD_ONLY,
|
||||
MERGE_IF_NECESSARY,
|
||||
REBASE_IF_NECESSARY,
|
||||
REBASE_ALWAYS,
|
||||
MERGE_ALWAYS,
|
||||
CHERRY_PICK
|
||||
CHERRY_PICK;
|
||||
}
|
||||
|
@@ -25,6 +25,12 @@ import java.util.Map;
|
||||
|
||||
/** Projects match a source code repository managed by Gerrit */
|
||||
public final class Project {
|
||||
/** Default submit type for new projects. */
|
||||
public static final SubmitType DEFAULT_SUBMIT_TYPE = SubmitType.MERGE_IF_NECESSARY;
|
||||
|
||||
/** Default submit type for root project (All-Projects). */
|
||||
public static final SubmitType DEFAULT_ALL_PROJECTS_SUBMIT_TYPE = SubmitType.MERGE_IF_NECESSARY;
|
||||
|
||||
/** Project name key */
|
||||
public static class NameKey extends StringKey<com.google.gwtorm.client.Key<?>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -137,7 +143,14 @@ public final class Project {
|
||||
maxObjectSizeLimit = limit;
|
||||
}
|
||||
|
||||
public SubmitType getSubmitType() {
|
||||
/**
|
||||
* Submit type as configured in {@code project.config}.
|
||||
*
|
||||
* <p>Does not take inheritance into account, i.e. may return {@link SubmitType#INHERIT}.
|
||||
*
|
||||
* @return submit type.
|
||||
*/
|
||||
public SubmitType getConfiguredSubmitType() {
|
||||
return submitType;
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.change;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.gerrit.server.ioutil.BasicSerialization.readString;
|
||||
@@ -59,6 +60,7 @@ public class MergeabilityCacheImpl implements MergeabilityCache {
|
||||
|
||||
public static final ImmutableBiMap<SubmitType, Character> SUBMIT_TYPES =
|
||||
new ImmutableBiMap.Builder<SubmitType, Character>()
|
||||
.put(SubmitType.INHERIT, 'I')
|
||||
.put(SubmitType.FAST_FORWARD_ONLY, 'F')
|
||||
.put(SubmitType.MERGE_IF_NECESSARY, 'M')
|
||||
.put(SubmitType.REBASE_ALWAYS, 'P')
|
||||
@@ -98,6 +100,11 @@ public class MergeabilityCacheImpl implements MergeabilityCache {
|
||||
private String mergeStrategy;
|
||||
|
||||
public EntryKey(ObjectId commit, ObjectId into, SubmitType submitType, String mergeStrategy) {
|
||||
checkArgument(
|
||||
submitType != SubmitType.INHERIT,
|
||||
"Cannot cache %s.%s",
|
||||
SubmitType.class.getSimpleName(),
|
||||
submitType);
|
||||
this.commit = checkNotNull(commit, "commit");
|
||||
this.into = checkNotNull(into, "into");
|
||||
this.submitType = checkNotNull(submitType, "submitType");
|
||||
|
@@ -16,6 +16,7 @@ package com.google.gerrit.server.git;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.gerrit.common.data.Permission.isPermission;
|
||||
import static com.google.gerrit.reviewdb.client.Project.DEFAULT_SUBMIT_TYPE;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -42,7 +43,6 @@ import com.google.gerrit.common.data.SubscribeSection;
|
||||
import com.google.gerrit.common.errors.InvalidNameException;
|
||||
import com.google.gerrit.extensions.client.InheritableBoolean;
|
||||
import com.google.gerrit.extensions.client.ProjectState;
|
||||
import com.google.gerrit.extensions.client.SubmitType;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
@@ -151,7 +151,6 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
||||
|
||||
private static final String PLUGIN = "plugin";
|
||||
|
||||
private static final SubmitType DEFAULT_SUBMIT_ACTION = SubmitType.MERGE_IF_NECESSARY;
|
||||
private static final ProjectState DEFAULT_STATE_VALUE = ProjectState.ACTIVE;
|
||||
|
||||
private static final String EXTENSION_PANELS = "extension-panels";
|
||||
@@ -519,7 +518,7 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
||||
|
||||
p.setMaxObjectSizeLimit(rc.getString(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT));
|
||||
|
||||
p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, DEFAULT_SUBMIT_ACTION));
|
||||
p.setSubmitType(getEnum(rc, SUBMIT, null, KEY_ACTION, DEFAULT_SUBMIT_TYPE));
|
||||
p.setState(getEnum(rc, PROJECT, null, KEY_STATE, DEFAULT_STATE_VALUE));
|
||||
|
||||
p.setDefaultDashboard(rc.getString(DASHBOARD, null, KEY_DEFAULT));
|
||||
@@ -1043,7 +1042,7 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
|
||||
KEY_MAX_OBJECT_SIZE_LIMIT,
|
||||
validMaxObjectSizeLimit(p.getMaxObjectSizeLimit()));
|
||||
|
||||
set(rc, SUBMIT, null, KEY_ACTION, p.getSubmitType(), DEFAULT_SUBMIT_ACTION);
|
||||
set(rc, SUBMIT, null, KEY_ACTION, p.getConfiguredSubmitType(), DEFAULT_SUBMIT_TYPE);
|
||||
|
||||
set(rc, PROJECT, null, KEY_STATE, p.getState(), DEFAULT_STATE_VALUE);
|
||||
|
||||
|
@@ -133,6 +133,7 @@ public class SubmitDryRun {
|
||||
return RebaseIfNecessary.dryRun(args, repo, tipCommit, toMergeCommit);
|
||||
case REBASE_ALWAYS:
|
||||
return RebaseAlways.dryRun(args, repo, tipCommit, toMergeCommit);
|
||||
case INHERIT:
|
||||
default:
|
||||
String errorMsg = "No submit strategy for: " + submitType;
|
||||
log.error(errorMsg);
|
||||
|
@@ -96,6 +96,7 @@ public class SubmitStrategyFactory {
|
||||
return new RebaseIfNecessary(args);
|
||||
case REBASE_ALWAYS:
|
||||
return new RebaseAlways(args);
|
||||
case INHERIT:
|
||||
default:
|
||||
String errorMsg = "No submit strategy for: " + submitType;
|
||||
log.error(errorMsg);
|
||||
|
@@ -465,6 +465,7 @@ abstract class SubmitStrategyOp implements BatchUpdateOp {
|
||||
case REBASE_IF_NECESSARY:
|
||||
case REBASE_ALWAYS:
|
||||
return message(ctx, commit, CommitMergeStatus.CLEAN_REBASE);
|
||||
case INHERIT:
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"unexpected submit type "
|
||||
|
@@ -31,6 +31,7 @@ import com.google.gerrit.common.data.RefConfigSection;
|
||||
import com.google.gerrit.common.data.SubscribeSection;
|
||||
import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
|
||||
import com.google.gerrit.extensions.api.projects.ThemeInfo;
|
||||
import com.google.gerrit.extensions.client.SubmitType;
|
||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||
import com.google.gerrit.reviewdb.client.BooleanProjectConfig;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
@@ -490,6 +491,16 @@ public class ProjectState {
|
||||
return getGroups(getLocalAccessSections());
|
||||
}
|
||||
|
||||
public SubmitType getSubmitType() {
|
||||
for (ProjectState s : tree()) {
|
||||
SubmitType t = s.getProject().getConfiguredSubmitType();
|
||||
if (t != SubmitType.INHERIT) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return Project.DEFAULT_ALL_PROJECTS_SUBMIT_TYPE;
|
||||
}
|
||||
|
||||
private static Set<GroupReference> getGroups(List<SectionMatcher> sectionMatcherList) {
|
||||
final Set<GroupReference> all = new HashSet<>();
|
||||
for (SectionMatcher matcher : sectionMatcherList) {
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
package com.google.gerrit.server.restapi.project;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
|
||||
@@ -42,6 +43,7 @@ import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ConfigInfoImpl extends ConfigInfo {
|
||||
@SuppressWarnings("deprecation")
|
||||
public ConfigInfoImpl(
|
||||
boolean serverEnableSignedPush,
|
||||
ProjectState projectState,
|
||||
@@ -79,7 +81,18 @@ public class ConfigInfoImpl extends ConfigInfo {
|
||||
maxObjectSizeLimit.inheritedValue = config.getFormattedMaxObjectSizeLimit();
|
||||
this.maxObjectSizeLimit = maxObjectSizeLimit;
|
||||
|
||||
this.submitType = p.getSubmitType();
|
||||
this.defaultSubmitType = new SubmitTypeInfo();
|
||||
this.defaultSubmitType.value = projectState.getSubmitType();
|
||||
this.defaultSubmitType.configuredValue =
|
||||
MoreObjects.firstNonNull(
|
||||
projectState.getConfig().getProject().getConfiguredSubmitType(),
|
||||
Project.DEFAULT_SUBMIT_TYPE);
|
||||
ProjectState parent =
|
||||
projectState.isAllProjects() ? projectState : projectState.parents().get(0);
|
||||
this.defaultSubmitType.inheritedValue = parent.getSubmitType();
|
||||
|
||||
this.submitType = this.defaultSubmitType.value;
|
||||
|
||||
this.state =
|
||||
p.getState() != com.google.gerrit.extensions.client.ProjectState.ACTIVE
|
||||
? p.getState()
|
||||
|
@@ -47,7 +47,7 @@ public class PRED_project_default_submit_type_1 extends Predicate.P1 {
|
||||
Term a1 = arg1.dereference();
|
||||
|
||||
ProjectState projectState = StoredValues.PROJECT_STATE.get(engine);
|
||||
SubmitType submitType = projectState.getProject().getSubmitType();
|
||||
SubmitType submitType = projectState.getSubmitType();
|
||||
if (!a1.unify(term[submitType.ordinal()], engine.trail)) {
|
||||
return engine.fail();
|
||||
}
|
||||
|
@@ -219,13 +219,13 @@ public class ProjectIT extends AbstractDaemonTest {
|
||||
RevCommit initialHead = getRemoteHead(project, RefNames.REFS_CONFIG);
|
||||
|
||||
ConfigInfo info = gApi.projects().name(project.get()).config();
|
||||
assertThat(info.submitType).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(info.defaultSubmitType.value).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
ConfigInput input = new ConfigInput();
|
||||
input.submitType = SubmitType.CHERRY_PICK;
|
||||
info = gApi.projects().name(project.get()).config(input);
|
||||
assertThat(info.submitType).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(info.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
info = gApi.projects().name(project.get()).config();
|
||||
assertThat(info.submitType).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(info.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
|
||||
RevCommit updatedHead = getRemoteHead(project, RefNames.REFS_CONFIG);
|
||||
eventRecorder.assertRefUpdatedEvents(
|
||||
@@ -233,6 +233,7 @@ public class ProjectIT extends AbstractDaemonTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setConfig() throws Exception {
|
||||
ConfigInput input = createTestConfigInput();
|
||||
ConfigInfo info = gApi.projects().name(project.get()).config(input);
|
||||
@@ -250,9 +251,13 @@ public class ProjectIT extends AbstractDaemonTest {
|
||||
.isEqualTo(input.createNewChangeForAllNotInTarget);
|
||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo(input.maxObjectSizeLimit);
|
||||
assertThat(info.submitType).isEqualTo(input.submitType);
|
||||
assertThat(info.defaultSubmitType.value).isEqualTo(input.submitType);
|
||||
assertThat(info.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(info.defaultSubmitType.configuredValue).isEqualTo(input.submitType);
|
||||
assertThat(info.state).isEqualTo(input.state);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void setPartialConfig() throws Exception {
|
||||
ConfigInput input = createTestConfigInput();
|
||||
@@ -276,6 +281,9 @@ public class ProjectIT extends AbstractDaemonTest {
|
||||
.isEqualTo(input.createNewChangeForAllNotInTarget);
|
||||
assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo(input.maxObjectSizeLimit);
|
||||
assertThat(info.submitType).isEqualTo(input.submitType);
|
||||
assertThat(info.defaultSubmitType.value).isEqualTo(input.submitType);
|
||||
assertThat(info.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(info.defaultSubmitType.configuredValue).isEqualTo(input.submitType);
|
||||
assertThat(info.state).isEqualTo(input.state);
|
||||
}
|
||||
|
||||
|
@@ -238,6 +238,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
|
||||
break;
|
||||
case MERGE_ALWAYS:
|
||||
case MERGE_IF_NECESSARY:
|
||||
case INHERIT:
|
||||
assertThat(e.getMessage())
|
||||
.isEqualTo(
|
||||
"Failed to submit 3 changes due to the following problems:\n"
|
||||
|
@@ -24,9 +24,12 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.google.gerrit.acceptance.AbstractDaemonTest;
|
||||
import com.google.gerrit.acceptance.GerritConfig;
|
||||
import com.google.gerrit.acceptance.RestResponse;
|
||||
import com.google.gerrit.acceptance.UseLocalDisk;
|
||||
import com.google.gerrit.common.data.GlobalCapability;
|
||||
import com.google.gerrit.extensions.api.projects.ConfigInfo;
|
||||
import com.google.gerrit.extensions.api.projects.ConfigInput;
|
||||
import com.google.gerrit.extensions.api.projects.ProjectInput;
|
||||
import com.google.gerrit.extensions.client.InheritableBoolean;
|
||||
import com.google.gerrit.extensions.client.SubmitType;
|
||||
@@ -181,7 +184,7 @@ public class CreateProjectIT extends AbstractDaemonTest {
|
||||
Project project = projectCache.get(new Project.NameKey(newProjectName)).getProject();
|
||||
assertProjectInfo(project, p);
|
||||
assertThat(project.getDescription()).isEqualTo(in.description);
|
||||
assertThat(project.getSubmitType()).isEqualTo(in.submitType);
|
||||
assertThat(project.getConfiguredSubmitType()).isEqualTo(in.submitType);
|
||||
assertThat(project.getBooleanConfig(BooleanProjectConfig.USE_CONTRIBUTOR_AGREEMENTS))
|
||||
.isEqualTo(in.useContributorAgreements);
|
||||
assertThat(project.getBooleanConfig(BooleanProjectConfig.USE_SIGNED_OFF_BY))
|
||||
@@ -331,6 +334,84 @@ public class CreateProjectIT extends AbstractDaemonTest {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void createProjectWithDefaultInheritedSubmitType() throws Exception {
|
||||
String parent = name("parent");
|
||||
ProjectInput pin = new ProjectInput();
|
||||
pin.name = parent;
|
||||
ConfigInfo cfg = gApi.projects().create(pin).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
|
||||
ConfigInput cin = new ConfigInput();
|
||||
cin.submitType = SubmitType.CHERRY_PICK;
|
||||
gApi.projects().name(parent).config(cin);
|
||||
cfg = gApi.projects().name(parent).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
|
||||
String child = name("child");
|
||||
pin = new ProjectInput();
|
||||
pin.submitType = SubmitType.INHERIT;
|
||||
pin.parent = parent;
|
||||
pin.name = child;
|
||||
cfg = gApi.projects().create(pin).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.INHERIT);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
|
||||
cin = new ConfigInput();
|
||||
cin.submitType = SubmitType.REBASE_IF_NECESSARY;
|
||||
gApi.projects().name(parent).config(cin);
|
||||
cfg = gApi.projects().name(parent).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
|
||||
cfg = gApi.projects().name(child).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.INHERIT);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.REBASE_IF_NECESSARY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
@GerritConfig(
|
||||
name = "repository.testinheritedsubmittype/*.defaultSubmitType",
|
||||
value = "CHERRY_PICK"
|
||||
)
|
||||
public void repositoryConfigTakesPrecedenceOverInheritedSubmitType() throws Exception {
|
||||
// Can't use name() since we need to specify this project name in gerrit.config prior to
|
||||
// startup. Pick something reasonably unique instead.
|
||||
String parent = "testinheritedsubmittype";
|
||||
ProjectInput pin = new ProjectInput();
|
||||
pin.name = parent;
|
||||
pin.submitType = SubmitType.MERGE_ALWAYS;
|
||||
ConfigInfo cfg = gApi.projects().create(pin).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.MERGE_ALWAYS);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.MERGE_ALWAYS);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.MERGE_ALWAYS);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
|
||||
|
||||
String child = parent + "/child";
|
||||
pin = new ProjectInput();
|
||||
pin.parent = parent;
|
||||
pin.name = child;
|
||||
cfg = gApi.projects().create(pin).config();
|
||||
assertThat(cfg.submitType).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.configuredValue).isEqualTo(SubmitType.CHERRY_PICK);
|
||||
assertThat(cfg.defaultSubmitType.inheritedValue).isEqualTo(SubmitType.MERGE_ALWAYS);
|
||||
}
|
||||
|
||||
private void assertHead(String projectName, String expectedRef) throws Exception {
|
||||
try (Repository repo = repoManager.openRepository(new Project.NameKey(projectName))) {
|
||||
assertThat(repo.exactRef(Constants.HEAD).getTarget().getName()).isEqualTo(expectedRef);
|
||||
|
@@ -103,7 +103,8 @@ limitations under the License.
|
||||
id="submitTypeSelect"
|
||||
bind-value="{{_repoConfig.submit_type}}">
|
||||
<select disabled$="[[_readOnly]]">
|
||||
<template is="dom-repeat" items="[[_submitTypes]]">
|
||||
<template is="dom-repeat"
|
||||
items="[[_formatSubmitTypeSelect(_repoConfig)]]">
|
||||
<option value="[[item.value]]">[[item.label]]</option>
|
||||
</template>
|
||||
</select>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
};
|
||||
|
||||
const SUBMIT_TYPES = {
|
||||
// Exclude INHERIT, which is handled specially.
|
||||
mergeIfNecessary: {
|
||||
value: 'MERGE_IF_NECESSARY',
|
||||
label: 'Merge if necessary',
|
||||
@@ -129,6 +130,15 @@
|
||||
|
||||
promises.push(this.$.restAPI.getProjectConfig(this.repo).then(
|
||||
config => {
|
||||
if (config.default_submit_type) {
|
||||
// The gr-select is bound to submit_type, which needs to be the
|
||||
// *configured* submit type. When default_submit_type is
|
||||
// present, the server reports the *effective* submit type in
|
||||
// submit_type, so we need to overwrite it before storing the
|
||||
// config in this.
|
||||
config.submit_type =
|
||||
config.default_submit_type.configured_value;
|
||||
}
|
||||
if (!config.state) {
|
||||
config.state = STATES.active.value;
|
||||
}
|
||||
@@ -183,6 +193,36 @@
|
||||
];
|
||||
},
|
||||
|
||||
_formatSubmitTypeSelect(projectConfig) {
|
||||
if (!projectConfig) { return; }
|
||||
const allValues = Object.values(SUBMIT_TYPES);
|
||||
const type = projectConfig.default_submit_type;
|
||||
if (!type) {
|
||||
// Server is too old to report default_submit_type, so assume INHERIT
|
||||
// is not a valid value.
|
||||
return allValues;
|
||||
}
|
||||
|
||||
let inheritLabel = 'Inherit';
|
||||
if (type.inherited_value) {
|
||||
let inherited = type.inherited_value;
|
||||
for (const val of allValues) {
|
||||
if (val.value === type.inherited_value) {
|
||||
inherited = val.label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
inheritLabel = `Inherit (${inherited})`;
|
||||
}
|
||||
return [
|
||||
{
|
||||
label: inheritLabel,
|
||||
value: 'INHERIT',
|
||||
},
|
||||
...allValues,
|
||||
];
|
||||
},
|
||||
|
||||
_isLoading() {
|
||||
return this._loading || this._loading === undefined;
|
||||
},
|
||||
@@ -195,6 +235,12 @@
|
||||
const configInputObj = {};
|
||||
for (const key in p) {
|
||||
if (p.hasOwnProperty(key)) {
|
||||
if (key === 'default_submit_type') {
|
||||
// default_submit_type is not in the input type, and the
|
||||
// configured value was already copied to submit_type by
|
||||
// _loadProject. Omit this property when saving.
|
||||
continue;
|
||||
}
|
||||
if (typeof p[key] === 'object') {
|
||||
configInputObj[key] = p[key].configured_value;
|
||||
} else {
|
||||
|
@@ -99,6 +99,11 @@ limitations under the License.
|
||||
},
|
||||
max_object_size_limit: {},
|
||||
submit_type: 'MERGE_IF_NECESSARY',
|
||||
default_submit_type: {
|
||||
value: 'MERGE_IF_NECESSARY',
|
||||
configured_value: 'INHERIT',
|
||||
inherited_value: 'MERGE_IF_NECESSARY',
|
||||
},
|
||||
});
|
||||
},
|
||||
getConfig() {
|
||||
@@ -252,7 +257,16 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('fields update and save correctly', done => {
|
||||
test('inherited submit type value is calculated correctly', () => {
|
||||
return element._loadRepo().then(() => {
|
||||
const sel = element.$.submitTypeSelect;
|
||||
assert.equal(sel.bindValue, 'INHERIT');
|
||||
assert.equal(
|
||||
sel.nativeSelect.options[0].text, 'Inherit (Merge if necessary)');
|
||||
});
|
||||
});
|
||||
|
||||
test('fields update and save correctly', () => {
|
||||
// test notedb
|
||||
element._noteDbEnabled = false;
|
||||
|
||||
@@ -289,7 +303,7 @@ limitations under the License.
|
||||
|
||||
const button = Polymer.dom(element.root).querySelector('gr-button');
|
||||
|
||||
element._loadRepo().then(() => {
|
||||
return element._loadRepo().then(() => {
|
||||
assert.isTrue(button.hasAttribute('disabled'));
|
||||
assert.isFalse(element.$.Title.classList.contains('edited'));
|
||||
element.$.descriptionInput.bindValue = configInputObj.description;
|
||||
@@ -327,12 +341,11 @@ limitations under the License.
|
||||
element._formatRepoConfigForSave(element._repoConfig);
|
||||
assert.deepEqual(formattedObj, configInputObj);
|
||||
|
||||
element._handleSaveRepoConfig().then(() => {
|
||||
return element._handleSaveRepoConfig().then(() => {
|
||||
assert.isTrue(button.hasAttribute('disabled'));
|
||||
assert.isFalse(element.$.Title.classList.contains('edited'));
|
||||
assert.isTrue(saveStub.lastCall.calledWithExactly(REPO,
|
||||
configInputObj));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user