Merge branch 'stable-3.1' * stable-3.1: Format Java files with google-java-format Change-Id: I131e4e8b407fbb6dc2953380fcf3170974aeb87b
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..6d9ae7c --- /dev/null +++ b/.eslintrc.json
@@ -0,0 +1,166 @@ +{ + "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"], + "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);