Merge branch 'stable-3.2'

* stable-3.2:
  ProjectOperations: Add method to wipe all access sections
  Migrate to python 3

Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: Ibb823e5295ff3dc73fbfb683dd09ba2c5e9c16a7
diff --git a/.bazelrc b/.bazelrc
index 604a64e..71feca1 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,4 +1,4 @@
-build --workspace_status_command="python ./tools/workspace_status.py"
+build --workspace_status_command="python3 ./tools/workspace_status.py"
 build --repository_cache=~/.gerritcodereview/bazel-cache/repository
 build --action_env=PATH
 build --disk_cache=~/.gerritcodereview/bazel-cache/cas
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index e6b7950..d5ed4ed 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -19,7 +19,7 @@
 
 * A Linux or macOS system (Windows is not supported at this time)
 * A JDK for Java 8|11|...
-* Python 2 or 3
+* Python 3
 * link:https://github.com/nodesource/distributions/blob/master/README.md[Node.js (including npm),role=external,window=_blank]
 * Bower (`npm install -g bower`)
 * link:https://docs.bazel.build/versions/master/install.html[Bazel,role=external,window=_blank] -launched with
diff --git a/Documentation/replace_macros.py b/Documentation/replace_macros.py
index aaa9223..f270231 100755
--- a/Documentation/replace_macros.py
+++ b/Documentation/replace_macros.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # coding=utf-8
 # Copyright (C) 2013 The Android Open Source Project
 #
diff --git a/contrib/check-valid-commit.py b/contrib/check-valid-commit.py
index 763ae3e..bb018f9 100755
--- a/contrib/check-valid-commit.py
+++ b/contrib/check-valid-commit.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 from __future__ import print_function
 
