Merge "edit: Prevent adding, restoring, renaming or deleting if input is empty"
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index 3253282..0d710b9 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -126,12 +126,12 @@
public static final String KEY_CAN_OVERRIDE = "canOverride";
public static final String KEY_BRANCH = "branch";
- public static final String SUBMIT_REQUIREMENT = "submitRequirement";
+ public static final String SUBMIT_REQUIREMENT = "submit-requirement";
public static final String KEY_SR_NAME = "name";
public static final String KEY_SR_DESCRIPTION = "description";
- public static final String KEY_SR_APPLICABILITY_EXPRESSION = "applicabilityExpression";
- public static final String KEY_SR_SUBMITTABILITY_EXPRESSION = "submittabilityExpression";
- public static final String KEY_SR_OVERRIDE_EXPRESSION = "overrideExpression";
+ public static final String KEY_SR_APPLICABILITY_EXPRESSION = "applicableIf";
+ public static final String KEY_SR_SUBMITTABILITY_EXPRESSION = "submittableIf";
+ public static final String KEY_SR_OVERRIDE_EXPRESSION = "overrideIf";
public static final String KEY_SR_OVERRIDE_IN_CHILD_PROJECTS = "canOverrideInChildProjects";
public static final String KEY_MATCH = "match";
diff --git a/java/com/google/gerrit/server/update/BatchUpdate.java b/java/com/google/gerrit/server/update/BatchUpdate.java
index 3b0cd9a..f558d30 100644
--- a/java/com/google/gerrit/server/update/BatchUpdate.java
+++ b/java/com/google/gerrit/server/update/BatchUpdate.java
@@ -75,6 +75,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.TimeZone;
@@ -553,11 +554,15 @@
try {
logDebug("Executing updateRepo on %d ops", ops.size());
RepoContextImpl ctx = new RepoContextImpl();
- for (BatchUpdateOp op : ops.values()) {
+ for (Entry<Change.Id, BatchUpdateOp> op : ops.entries()) {
try (TraceContext.TraceTimer ignored =
TraceContext.newTimer(
- op.getClass().getSimpleName() + "#updateRepo", Metadata.empty())) {
- op.updateRepo(ctx);
+ op.getClass().getSimpleName() + "#updateRepo",
+ Metadata.builder()
+ .projectName(project.get())
+ .changeId(op.getKey().get())
+ .build())) {
+ op.getValue().updateRepo(ctx);
}
}
@@ -672,7 +677,8 @@
for (BatchUpdateOp op : e.getValue()) {
try (TraceContext.TraceTimer ignored =
TraceContext.newTimer(
- op.getClass().getSimpleName() + "#updateChange", Metadata.empty())) {
+ op.getClass().getSimpleName() + "#updateChange",
+ Metadata.builder().projectName(project.get()).changeId(id.get()).build())) {
dirty |= op.updateChange(ctx);
}
}
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index 2e934e9..9130d3e 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -209,15 +209,15 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submitRequirement \"Code-review\"]\n"
+ "[submit-requirement \"Code-review\"]\n"
+ " description = At least one Code Review +2\n"
- + " applicabilityExpression = branch(refs/heads/master)\n"
- + " submittabilityExpression = label(code-review, +2)\n"
- + "[submitRequirement \"api-review\"]\n"
+ + " applicableIf =branch(refs/heads/master)\n"
+ + " submittableIf = label(code-review, +2)\n"
+ + "[submit-requirement \"api-review\"]\n"
+ " description = Additional review required for API modifications\n"
- + " applicabilityExpression = commit_filepath_contains(\\\"/api/.*\\\")\n"
- + " submittabilityExpression = label(api-review, +2)\n"
- + " overrideExpression = label(build-cop-override, +1)\n"
+ + " applicableIf =commit_filepath_contains(\\\"/api/.*\\\")\n"
+ + " submittableIf = label(api-review, +2)\n"
+ + " overrideIf = label(build-cop-override, +1)\n"
+ " canOverrideInChildProjects = true\n")
.create();
@@ -257,8 +257,8 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submitRequirement \"code-review\"]\n"
- + " submittabilityExpression = label(code-review, +2)\n")
+ "[submit-requirement \"code-review\"]\n"
+ + " submittableIf = label(code-review, +2)\n")
.create();
ProjectConfig cfg = read(rev);
@@ -281,12 +281,12 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submitRequirement \"code-review\"]\n"
+ "[submit-requirement \"code-review\"]\n"
+ " description = At least one Code Review +2\n"
- + " submittabilityExpression = label(code-review, +2)\n"
- + "[submitRequirement \"Code-Review\"]\n"
+ + " submittableIf = label(code-review, +2)\n"
+ + "[submit-requirement \"Code-Review\"]\n"
+ " description = Another code review label\n"
- + " submittabilityExpression = label(code-review, +2)\n"
+ + " submittableIf = label(code-review, +2)\n"
+ " canOverrideInChildProjects = true\n")
.create();
@@ -317,8 +317,8 @@
.add("groups", group(developers))
.add(
"project.config",
- "[submitRequirement \"code-review\"]\n"
- + " applicabilityExpression = label(code-review, +2)\n")
+ "[submit-requirement \"code-review\"]\n"
+ + " applicableIf =label(code-review, +2)\n")
.create();
ProjectConfig cfg = read(rev);
@@ -943,10 +943,10 @@
tr.commit()
.add(
"project.config",
- "[submitRequirement \"code-review\"]\n"
+ "[submit-requirement \"code-review\"]\n"
+ " description = At least one Code Review +2\n"
- + " applicabilityExpression = branch(refs/heads/master)\n"
- + " submittabilityExpression = label(code-review, +2)\n"
+ + " applicableIf =branch(refs/heads/master)\n"
+ + " submittableIf = label(code-review, +2)\n"
+ "[notify \"name\"]\n"
+ " email = example@example.com\n")
.create();
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 1591738..fcf1cf4 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -121,8 +121,6 @@
"elements/gr-app-element_html.ts",
"elements/settings/gr-settings-view/gr-settings-view_html.ts",
"elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_html.ts",
- "elements/shared/gr-account-entry/gr-account-entry_html.ts",
- "elements/shared/gr-account-label/gr-account-label_html.ts",
"elements/shared/gr-account-list/gr-account-list_html.ts",
"elements/shared/gr-autocomplete/gr-autocomplete_html.ts",
"elements/shared/gr-change-status/gr-change-status_html.ts",
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
index 5436128..f703037 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.ts
@@ -173,9 +173,9 @@
<gr-account-link
.account="${this.account}"
.change="${this.change}"
- ?force-attention=${this.forceAttention}
- ?highlight-attention=${this.highlightAttention}
- .voteable-text=${this.voteableText}
+ ?forceAttention=${this.forceAttention}
+ ?highlightAttention=${this.highlightAttention}
+ .voteableText=${this.voteableText}
>
</gr-account-link>
<gr-button
diff --git a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.ts b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.ts
index 944054e..c250428 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry.ts
@@ -54,13 +54,13 @@
*/
@property({type: Boolean})
- allowAnyInput?: boolean;
+ allowAnyInput = false;
@property({type: Boolean})
- borderless?: boolean;
+ borderless = false;
@property({type: String})
- placeholder?: string;
+ placeholder = '';
@property({type: Number})
suggestFrom = 0;
@@ -69,7 +69,7 @@
querySuggestions: AutocompleteQuery = () => Promise.resolve([]);
@property({type: String, observer: '_inputTextChanged'})
- _inputText?: string;
+ _inputText = '';
get focusStart() {
return this.$.input.focusStart;
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
index d7078ed..cc66734 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
@@ -190,11 +190,7 @@
: '';
}
- _computeName(
- account?: AccountInfo,
- config?: ServerInfo,
- firstName?: boolean
- ) {
+ _computeName(account: AccountInfo, firstName: boolean, config?: ServerInfo) {
return getDisplayName(config, account, firstName);
}
@@ -264,12 +260,12 @@
highlight: boolean,
account: AccountInfo,
change: ChangeInfo,
- selfAccount: AccountInfo,
- selected: boolean
+ selected: boolean,
+ selfAccount?: AccountInfo
) {
if (selected) return true;
return (
- this._hasUnforcedAttention(highlight, account, change) &&
+ !!this._hasUnforcedAttention(highlight, account, change) &&
(isInvolved(change, selfAccount) || isSelf(account, selfAccount))
);
}
@@ -278,16 +274,16 @@
highlight: boolean,
account: AccountInfo,
change: ChangeInfo,
- selfAccount: AccountInfo,
force: boolean,
- selected: boolean
+ selected: boolean,
+ selfAccount?: AccountInfo
) {
const enabled = this._computeAttentionButtonEnabled(
highlight,
account,
change,
- selfAccount,
- selected
+ selected,
+ selfAccount
);
return enabled
? 'Click to remove the user from the attention set'
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.ts
index 03178c7..352763b 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.ts
@@ -111,9 +111,9 @@
link=""
aria-label="Remove user from attention set"
on-click="_handleRemoveAttentionClick"
- disabled="[[!_computeAttentionButtonEnabled(highlightAttention, account, change, _selfAccount, selected)]]"
- has-tooltip="[[_computeAttentionButtonEnabled(highlightAttention, account, change, _selfAccount, false)]]"
- title="[[_computeAttentionIconTitle(highlightAttention, account, change, _selfAccount, forceAttention, selected)]]"
+ disabled="[[!_computeAttentionButtonEnabled(highlightAttention, account, change, selected, _selfAccount)]]"
+ has-tooltip="[[_computeAttentionButtonEnabled(highlightAttention, account, change, false, _selfAccount)]]"
+ title="[[_computeAttentionIconTitle(highlightAttention, account, change, forceAttention, selected, _selfAccount)]]"
><iron-icon class="attention" icon="gr-icons:attention"></iron-icon>
</gr-button>
</template>
@@ -126,7 +126,7 @@
<gr-avatar account="[[account]]" imageSize="32"></gr-avatar>
</template>
<span class="text" part="gr-account-label-text">
- <span class="name">[[_computeName(account, _config, firstName)]]</span>
+ <span class="name">[[_computeName(account, firstName, _config)]]</span>
<template is="dom-if" if="[[!hideStatus]]">
<template is="dom-if" if="[[account.status]]">
<iron-icon class="status" icon="gr-icons:calendar"></iron-icon>
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
index efaa9f7..574e450 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
@@ -55,12 +55,12 @@
suite('_computeName', () => {
test('not showing anonymous', () => {
const account = {name: 'Wyatt'};
- assert.deepEqual(element._computeName(account), 'Wyatt');
+ assert.deepEqual(element._computeName(account, false), 'Wyatt');
});
test('showing anonymous but no config', () => {
const account = {};
- assert.deepEqual(element._computeName(account), 'Anonymous');
+ assert.deepEqual(element._computeName(account, false), 'Anonymous');
});
test('test for Anonymous Coward user and replace with Anonymous', () => {
@@ -71,7 +71,10 @@
},
};
const account = {};
- assert.deepEqual(element._computeName(account, config), 'Anonymous');
+ assert.deepEqual(
+ element._computeName(account, false, config),
+ 'Anonymous'
+ );
});
test('test for anonymous_coward_name', () => {
@@ -82,7 +85,10 @@
},
};
const account = {};
- assert.deepEqual(element._computeName(account, config), 'TestAnon');
+ assert.deepEqual(
+ element._computeName(account, false, config),
+ 'TestAnon'
+ );
});
});
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
index 7298af7..6b5553d 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
@@ -15,12 +15,10 @@
* limitations under the License.
*/
import '../gr-linked-text/gr-linked-text';
-import '../../../styles/shared-styles';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {customElement, property} from '@polymer/decorators';
-import {htmlTemplate} from './gr-formatted-text_html';
import {CommentLinks} from '../../../types/common';
import {appContext} from '../../../services/app-context';
+import {GrLitElement} from '../../lit/gr-lit-element';
+import {css, customElement, html, property} from 'lit-element';
const CODE_MARKER_PATTERN = /^(`{1,3})([^`]+?)\1$/;
@@ -36,20 +34,9 @@
'gr-formatted-text': GrFormattedText;
}
}
-
-export interface GrFormattedText {
- $: {
- container: HTMLElement;
- };
-}
-
@customElement('gr-formatted-text')
-export class GrFormattedText extends PolymerElement {
- static get template() {
- return htmlTemplate;
- }
-
- @property({type: String, observer: '_contentChanged'})
+export class GrFormattedText extends GrLitElement {
+ @property({type: String})
content?: string;
@property({type: Object})
@@ -60,43 +47,70 @@
private readonly reporting = appContext.reportingService;
- static get observers() {
- return ['_contentOrConfigChanged(content, config)'];
+ static get styles() {
+ return [
+ css`
+ :host {
+ display: block;
+ font-family: var(--font-family);
+ }
+ p,
+ ul,
+ code,
+ blockquote,
+ gr-linked-text.pre {
+ margin: 0 0 var(--spacing-m) 0;
+ }
+ p,
+ ul,
+ code,
+ blockquote {
+ max-width: var(--gr-formatted-text-prose-max-width, none);
+ }
+ :host(.noTrailingMargin) p:last-child,
+ :host(.noTrailingMargin) ul:last-child,
+ :host(.noTrailingMargin) blockquote:last-child,
+ :host(.noTrailingMargin) gr-linked-text.pre:last-child {
+ margin: 0;
+ }
+ code,
+ blockquote {
+ border-left: 1px solid #aaa;
+ padding: 0 var(--spacing-m);
+ }
+ code {
+ display: block;
+ white-space: pre-wrap;
+ color: var(--deemphasized-text-color);
+ }
+ li {
+ list-style-type: disc;
+ margin-left: var(--spacing-xl);
+ }
+ code,
+ gr-linked-text.pre {
+ font-family: var(--monospace-font-family);
+ font-size: var(--font-size-code);
+ /* usually 16px = 12px + 4px */
+ line-height: calc(var(--font-size-code) + var(--spacing-s));
+ }
+ `,
+ ];
}
- /** @override */
- ready() {
- super.ready();
+ render() {
+ const nodes = this._computeNodes(this._computeBlocks(this.content));
+ return html`<div id="container">${nodes}</div>`;
+ }
+
+ constructor() {
+ super();
+
if (this.noTrailingMargin) {
this.classList.add('noTrailingMargin');
}
}
- _contentChanged(content: string) {
- // In the case where the config may not be set (perhaps due to the
- // request for it still being in flight), set the content anyway to
- // prevent waiting on the config to display the text.
- if (this.config) return;
- this._contentOrConfigChanged(content);
- }
-
- /**
- * Given a source string, update the DOM inside #container.
- */
- _contentOrConfigChanged(content?: string) {
- const container = this.$.container;
-
- // Remove existing content.
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
-
- // Add new content.
- for (const node of this._computeNodes(this._computeBlocks(content))) {
- if (node) container.appendChild(node);
- }
- }
-
/**
* Given a source string, parse into an array of block objects. Each block
* has a `type` property which takes any of the following values.
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_html.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_html.ts
deleted file mode 100644
index 04e4954..0000000
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_html.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 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.
- */
-import {html} from '@polymer/polymer/lib/utils/html-tag';
-
-export const htmlTemplate = html`
- <style>
- :host {
- display: block;
- font-family: var(--font-family);
- }
- p,
- ul,
- code,
- blockquote,
- gr-linked-text.pre {
- margin: 0 0 var(--spacing-m) 0;
- }
- p,
- ul,
- code,
- blockquote {
- max-width: var(--gr-formatted-text-prose-max-width, none);
- }
- :host(.noTrailingMargin) p:last-child,
- :host(.noTrailingMargin) ul:last-child,
- :host(.noTrailingMargin) blockquote:last-child,
- :host(.noTrailingMargin) gr-linked-text.pre:last-child {
- margin: 0;
- }
- code,
- blockquote {
- border-left: 1px solid #aaa;
- padding: 0 var(--spacing-m);
- }
- code {
- display: block;
- white-space: pre-wrap;
- color: var(--deemphasized-text-color);
- }
- li {
- list-style-type: disc;
- margin-left: var(--spacing-xl);
- }
- code,
- gr-linked-text.pre {
- font-family: var(--monospace-font-family);
- font-size: var(--font-size-code);
- /* usually 16px = 12px + 4px */
- line-height: calc(var(--font-size-code) + var(--spacing-s));
- }
- </style>
- <div id="container"></div>
-`;
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
index fd5a9ba..3e05f11 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
@@ -387,20 +387,5 @@
assert.equal(result[3].type, 'code');
assert.equal(result[4].type, 'quote');
});
-
- test('_computeNodes called without config', () => {
- const computeNodesSpy = sinon.spy(element, '_computeNodes');
- element.content = 'some text';
- assert.isTrue(computeNodesSpy.called);
- });
-
- test('_contentOrConfigChanged called with config', () => {
- const contentStub = sinon.stub(element, '_contentChanged');
- const contentConfigStub = sinon.stub(element, '_contentOrConfigChanged');
- element.content = 'some text';
- element.config = {};
- assert.isTrue(contentStub.called);
- assert.isTrue(contentConfigStub.called);
- });
});
diff --git a/polygerrit-ui/app/types/events.ts b/polygerrit-ui/app/types/events.ts
index 6e37697..5145527 100644
--- a/polygerrit-ui/app/types/events.ts
+++ b/polygerrit-ui/app/types/events.ts
@@ -26,6 +26,7 @@
CHANGE = 'change',
CHANGED = 'changed',
CHANGE_MESSAGE_DELETED = 'change-message-deleted',
+ COMMIT = 'commit',
DIALOG_CHANGE = 'dialog-change',
DROP = 'drop',
EDITABLE_CONTENT_SAVE = 'editable-content-save',
@@ -58,6 +59,8 @@
/* prettier-ignore */
'changed': ChangedEvent;
'change-message-deleted': ChangeMessageDeletedEvent;
+ /* prettier-ignore */
+ 'commit': CommitEvent;
'dialog-change': DialogChangeEvent;
/* prettier-ignore */
'drop': DropEvent;
@@ -109,6 +112,8 @@
}
export type ChangeMessageDeletedEvent = CustomEvent<ChangeMessageDeletedEventDetail>;
+export type CommitEvent = CustomEvent;
+
// TODO(milutin) - remove once new gr-dialog will do it out of the box
// This informs gr-app-element to remove footer, header from a11y tree
export interface DialogChangeEventDetail {