Merge branch 'stable-3.1'
* stable-3.1:
Upgrade bazlets to latest stable-2.16 to build with 2.16.18 API
Bump Bazel version to 3.1.0
Change-Id: I28a5ac8be5fd1abf909f4fd4f177c7589028c066
diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.eslintignore
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..a43acc6
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,167 @@
+{
+ "extends": ["eslint:recommended", "google"],
+ "parserOptions": {
+ "ecmaVersion": 8,
+ "sourceType": "module"
+ },
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "globals": {
+ "__dirname": false,
+ "app": false,
+ "page": false,
+ "Polymer": false,
+ "process": false,
+ "require": false,
+ "Gerrit": false,
+ "Promise": false,
+ "assert": false,
+ "test": false,
+ "flushAsynchronousOperations": false
+ },
+ "rules": {
+ "arrow-parens": ["error", "as-needed"],
+ "block-spacing": ["error", "always"],
+ "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
+ "camelcase": "off",
+ "comma-dangle": ["error", {
+ "arrays": "always-multiline",
+ "objects": "always-multiline",
+ "imports": "always-multiline",
+ "exports": "always-multiline",
+ "functions": "never"
+ }],
+ "eol-last": "off",
+ "indent": ["error", 2, {
+ "MemberExpression": 2,
+ "FunctionDeclaration": {"body": 1, "parameters": 2},
+ "FunctionExpression": {"body": 1, "parameters": 2},
+ "CallExpression": {"arguments": 2 },
+ "ArrayExpression": 1,
+ "ObjectExpression": 1,
+ "SwitchCase": 1
+ }],
+ "keyword-spacing": ["error", { "after": true, "before": true }],
+ "lines-between-class-members": ["error", "always"],
+ "max-len": [
+ "error",
+ 80,
+ 2,
+ {
+ "ignoreComments": true,
+ "ignorePattern": "^import .*;$"
+ }
+ ],
+ "new-cap": ["error", { "capIsNewExceptions": ["Polymer", "LegacyElementMixin", "GestureEventListeners", "LegacyDataMixin"] }],
+ "no-console": "off",
+ "no-multiple-empty-lines": [ "error", { "max": 1 } ],
+ "no-prototype-builtins": "off",
+ "no-redeclare": "off",
+ "no-restricted-syntax": [
+ "error",
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='test'][property.name='only']",
+ "message": "Remove test.only."
+ },
+ {
+ "selector": "ExpressionStatement > CallExpression > MemberExpression[object.name='suite'][property.name='only']",
+ "message": "Remove suite.only."
+ }
+ ],
+ "no-undef": "off",
+ "no-useless-escape": "off",
+ "no-var": "error",
+ "object-shorthand": ["error", "always"],
+ "padding-line-between-statements": [
+ "error",
+ {
+ "blankLine": "always",
+ "prev": "class",
+ "next": "*"
+ },
+ {
+ "blankLine": "always",
+ "prev": "*",
+ "next": "class"
+ }
+ ],
+ "prefer-arrow-callback": "error",
+ "prefer-const": "error",
+ "prefer-spread": "error",
+ "quote-props": ["error", "consistent-as-needed"],
+ "require-jsdoc": "off",
+ "semi": [2, "always"],
+ "template-curly-spacing": "error",
+ "valid-jsdoc": "off",
+
+ "require-jsdoc": 0,
+ "valid-jsdoc": 0,
+ "jsdoc/check-alignment": 2,
+ "jsdoc/check-examples": 0,
+ "jsdoc/check-indentation": 0,
+ "jsdoc/check-param-names": 0,
+ "jsdoc/check-syntax": 0,
+ "jsdoc/check-tag-names": 0,
+ "jsdoc/check-types": 0,
+ "jsdoc/implements-on-classes": 2,
+ "jsdoc/match-description": 0,
+ "jsdoc/newline-after-description": 2,
+ "jsdoc/no-types": 0,
+ "jsdoc/no-undefined-types": 0,
+ "jsdoc/require-description": 0,
+ "jsdoc/require-description-complete-sentence": 0,
+ "jsdoc/require-example": 0,
+ "jsdoc/require-hyphen-before-param-description": 0,
+ "jsdoc/require-jsdoc": 0,
+ "jsdoc/require-param": 0,
+ "jsdoc/require-param-description": 0,
+ "jsdoc/require-param-name": 2,
+ "jsdoc/require-param-type": 2,
+ "jsdoc/require-returns": 0,
+ "jsdoc/require-returns-check": 0,
+ "jsdoc/require-returns-description": 0,
+ "jsdoc/require-returns-type": 2,
+ "jsdoc/valid-types": 2,
+ "jsdoc/require-file-overview": ["error", {
+ "tags": {
+ "license": {
+ "mustExist": true,
+ "preventDuplicates": true
+ }
+ }
+ }],
+ "import/named": 2,
+ "import/no-unresolved": 2,
+ "import/no-self-import": 2,
+ // The no-cycle rule is slow, because it doesn't cache dependencies.
+ // Disable it.
+ "import/no-cycle": 0,
+ "import/no-useless-path-segments": 2,
+ "import/no-unused-modules": 2,
+ "import/no-default-export": 2
+ },
+ "plugins": [
+ "html",
+ "jsdoc",
+ "import"
+ ],
+ "settings": {
+ "html/report-bad-indent": "error"
+ },
+ "overrides": [
+ {
+ "files": ["*_html.js", "*-styles.js", "externs.js"],
+ "rules": {
+ "max-len": "off"
+ }
+ },
+ {
+ "files": ["*.html"],
+ "rules": {
+ "jsdoc/require-file-overview": "off"
+ }
+ }
+ ]
+}
diff --git a/BUILD b/BUILD
index 819cac0..7008531 100644
--- a/BUILD
+++ b/BUILD
@@ -1,5 +1,7 @@
load("@rules_java//java:defs.bzl", "java_library")
+load("@npm_bazel_rollup//:index.bzl", "rollup_bundle")
load("//tools/bzl:junit.bzl", "junit_tests")
+load("//tools/js:eslint.bzl", "eslint")
load(
"//tools/bzl:plugin.bzl",
"PLUGIN_DEPS",
@@ -29,7 +31,7 @@
outs = ["gr-delete-repo-static.jar"],
cmd = " && ".join([
"mkdir $$TMP/static",
- "cp -r $(locations :gr-delete-repo) $$TMP/static",
+ "cp $(locations :gr-delete-repo) $$TMP/static",
"cd $$TMP",
"zip -Drq $$ROOT/$@ -g .",
]),
@@ -37,11 +39,19 @@
polygerrit_plugin(
name = "gr-delete-repo",
- srcs = glob([
- "gr-delete-repo/*.html",
- "gr-delete-repo/*.js",
- ]),
- app = "plugin.html",
+ app = "delete-project-bundle.js",
+ plugin_name = "delete-project",
+)
+
+rollup_bundle(
+ name = "delete-project-bundle",
+ srcs = glob(["gr-delete-repo/*.js"]),
+ entry_point = "gr-delete-repo/plugin.js",
+ rollup_bin = "//tools/node_tools:rollup-bin",
+ sourcemap = "hidden",
+ deps = [
+ "@tools_npm//rollup-plugin-node-resolve",
+ ],
)
junit_tests(
@@ -63,3 +73,24 @@
"@mockito//jar",
],
)
+
+# Define the eslinter for the plugin
+# The eslint macro creates 2 rules: lint_test and lint_bin
+eslint(
+ name = "lint",
+ srcs = glob([
+ "gr-delete-repo/**/*.js",
+ ]),
+ config = ".eslintrc.json",
+ data = [],
+ extensions = [
+ ".js",
+ ],
+ ignore = ".eslintignore",
+ plugins = [
+ "@npm//eslint-config-google",
+ "@npm//eslint-plugin-html",
+ "@npm//eslint-plugin-import",
+ "@npm//eslint-plugin-jsdoc",
+ ],
+)
diff --git a/gr-delete-repo/gr-delete-repo.js b/gr-delete-repo/gr-delete-repo.js
index 8055070..9afef3c 100644
--- a/gr-delete-repo/gr-delete-repo.js
+++ b/gr-delete-repo/gr-delete-repo.js
@@ -1,63 +1,79 @@
-// Copyright (C) 2018 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.
-(function() {
- 'use strict';
+/**
+ * @license
+ * Copyright (C) 2018 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.
+ */
- Polymer({
- is: 'gr-delete-repo',
+import {htmlTemplate} from './gr-delete-repo_html.js';
- properties: {
+class GrDeleteRepo extends Polymer.Element {
+ /** @returns {string} name of the component */
+ static get is() { return 'gr-delete-repo'; }
+
+ /** @returns {?} template for this component */
+ static get template() { return htmlTemplate; }
+
+ /**
+ * Defines properties of the component
+ *
+ * @returns {?}
+ */
+ static get properties() {
+ return {
repoName: String,
config: Object,
action: Object,
actionId: String,
- },
+ };
+ }
- attached() {
- this.actionId = this.plugin.getPluginName() + '~delete';
- this.action = this.config.actions[this.actionId];
- this.hidden = !this.action;
- },
+ connectedCallback() {
+ super.connectedCallback();
+ this.actionId = this.plugin.getPluginName() + '~delete';
+ this.action = this.config.actions[this.actionId];
+ this.hidden = !this.action;
+ }
- _handleCommandTap() {
- this.$.deleteRepoOverlay.open();
- },
+ _handleCommandTap() {
+ this.$.deleteRepoOverlay.open();
+ }
- _handleCloseDeleteRepo() {
- this.$.deleteRepoOverlay.close();
- },
+ _handleCloseDeleteRepo() {
+ this.$.deleteRepoOverlay.close();
+ }
- _handleDeleteRepo() {
- const endpoint = '/projects/' +
- encodeURIComponent(this.repoName) + '/' +
- this.actionId;
+ _handleDeleteRepo() {
+ const endpoint = '/projects/' +
+ encodeURIComponent(this.repoName) + '/' +
+ this.actionId;
- const json = {
- force: this.$.forceDeleteOpenChangesCheckBox.checked,
- preserve: this.$.preserveGitRepoCheckBox.checked
- };
+ const json = {
+ force: this.$.forceDeleteOpenChangesCheckBox.checked,
+ preserve: this.$.preserveGitRepoCheckBox.checked,
+ };
- const errFn = response => {
- this.fire('page-error', {response});
- };
+ const errFn = response => {
+ this.fire('page-error', {response});
+ };
- return this.plugin.restApi().send(
- this.action.method, endpoint, json, errFn)
- .then(r => {
- this.plugin.restApi().invalidateReposCache();
- Gerrit.Nav.navigateToRelativeUrl('/admin/repos');
- });
- },
- });
-})();
+ return this.plugin.restApi().send(
+ this.action.method, endpoint, json, errFn)
+ .then(r => {
+ this.plugin.restApi().invalidateReposCache();
+ Gerrit.Nav.navigateToRelativeUrl('/admin/repos');
+ });
+ }
+}
+
+customElements.define(GrDeleteRepo.is, GrDeleteRepo);
diff --git a/gr-delete-repo/gr-delete-repo.html b/gr-delete-repo/gr-delete-repo_html.js
similarity index 65%
rename from gr-delete-repo/gr-delete-repo.html
rename to gr-delete-repo/gr-delete-repo_html.js
index c2a4a1b..31962d8 100644
--- a/gr-delete-repo/gr-delete-repo.html
+++ b/gr-delete-repo/gr-delete-repo_html.js
@@ -1,21 +1,21 @@
-<!--
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 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.
+ */
-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.
--->
-
-<dom-module id="gr-delete-repo">
- <template>
+export const htmlTemplate = Polymer.html`
<style include="gr-form-styles"></style>
<gr-repo-command
title="[[action.label]]"
@@ -52,6 +52,4 @@
</div>
</gr-dialog>
</gr-overlay>
- </template>
- <script src="gr-delete-repo.js"></script>
-</dom-module>
+`;
diff --git a/gr-delete-repo/plugin.js b/gr-delete-repo/plugin.js
new file mode 100644
index 0000000..2e22d59
--- /dev/null
+++ b/gr-delete-repo/plugin.js
@@ -0,0 +1,22 @@
+/**
+ * @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 './gr-delete-repo.js';
+
+Gerrit.install(plugin => {
+ plugin.registerCustomComponent(
+ 'repo-command', 'gr-delete-repo');
+});
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..5a46795
--- /dev/null
+++ b/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "delete-project",
+ "description": "Delete project plugin",
+ "browser": true,
+ "scripts": {
+ "safe_bazelisk": "if which bazelisk >/dev/null; then bazel_bin=bazelisk; else bazel_bin=bazel; fi && $bazel_bin",
+ "eslint": "npm run safe_bazelisk test :lint_test",
+ "eslintfix": "npm run safe_bazelisk run :lint_bin -- -- --fix $(pwd)"
+ },
+ "devDependencies": {},
+ "license": "Apache-2.0",
+ "private": true
+}
diff --git a/plugin.html b/plugin.html
deleted file mode 100644
index 7118174..0000000
--- a/plugin.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2018 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.
--->
-
-<link rel="import" href="./gr-delete-repo/gr-delete-repo.html">
-
-<dom-module id="delete-repo">
- <script>
- Gerrit.install(function(plugin) {
- plugin.registerCustomComponent(
- 'repo-command', 'gr-delete-repo');
- });
- </script>
-</dom-module>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
index 05842c4..417c968 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/DeletePreconditions.java
@@ -39,7 +39,7 @@
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.project.ListChildProjects;
import com.google.gerrit.server.submit.MergeOpRepoManager;
-import com.google.gerrit.server.submit.SubmoduleException;
+import com.google.gerrit.server.submit.SubmoduleConflictException;
import com.google.gerrit.server.submit.SubmoduleOp;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -165,7 +165,7 @@
} catch (RepositoryNotFoundException e) {
// we're trying to delete the repository,
// so this exception should not stop us
- } catch (IOException | SubmoduleException e) {
+ } catch (IOException | SubmoduleConflictException e) {
throw new CannotDeleteProjectException("Project is subscribed by other projects.", e);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
index c5bf8ce..7656726 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HideProject.java
@@ -84,7 +84,7 @@
}
private void createProjectIfMissing(String projectName) throws IOException, RestApiException {
- if (projectCache.get(Project.nameKey(projectName)) == null) {
+ if (!projectCache.get(Project.nameKey(projectName)).isPresent()) {
try {
createProject.apply(TopLevelResource.INSTANCE, IdString.fromDecoded(projectName), null);
} catch (RestApiException | ConfigInvalidException | PermissionBackendException e) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HttpModule.java
index 5066685..a41a374 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/deleteproject/HttpModule.java
@@ -23,6 +23,6 @@
@Override
protected void configureServlets() {
DynamicSet.bind(binder(), WebUiPlugin.class)
- .toInstance(new JavaScriptPlugin("gr-delete-repo.html"));
+ .toInstance(new JavaScriptPlugin("delete-project.html"));
}
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
index d83fac7..4960816 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/deleteproject/DeleteProjectIT.java
@@ -19,15 +19,16 @@
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import com.google.common.base.Joiner;
-import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.UseSsh;
+import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
@@ -173,7 +174,7 @@
String cmd = createDeleteCommand("--preserve-git-repository", project.get());
adminSshSession.exec(cmd);
- ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
+ ProjectConfig cfg = projectCache.get(project).orElseThrow(illegalState(project)).getConfig();
ProjectState state = cfg.getProject().getState();
assertThat(state).isEqualTo(ProjectState.HIDDEN);