diff --git a/contrib/git-push-review b/contrib/git-push-review
index b995fc2..5a7f664 100755
--- a/contrib/git-push-review
+++ b/contrib/git-push-review
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/contrib/populate-fixture-data.py b/contrib/populate-fixture-data.py
index 4c6769c..e51e29d 100755
--- a/contrib/populate-fixture-data.py
+++ b/contrib/populate-fixture-data.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
index f6e5de3..e7354ab 100644
--- a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
+++ b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
@@ -138,6 +138,9 @@
         throws IOException, ConfigInvalidException {
       try (MetaDataUpdate metaDataUpdate = metaDataUpdateFactory.create(nameKey)) {
         ProjectConfig projectConfig = projectConfigFactory.read(metaDataUpdate);
+        if (projectUpdate.removeAllAccessSections()) {
+          projectConfig.getAccessSections().forEach(as -> projectConfig.remove(as));
+        }
         removePermissions(projectConfig, projectUpdate.removedPermissions());
         addCapabilities(projectConfig, projectUpdate.addedCapabilities());
         addPermissions(projectConfig, projectUpdate.addedPermissions());
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java b/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java
index ea20931..9a9a21a 100644
--- a/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java
+++ b/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java
@@ -294,7 +294,8 @@
     return new AutoValue_TestProjectUpdate.Builder()
         .nameKey(nameKey)
         .allProjectsName(allProjectsName)
-        .projectUpdater(projectUpdater);
+        .projectUpdater(projectUpdater)
+        .removeAllAccessSections(false);
   }
 
   /** Builder for {@link TestProjectUpdate}. */
@@ -314,6 +315,16 @@
 
     abstract ImmutableMap.Builder<TestPermissionKey, Boolean> exclusiveGroupPermissionsBuilder();
 
+    abstract Builder removeAllAccessSections(boolean value);
+
+    /**
+     * Removes all access sections. Useful when testing against a specific set of access sections or
+     * permissions.
+     */
+    public Builder removeAllAccessSections() {
+      return removeAllAccessSections(true);
+    }
+
     /** Adds a permission to be included in this update. */
     public Builder add(TestPermission testPermission) {
       addedPermissionsBuilder().add(testPermission);
@@ -418,6 +429,8 @@
 
   abstract ThrowingConsumer<TestProjectUpdate> projectUpdater();
 
+  abstract boolean removeAllAccessSections();
+
   boolean hasCapabilityUpdates() {
     return !addedCapabilities().isEmpty()
         || removedPermissions().stream().anyMatch(k -> k.section().equals(GLOBAL_CAPABILITIES));
diff --git a/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java b/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
index 00d01d6..7543ba8 100644
--- a/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
+++ b/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
@@ -595,6 +595,15 @@
   }
 
   @Test
+  public void removeAllAccessSections() {
+    projectOperations.allProjectsForUpdate().removeAllAccessSections().update();
+
+    assertThat(projectOperations.project(allProjects).getConfig())
+        .sectionValues("access")
+        .isEmpty();
+  }
+
+  @Test
   public void updatingCapabilitiesNotAllowedForNonAllProjects() throws Exception {
     Project.NameKey key = projectOperations.newProject().create();
     assertThrows(
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
index 5214cec..dcc4739 100644
--- a/tools/bzl/js.bzl
+++ b/tools/bzl/js.bzl
@@ -28,7 +28,7 @@
     else:
         fail("repository %s not in {%s,%s}" % (repository, GERRIT, NPMJS))
 
-    python = ctx.which("python")
+    python = ctx.which("python3")
     script = ctx.path(ctx.attr._download_script)
 
     args = [python, script, "-o", dest, "-u", url, "-v", sha1]
@@ -51,7 +51,7 @@
 
 # for use in repo rules.
 def _run_npm_binary_str(ctx, tarball, args):
-    python_bin = ctx.which("python")
+    python_bin = ctx.which("python3")
     return " ".join([
         str(python_bin),
         str(ctx.path(ctx.attr._run_npm)),
@@ -65,7 +65,7 @@
     version_name = "%s__version.json" % ctx.name
 
     cmd = [
-        ctx.which("python"),
+        ctx.which("python3"),
         ctx.path(ctx.attr._download_bower),
         "-b",
         "%s" % _run_npm_binary_str(ctx, ctx.attr._bower_archive, []),
@@ -320,7 +320,7 @@
     app_path = app_path[app_path.index(pkg_dir) + len(pkg_dir):]
 
     hermetic_npm_binary = " ".join([
-        "python",
+        "python3",
         "$p/" + ctx.file._run_npm.path,
         "$p/" + ctx.file._bundler_archive.path,
         "--inline-scripts",
@@ -371,7 +371,7 @@
 
     if ctx.attr.split:
         hermetic_npm_command = "export PATH && " + " ".join([
-            "python",
+            "python3",
             ctx.file._run_npm.path,
             ctx.file._crisper_archive.path,
             "--script-in-head=false",
diff --git a/tools/bzl/license-map.py b/tools/bzl/license-map.py
index 221ae2f..555aa17 100644
--- a/tools/bzl/license-map.py
+++ b/tools/bzl/license-map.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # reads bazel query XML files, to join target names with their licenses.
 
diff --git a/tools/bzl/license.bzl b/tools/bzl/license.bzl
index cdb13d0..7b1375a 100644
--- a/tools/bzl/license.bzl
+++ b/tools/bzl/license.bzl
@@ -50,7 +50,7 @@
     # post process the XML into our favorite format.
     native.genrule(
         name = "gen_license_txt_" + name,
-        cmd = "python $(location //tools/bzl:license-map.py) %s %s %s > $@" % (" ".join(opts), " ".join(json_maps_locations), " ".join(xmls)),
+        cmd = "python3 $(location //tools/bzl:license-map.py) %s %s %s > $@" % (" ".join(opts), " ".join(json_maps_locations), " ".join(xmls)),
         outs = [name + ".gen.txt"],
         tools = tools,
         **kwargs
diff --git a/tools/bzl/maven_jar.bzl b/tools/bzl/maven_jar.bzl
index d96ffc2..adea89e 100644
--- a/tools/bzl/maven_jar.bzl
+++ b/tools/bzl/maven_jar.bzl
@@ -141,7 +141,7 @@
     binjar_path = ctx.path("/".join(["jar", binjar]))
     binurl = url + ".jar"
 
-    python = ctx.which("python")
+    python = ctx.which("python3")
     script = ctx.path(ctx.attr._download_script)
 
     args = [python, script, "-o", binjar_path, "-u", binurl]
diff --git a/tools/download_file.py b/tools/download_file.py
index 936bcef..2af2c07 100755
--- a/tools/download_file.py
+++ b/tools/download_file.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2013 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index acb5346..6cfa858 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2016 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/js/download_bower.py b/tools/js/download_bower.py
index d541b56..2a75fc1 100755
--- a/tools/js/download_bower.py
+++ b/tools/js/download_bower.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2015 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/js/npm_pack.py b/tools/js/npm_pack.py
index 57f3166..33b38a0 100755
--- a/tools/js/npm_pack.py
+++ b/tools/js/npm_pack.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2015 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/js/run_npm_binary.py b/tools/js/run_npm_binary.py
index bdee5ab..31f8a54 100644
--- a/tools/js/run_npm_binary.py
+++ b/tools/js/run_npm_binary.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2015 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/maven/mvn.py b/tools/maven/mvn.py
index 60e9f15..4ed5bf9 100755
--- a/tools/maven/mvn.py
+++ b/tools/maven/mvn.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2013 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/util_test.py b/tools/util_test.py
index 1a389f5..ab1133b2 100644
--- a/tools/util_test.py
+++ b/tools/util_test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2013 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/version.py b/tools/version.py
index 2326757..d02fc26 100755
--- a/tools/version.py
+++ b/tools/version.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # Copyright (C) 2014 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tools/workspace_status.py b/tools/workspace_status.py
index 443c2f0..bedc051 100644
--- a/tools/workspace_status.py
+++ b/tools/workspace_status.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # This script will be run by bazel when the build process starts to
 # generate key-value information that represents the status of the
diff --git a/tools/workspace_status_release.py b/tools/workspace_status_release.py
index 36535fb..b3e72ff 100644
--- a/tools/workspace_status_release.py
+++ b/tools/workspace_status_release.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # This is a variant of the `workspace_status.py` script that in addition to
 # plain `git describe` implements a few heuristics to arrive at more to the
@@ -9,7 +9,7 @@
 #
 # To use it, simply add
 #
-#   --workspace_status_command="python ./tools/workspace_status_release.py"
+#   --workspace_status_command="python3 ./tools/workspace_status_release.py"
 #
 # to your bazel command. So for example instead of
 #
@@ -17,11 +17,11 @@
 #
 # use
 #
-#   bazel build --workspace_status_command="python ./tools/workspace_status_release.py" release.war
+#   bazel build --workspace_status_command="python3 ./tools/workspace_status_release.py" release.war
 #
 # Alternatively, you can add
 #
-#   build --workspace_status_command="python ./tools/workspace_status_release.py"
+#   build --workspace_status_command="python3 ./tools/workspace_status_release.py"
 #
 # to `.bazelrc` in your home directory.
 #
@@ -150,7 +150,7 @@
         'tools', 'workspace_status_release.py')
     if os.path.isfile(workspace_status_script):
         # directory has own workspace_status_command, so we use stamps from that
-        for line in run(["python", workspace_status_script]).split('\n'):
+        for line in run(["python3", workspace_status_script]).split('\n'):
             if re.search("^STABLE_[a-zA-Z0-9().:@/_ -]*$", line):
                 print(line)
     else: