diff options
21 files changed, 144 insertions, 20 deletions
diff --git a/.gitmodules b/.gitmodules index 9f67e77676..410b47db09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,58 +1,59 @@ [submodule "modules/jgit"] path = modules/jgit - url = ../jgit + url = https://gerrit.googlesource.com/jgit + branch = . [submodule "plugins/codemirror-editor"] path = plugins/codemirror-editor - url = ../plugins/codemirror-editor + url = https://gerrit.googlesource.com/plugins/codemirror-editor branch = . [submodule "plugins/commit-message-length-validator"] path = plugins/commit-message-length-validator - url = ../plugins/commit-message-length-validator + url = https://gerrit.googlesource.com/plugins/commit-message-length-validator branch = . [submodule "plugins/delete-project"] path = plugins/delete-project - url = ../plugins/delete-project + url = https://gerrit.googlesource.com/plugins/delete-project branch = . [submodule "plugins/download-commands"] path = plugins/download-commands - url = ../plugins/download-commands + url = https://gerrit.googlesource.com/plugins/download-commands branch = . [submodule "plugins/gitiles"] path = plugins/gitiles - url = ../plugins/gitiles + url = https://gerrit.googlesource.com/plugins/gitiles branch = . [submodule "plugins/hooks"] path = plugins/hooks - url = ../plugins/hooks + url = https://gerrit.googlesource.com/plugins/hooks branch = . [submodule "plugins/plugin-manager"] path = plugins/plugin-manager - url = ../plugins/plugin-manager + url = https://gerrit.googlesource.com/plugins/plugin-manager branch = . [submodule "plugins/replication"] path = plugins/replication - url = ../plugins/replication + url = https://gerrit.googlesource.com/plugins/replication branch = . [submodule "plugins/reviewnotes"] path = plugins/reviewnotes - url = ../plugins/reviewnotes + url = https://gerrit.googlesource.com/plugins/reviewnotes branch = . [submodule "plugins/singleusergroup"] path = plugins/singleusergroup - url = ../plugins/singleusergroup + url = https://gerrit.googlesource.com/plugins/singleusergroup branch = . [submodule "plugins/webhooks"] path = plugins/webhooks - url = ../plugins/webhooks + url = https://gerrit.googlesource.com/plugins/webhooks branch = . diff --git a/java/com/google/gerrit/common/PageLinks.java b/java/com/google/gerrit/common/PageLinks.java index 38de5b15a1..30708b8c18 100644 --- a/java/com/google/gerrit/common/PageLinks.java +++ b/java/com/google/gerrit/common/PageLinks.java @@ -141,11 +141,15 @@ public class PageLinks { public static String topicQuery(Status status, String topic) { switch (status) { case ABANDONED: + case DEFERRED: return toChangeQuery(status(status) + " " + op("topic", topic)); case MERGED: case NEW: return toChangeQuery( op("topic", topic) + " (" + status(Status.NEW) + " OR " + status(Status.MERGED) + ")"); + case INTEGRATING: + case STAGED: + return toChangeQuery(status(status) + " " + op("topic", topic)); } return toChangeQuery(status(status) + " " + op("topic", topic)); } @@ -168,6 +172,12 @@ public class PageLinks { return "status:abandoned"; case MERGED: return "status:merged"; + case INTEGRATING: + return "status:integrating"; + case DEFERRED: + return "status:deferred"; + case STAGED: + return "status:staged"; case NEW: default: return "status:open"; diff --git a/java/com/google/gerrit/common/data/Permission.java b/java/com/google/gerrit/common/data/Permission.java index 3ba0ba75d1..f91df4b6dc 100644 --- a/java/com/google/gerrit/common/data/Permission.java +++ b/java/com/google/gerrit/common/data/Permission.java @@ -48,6 +48,7 @@ public class Permission implements Comparable<Permission> { public static final String SUBMIT_AS = "submitAs"; public static final String TOGGLE_WORK_IN_PROGRESS_STATE = "toggleWipState"; public static final String VIEW_PRIVATE_CHANGES = "viewPrivateChanges"; + public static final String QT_STAGE = "stage"; private static final List<String> NAMES_LC; private static final int LABEL_INDEX; @@ -81,6 +82,7 @@ public class Permission implements Comparable<Permission> { NAMES_LC.add(SUBMIT_AS.toLowerCase()); NAMES_LC.add(TOGGLE_WORK_IN_PROGRESS_STATE.toLowerCase()); NAMES_LC.add(VIEW_PRIVATE_CHANGES.toLowerCase()); + NAMES_LC.add(QT_STAGE.toLowerCase()); LABEL_INDEX = NAMES_LC.indexOf(Permission.LABEL); LABEL_AS_INDEX = NAMES_LC.indexOf(Permission.LABEL_AS.toLowerCase()); diff --git a/java/com/google/gerrit/entities/Change.java b/java/com/google/gerrit/entities/Change.java index 739bd38097..00bfd911e0 100644 --- a/java/com/google/gerrit/entities/Change.java +++ b/java/com/google/gerrit/entities/Change.java @@ -324,9 +324,16 @@ public final class Change { private static final char MIN_OPEN = 'a'; /** Database constant for {@link Status#NEW}. */ public static final char STATUS_NEW = 'n'; + /** Maximum database status constant for an open change. */ private static final char MAX_OPEN = 'z'; + /** Database constant for {@link Status#STAGED}. */ + public static final char STATUS_STAGED = 'R'; + + /** Database constant for {@link Status#INTEGRATING}. */ + public static final char STATUS_INTEGRATING = 'I'; + /** Database constant for {@link Status#MERGED}. */ public static final char STATUS_MERGED = 'M'; @@ -360,6 +367,9 @@ public final class Change { */ NEW(STATUS_NEW, ChangeStatus.NEW), + STAGED(STATUS_STAGED, ChangeStatus.STAGED), + INTEGRATING(STATUS_INTEGRATING, ChangeStatus.INTEGRATING), + /** * Change is closed, and submitted to its destination branch. * @@ -374,7 +384,9 @@ public final class Change { * patch set, and it cannot be merged. Draft comments however may be published, permitting * reviewers to send constructive feedback. */ - ABANDONED('A', ChangeStatus.ABANDONED); + ABANDONED('A', ChangeStatus.ABANDONED), + + DEFERRED('D', ChangeStatus.DEFERRED); static { boolean ok = true; @@ -698,8 +710,18 @@ public final class Change { return getStatus().equals(Status.ABANDONED); } + public boolean isIntegrating() { + return getStatus().equals(Status.INTEGRATING); + } + public boolean isStaged() { + return getStatus().equals(Status.STAGED); + } + public boolean isDeferred() { + return getStatus().equals(Status.DEFERRED); + } + public boolean isClosed() { - return isAbandoned() || isMerged(); + return isAbandoned() || isMerged() || isStaged() || isIntegrating() || isDeferred(); } public String getTopic() { diff --git a/java/com/google/gerrit/extensions/client/ChangeStatus.java b/java/com/google/gerrit/extensions/client/ChangeStatus.java index 83d5bd2cc7..89cdf5d468 100644 --- a/java/com/google/gerrit/extensions/client/ChangeStatus.java +++ b/java/com/google/gerrit/extensions/client/ChangeStatus.java @@ -34,6 +34,22 @@ public enum ChangeStatus { NEW, /** + * Change is staged and waiting for CI to start a build of it. + * + * <p> While a change is staged, it cannot be further modified by adding a replacement patch + * set. + */ + STAGED, + + /** + * Change is integrating in a build on a CI system. + * + * <p> While a change is integrating, it cannot be further modified by adding a replacement patch + * set. + */ + INTEGRATING, + + /** * Change is closed, and submitted to its destination branch. * * <p>Once a change has been merged, it cannot be further modified by adding a replacement patch @@ -54,5 +70,21 @@ public enum ChangeStatus { * <li>{@link #NEW} - when the Restore action is used. * </ul> */ - ABANDONED + ABANDONED, + + /** + * Change is closed, but was not submitted to its destination branch. Deferred is similar + * to abandoned, the difference is that the change is expected to be reopened later. + * + * <p>Once a change has been deferred, it cannot be further modified by adding a replacement + * patch set, and it cannot be merged. Draft comments however may be published, permitting + * reviewers to send constructive feedback. + * + * <p>Changes in the DEFERRED state can be moved to: + * + * <ul> + * <li>{@link #NEW} - when the Reopen action is used. + * </ul> + */ + DEFERRED } diff --git a/java/com/google/gerrit/server/permissions/ChangeControl.java b/java/com/google/gerrit/server/permissions/ChangeControl.java index cecdb959a6..dd5ff821e4 100644 --- a/java/com/google/gerrit/server/permissions/ChangeControl.java +++ b/java/com/google/gerrit/server/permissions/ChangeControl.java @@ -321,6 +321,8 @@ class ChangeControl { case REMOVE_REVIEWER: case SUBMIT_AS: return refControl.canPerform(changePermissionName(perm)); + case QT_STAGE: + return refControl.canPerform(Permission.QT_STAGE); } } catch (StorageException e) { throw new PermissionBackendException("unavailable", e); diff --git a/java/com/google/gerrit/server/permissions/ChangePermission.java b/java/com/google/gerrit/server/permissions/ChangePermission.java index 2fba4ef039..458c01f63d 100644 --- a/java/com/google/gerrit/server/permissions/ChangePermission.java +++ b/java/com/google/gerrit/server/permissions/ChangePermission.java @@ -56,7 +56,8 @@ public enum ChangePermission implements ChangePermissionOrLabel { REBASE, SUBMIT, SUBMIT_AS("submit on behalf of other users"), - TOGGLE_WORK_IN_PROGRESS_STATE; + TOGGLE_WORK_IN_PROGRESS_STATE, + QT_STAGE("stage change for CI"); private final String description; diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java index 82150831d3..f17cc05912 100644 --- a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java +++ b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java @@ -101,6 +101,7 @@ public class DefaultPermissionMappings { .put( ChangePermission.TOGGLE_WORK_IN_PROGRESS_STATE, Permission.TOGGLE_WORK_IN_PROGRESS_STATE) + .put(ChangePermission.QT_STAGE, Permission.QT_STAGE) .build(); private static <T extends Enum<T>> void checkMapContainsAllEnumValues( diff --git a/java/com/google/gerrit/server/query/change/InternalChangeQuery.java b/java/com/google/gerrit/server/query/change/InternalChangeQuery.java index 6605c23da2..6c3d003131 100644 --- a/java/com/google/gerrit/server/query/change/InternalChangeQuery.java +++ b/java/com/google/gerrit/server/query/change/InternalChangeQuery.java @@ -152,6 +152,10 @@ public class InternalChangeQuery extends InternalQuery<ChangeData, InternalChang return query(and(ref(branch), project(branch.project()), status(Change.Status.NEW))); } + public List<ChangeData> byBranchStatus(BranchNameKey branch, Change.Status status) { + return query(and(ref(branch), project(branch.project()), status(status))); + } + public Iterable<ChangeData> byCommitsOnBranchNotMerged( Repository repo, BranchNameKey branch, Collection<String> hashes) throws IOException { return byCommitsOnBranchNotMerged( diff --git a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html index 0c75c44887..8161024f42 100644 --- a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html +++ b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior.html @@ -112,6 +112,10 @@ limitations under the License. id: 'removeReviewer', name: 'Remove Reviewer', }, + stage: { + id: 'stage', + name: 'QtStage', + }, submit: { id: 'submit', name: 'Submit', diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html index 85bc6a194d..5d08eda65f 100644 --- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html +++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html @@ -35,8 +35,11 @@ limitations under the License. ChangeStatus: { ABANDONED: 'ABANDONED', + DEFERRED: 'DEFERRED', + INTEGRATING: 'INTEGRATING', MERGED: 'MERGED', NEW: 'NEW', + STAGED: 'STAGED', }, // Must be kept in sync with the ListChangesOption enum and protobuf. @@ -145,6 +148,12 @@ limitations under the License. states.push('Merged'); } else if (change.status === this.ChangeStatus.ABANDONED) { states.push('Abandoned'); + } else if (change.status === this.ChangeStatus.DEFERRED) { + states.push('Deferred'); + } else if (change.status === this.ChangeStatus.INTEGRATING) { + states.push('Integrating'); + } else if (change.status === this.ChangeStatus.STAGED) { + states.push('Staged'); } else if (change.mergeable === false || (opt_options && opt_options.mergeable === false)) { // 'mergeable' prop may not always exist (@see Issue 6819) diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js index 02cf861afa..4532a04a5d 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js @@ -1532,7 +1532,10 @@ // changes are obviously not mergeable, but the mergeability API will not // answer for abandoned changes. if (this._change.status === this.ChangeStatus.MERGED || - this._change.status === this.ChangeStatus.ABANDONED) { + this._change.status === this.ChangeStatus.STAGED || + this._change.status === this.ChangeStatus.INTEGRATING || + this._change.status === this.ChangeStatus.ABANDONED || + this._change.status === this.ChangeStatus.DEFERRED) { this._mergeable = false; return Promise.resolve(); } diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html index c607a9f899..75409951c6 100644 --- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html +++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html @@ -38,6 +38,7 @@ limitations under the License. } </style> <template is="dom-repeat" items="[[_labels]]" as="label"> + <gr-endpoint-decorator name$="[[_computeDecoratorName('review-label-scores-', label.name)]]"> <gr-label-score-row class$="[[_computeLabelAccessClass(label.name, permittedLabels)]]" label="[[label]]" @@ -45,6 +46,7 @@ limitations under the License. labels="[[change.labels]]" permitted-labels="[[permittedLabels]]" label-values="[[_labelValues]]"></gr-label-score-row> + </gr-endpoint-decorator> </template> <div class="mergedMessage" hidden$="[[!_changeIsMerged(change.status)]]"> diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js index dffba3e60d..912ccae080 100644 --- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js +++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js @@ -82,6 +82,10 @@ return null; }, + _computeDecoratorName(preString, name) { + return preString + name.toLowerCase(); + }, + _computeLabels(labelRecord, account) { // Polymer 2: check for undefined if ([labelRecord, account].some(arg => arg === undefined)) { diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html index d29858eedd..25823849a6 100644 --- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html +++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html @@ -189,6 +189,7 @@ limitations under the License. <ul class="links"> <template is="dom-repeat" items="[[_links]]" as="linkGroup"> <li class$="[[_computeLinkGroupClass(linkGroup)]]"> + <gr-endpoint-decorator name$="[[_computeDecoratorName('header-dropdown-', linkGroup.title)]]"> <gr-dropdown link down-arrow @@ -198,6 +199,7 @@ limitations under the License. [[linkGroup.title]] </span> </gr-dropdown> + </gr-endpoint-decorator> </li> </template> </ul> diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js index 773ad68dc6..a02fc9a9ba 100644 --- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js +++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.js @@ -179,6 +179,10 @@ return '//' + window.location.host + this.getBaseUrl() + path; }, + _computeDecoratorName(preString, name) { + return preString + name.toLowerCase(); + }, + _computeLinks(defaultLinks, userLinks, adminLinks, topMenus, docBaseUrl) { // Polymer 2: check for undefined if ([ diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html index c8bf6c1236..533a4f4d34 100644 --- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html +++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html @@ -151,12 +151,19 @@ limitations under the License. suffixForDashboard: 'limit:10', }, { + name: 'Integrating', + query: '(is:staged OR is:integrating) -is:ignored (-is:wip OR owner:self) ' + + '(owner:${user} OR reviewer:${user} OR assignee:${user} ' + + 'OR cc:${user})', + suffixForDashboard: 'limit:20', + }, + { name: 'Recently closed', // Closed changes where viewed user is owner, reviewer, or assignee. // Changes ignored by the viewing user are filtered out, and so are WIP // changes not owned by the viewing user (the one instance of // 'owner:self' is intentional and implements this logic). - query: 'is:closed -is:ignored (-is:wip OR owner:self) ' + + query: '(is:merged OR is:abandoned OR is:deferred) -is:ignored (-is:wip OR owner:self) ' + '(owner:${user} OR reviewer:${user} OR assignee:${user} ' + 'OR cc:${user})', suffixForDashboard: '-age:4w limit:10', diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js index 0030babe97..f2f7d6d5e8 100644 --- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js +++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.js @@ -90,6 +90,8 @@ 'status:merged', 'status:open', 'status:reviewed', + 'status:integrating', + 'status:staged', 'topic:', 'tr:', ]; diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html index 55623b36f0..d56c59242d 100644 --- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html +++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html @@ -38,6 +38,18 @@ limitations under the License. background-color: #afafaf; color: #afafaf; } + :host(.deferred) .chip { + background-color: #afafaf; + color: #afafaf; + } + :host(.integrating) .chip { + background-color: #999900; + color: #999900; + } + :host(.staged) .chip { + background-color: #cccc00; + color: #cccc00; + } :host(.wip) .chip { background-color: #8f756c; color: #8f756c; diff --git a/polygerrit-ui/app/styles/themes/dark-theme.html b/polygerrit-ui/app/styles/themes/dark-theme.html index 957cc25344..1e72e3d3fd 100644 --- a/polygerrit-ui/app/styles/themes/dark-theme.html +++ b/polygerrit-ui/app/styles/themes/dark-theme.html @@ -80,7 +80,7 @@ limitations under the License. /* header and footer */ --footer-background-color: #131416; --footer-border-top: 1px solid var(--border-color); - --header-background-color: #3c4043; + --header-background-color: rgb(53, 54, 55); --header-border-bottom: 1px solid var(--border-color); --header-padding: 0 var(--spacing-l); --header-text-color: var(--primary-text-color); diff --git a/tools/workspace_status.py b/tools/workspace_status.py index 86df519ed5..84b548c732 100644 --- a/tools/workspace_status.py +++ b/tools/workspace_status.py @@ -35,7 +35,7 @@ def revision(directory, parent): os.chdir(parent) -print("STABLE_BUILD_GERRIT_LABEL %s" % revision(ROOT, ROOT)) +print("STABLE_BUILD_GERRIT_LABEL %s-QtFork" % revision(ROOT, ROOT)) for d in os.listdir(os.path.join(ROOT, 'plugins')): p = os.path.join('plugins', d) if os.path.isdir(p): |