Browse Source

build fixes

Frank-Rainer Grahl 2 weeks ago
parent
commit
06ddf6589a

+ 116 - 0
mozilla-release/patches/1670197-84a1.patch

@@ -0,0 +1,116 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1604944858 0
+# Node ID af3b04e5e877107e146bcfdc81aab950cc6a56d9
+# Parent  f3797766a6632fa22a728aca2360188678b66120
+Bug 1670197: "Universal" python binaries shouldn't cause setup.py fails r=firefox-build-system-reviewers,rstewart
+
+"distutils" builds packages to fit the architectures of the active
+python.
+However, the system Mac SDK doesn't always support all the same
+architectures as the local Python binary.
+To resolve this, we explicitly influence the build to only compile for
+the specific architecture that the system runs on.
+
+Assumes that "platform.machine()" will always line up with the "-arch"
+flag of compilers.
+
+Differential Revision: https://phabricator.services.mozilla.com/D96276
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -4,16 +4,17 @@
+ 
+ # This file contains code for populating the virtualenv environment for
+ # Mozilla's build system. It is typically called as part of configure.
+ 
+ from __future__ import absolute_import, print_function, unicode_literals
+ 
+ import argparse
+ import os
++import platform
+ import shutil
+ import subprocess
+ import sys
+ 
+ 
+ IS_NATIVE_WIN = (sys.platform == 'win32' and os.sep == '\\')
+ IS_CYGWIN = (sys.platform == 'cygwin')
+ 
+@@ -469,18 +470,26 @@ class VirtualenvManager(VirtualenvHelper
+         program.extend(arguments)
+ 
+         # We probably could call the contents of this file inside the context
+         # of this interpreter using execfile() or similar. However, if global
+         # variables like sys.path are adjusted, this could cause all kinds of
+         # havoc. While this may work, invoking a new process is safer.
+ 
+         try:
+-            output = subprocess.check_output(program, cwd=directory, stderr=subprocess.STDOUT,
+-                                             universal_newlines=True)
++            env = os.environ.copy()
++            env.setdefault("ARCHFLAGS", get_archflags())
++            env = ensure_subprocess_env(env)
++            output = subprocess.check_output(
++                program,
++                cwd=directory,
++                env=env,
++                stderr=subprocess.STDOUT,
++                universal_newlines=True
++            )
+             print(output)
+         except subprocess.CalledProcessError as e:
+             if 'Python.h: No such file or directory' in e.output:
+                 print('WARNING: Python.h not found. Install Python development headers.')
+             else:
+                 print(e.output)
+ 
+             raise Exception('Error installing package: %s' % directory)
+@@ -607,26 +616,44 @@ class VirtualenvManager(VirtualenvHelper
+             args.extend([
+                 '--no-deps',
+                 '--no-index',
+             ])
+ 
+         return self._run_pip(args)
+ 
+     def _run_pip(self, args):
++        env = os.environ.copy()
++        env.setdefault("ARCHFLAGS", get_archflags())
++        env = ensure_subprocess_env(env)
++
+         # It's tempting to call pip natively via pip.main(). However,
+         # the current Python interpreter may not be the virtualenv python.
+         # This will confuse pip and cause the package to attempt to install
+         # against the executing interpreter. By creating a new process, we
+         # force the virtualenv's interpreter to be used and all is well.
+         # It /might/ be possible to cheat and set sys.executable to
+         # self.python_path. However, this seems more risk than it's worth.
+         pip = os.path.join(self.bin_path, 'pip')
+-        subprocess.check_call([pip] + args, stderr=subprocess.STDOUT, cwd=self.topsrcdir,
+-                              universal_newlines=PY3)
++        subprocess.check_call(
++            [pip] + args,
++            stderr=subprocess.STDOUT,
++            cwd=self.topsrcdir,
++            env=env,
++            universal_newlines=PY3
++        )
++
++
++def get_archflags():
++    # distutils will use the architecture of the running Python instance when building packages.
++    # However, it's possible for the Xcode Python to be a universal binary (x86_64 and
++    # arm64) without the associated macOS SDK supporting arm64, thereby causing a build
++    # failure. To avoid this, we explicitly influence the build to only target a single
++    # architecture - our current architecture.
++    return "-arch {}".format(platform.machine())
+ 
+ 
+ def verify_python_version(log_handle):
+     """Ensure the current version of Python is sufficient."""
+     from distutils.version import LooseVersion
+ 
+     major, minor, micro = sys.version_info[:3]
+     minimum_python_versions = {

+ 37 - 0
mozilla-release/patches/1680353-85a1.patch

@@ -0,0 +1,37 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1607009136 0
+# Node ID c991b4d04c08d6fdd8228d9cf98c1f9d3c24f9ac
+# Parent  88f49a82f2201bf483f1d3374d5e26e85945827c
+Bug 1680353: Ensure MACOSX_DEPLOYMENT_TARGET is a string r=firefox-build-system-reviewers,dmajor
+
+The sysconfig config var of "MACOSX_DEPLOYMENT_TARGET" isn't
+consistently a string, so we need to explicitly convert it
+
+Differential Revision: https://phabricator.services.mozilla.com/D98533
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -426,17 +426,20 @@ class VirtualenvManager(VirtualenvHelper
+         IGNORE_ENV_VARIABLES = ('CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS')
+ 
+         try:
+             old_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
+             sysconfig_target = \
+                 distutils.sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+ 
+             if sysconfig_target is not None:
+-                os.environ['MACOSX_DEPLOYMENT_TARGET'] = sysconfig_target
++                # MACOSX_DEPLOYMENT_TARGET is usually a string (e.g.: "10.14.6"), but
++                # in some cases it is an int (e.g.: 11). Since environment variables
++                # must all be str, explicitly convert it.
++                os.environ["MACOSX_DEPLOYMENT_TARGET"] = str(sysconfig_target)
+ 
+             old_env_variables = {}
+             for k in IGNORE_ENV_VARIABLES:
+                 if k not in os.environ:
+                     continue
+ 
+                 old_env_variables[k] = os.environ[k]
+                 del os.environ[k]

+ 8 - 8
mozilla-release/patches/1680802-2-86a1.patch

@@ -2,7 +2,7 @@
 # User Mitchell Hentges <mhentges@mozilla.com>
 # Date 1609877665 0
 # Node ID 211eda8dbd44a2f1806f0b4a3845eec0791127e2
-# Parent  cce24bd70689c687c48f87a14680ff68488c42a7
+# Parent  b5b4e8fa34211195957e504c9013ffabb6574201
 Bug 1680802: Install pylint requirements with legacy resolver r=firefox-build-system-reviewers,sheehan,glandium
 
 pylint_requirements.txt fail to install with the new pip resolver due
@@ -16,7 +16,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D99940
 diff --git a/python/mach_commands.py b/python/mach_commands.py
 --- a/python/mach_commands.py
 +++ b/python/mach_commands.py
-@@ -203,17 +203,22 @@ class MachCommands(MachCommandBase):
+@@ -204,17 +204,22 @@ class MachCommands(MachCommandBase):
          if extra:
              os.environ['PYTEST_ADDOPTS'] += " " + " ".join(extra)
  
@@ -43,7 +43,7 @@ diff --git a/python/mach_commands.py b/python/mach_commands.py
 diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
 --- a/python/mozbuild/mozbuild/virtualenv.py
 +++ b/python/mozbuild/mozbuild/virtualenv.py
-@@ -572,17 +572,24 @@ class VirtualenvManager(VirtualenvHelper
+@@ -584,17 +584,24 @@ class VirtualenvManager(VirtualenvHelper
                  # concern and we can disable that feature. Note that this is
                  # safe and doesn't risk trampling any other packages that may be
                  # installed due to passing `--no-deps --no-index` as well.
@@ -69,7 +69,7 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
          If require_hashes is True, each specifier must contain the
          expected hash of the downloaded package. See:
          https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode
-@@ -604,16 +611,19 @@ class VirtualenvManager(VirtualenvHelper
+@@ -616,16 +623,19 @@ class VirtualenvManager(VirtualenvHelper
              args.append('--quiet')
  
          if vendored:
@@ -84,11 +84,11 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
          return self._run_pip(args)
  
      def _run_pip(self, args):
+         env = os.environ.copy()
+         env.setdefault("ARCHFLAGS", get_archflags())
+         env = ensure_subprocess_env(env)
+ 
          # It's tempting to call pip natively via pip.main(). However,
-         # the current Python interpreter may not be the virtualenv python.
-         # This will confuse pip and cause the package to attempt to install
-         # against the executing interpreter. By creating a new process, we
-         # force the virtualenv's interpreter to be used and all is well.
 diff --git a/tools/lint/python/pylint.py b/tools/lint/python/pylint.py
 --- a/tools/lint/python/pylint.py
 +++ b/tools/lint/python/pylint.py

+ 8 - 8
mozilla-release/patches/1682959-2-88a1.patch

@@ -2,7 +2,7 @@
 # User Alex Lopez <alex.lopez.zorzano@gmail.com>
 # Date 1614278220 0
 # Node ID d9dd15859c3fb24db7503e42f3abc56402c690ff
-# Parent  c40fff59bef2ae02e0fb053928a57a5d93a9f88d
+# Parent  c87e6b1c939b005e342c22b5a233ab6c23126fd9
 Bug 1682959 - Remove legacy_resolver support from mach. r=mhentges
 
 Now that all the conflicts in python dependencies that made the
@@ -16,7 +16,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D106503
 diff --git a/python/mach_commands.py b/python/mach_commands.py
 --- a/python/mach_commands.py
 +++ b/python/mach_commands.py
-@@ -205,19 +205,16 @@ class MachCommands(MachCommandBase):
+@@ -206,19 +206,16 @@ class MachCommands(MachCommandBase):
  
          installed_requirements = set()
          for test in tests:
@@ -39,7 +39,7 @@ diff --git a/python/mach_commands.py b/python/mach_commands.py
 diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
 --- a/python/mozbuild/mozbuild/virtualenv.py
 +++ b/python/mozbuild/mozbuild/virtualenv.py
-@@ -606,22 +606,17 @@ class VirtualenvManager(VirtualenvHelper
+@@ -585,22 +585,17 @@ class VirtualenvManager(VirtualenvHelper
                  # safe and doesn't risk trampling any other packages that may be
                  # installed due to passing `--no-deps --no-index` as well.
                  '--no-build-isolation',
@@ -63,7 +63,7 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
  
          If require_hashes is True, each specifier must contain the
          expected hash of the downloaded package. See:
-@@ -644,19 +639,16 @@ class VirtualenvManager(VirtualenvHelper
+@@ -623,19 +618,16 @@ class VirtualenvManager(VirtualenvHelper
              args.append('--quiet')
  
          if vendored:
@@ -78,8 +78,8 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
          return self._run_pip(args)
  
      def _run_pip(self, args):
+         env = os.environ.copy()
+         env.setdefault("ARCHFLAGS", get_archflags())
+         env = ensure_subprocess_env(env)
+ 
          # It's tempting to call pip natively via pip.main(). However,
-         # the current Python interpreter may not be the virtualenv python.
-         # This will confuse pip and cause the package to attempt to install
-         # against the executing interpreter. By creating a new process, we
-         # force the virtualenv's interpreter to be used and all is well.

+ 155 - 0
mozilla-release/patches/1696251-1-88a1.patch

@@ -0,0 +1,155 @@
+# HG changeset patch
+# User Alex Lopez <alex.lopez.zorzano@gmail.com>
+# Date 1615498947 0
+# Node ID 3e834be2046b46c75523ddff062c734eb7b1480f
+# Parent  5aec36bc42a3443f49b03b5b9d1a0d63b951cddc
+Bug 1696251 - Add tests to mach command decorators. r=mhentges
+
+In preparation for future changes in how these decorators work,
+add a few basic tests.
+
+Differential Revision: https://phabricator.services.mozilla.com/D107377
+
+diff --git a/python/mach/mach/test/python.ini b/python/mach/mach/test/python.ini
+--- a/python/mach/mach/test/python.ini
++++ b/python/mach/mach/test/python.ini
+@@ -1,13 +1,14 @@
+ [DEFAULT]
+ subsuite = mach
+ 
+ [test_commands.py]
+ [test_conditions.py]
+ skip-if = python == 3
+ [test_config.py]
++[test_decorators.py]
+ [test_dispatcher.py]
+ [test_entry_point.py]
+ [test_error_output.py]
+ skip-if = python == 3
+ [test_logger.py]
+ [test_mach.py]
+diff --git a/python/mach/mach/test/test_decorators.py b/python/mach/mach/test/test_decorators.py
+new file mode 100644
+--- /dev/null
++++ b/python/mach/mach/test/test_decorators.py
+@@ -0,0 +1,119 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++from __future__ import absolute_import, unicode_literals
++
++import os
++
++import pytest
++from mock import Mock
++
++from mozbuild.base import MachCommandBase
++from mozunit import main
++
++import mach.registrar
++import mach.decorators
++from mach.base import MachError
++from mach.decorators import CommandArgument, CommandProvider, Command, SubCommand
++
++
++@pytest.fixture
++def registrar(monkeypatch):
++    test_registrar = mach.registrar.MachRegistrar()
++    test_registrar.register_category(
++        "testing", "Mach unittest", "Testing for mach decorators"
++    )
++    monkeypatch.setattr(mach.decorators, "Registrar", test_registrar)
++    return test_registrar
++
++
++def test_register_command_with_argument(registrar):
++    inner_function = Mock()
++    context = Mock()
++    context.cwd = "."
++
++    @CommandProvider
++    class CommandFoo(MachCommandBase):
++        @Command("cmd_foo", category="testing")
++        @CommandArgument("--arg", default=None, help="Argument help.")
++        def run_foo(self, arg):
++            inner_function(arg)
++
++    registrar.dispatch("cmd_foo", context, arg="argument")
++
++    inner_function.assert_called_with("argument")
++
++
++def test_register_command_with_metrics_path(registrar):
++    context = Mock()
++    context.cwd = "."
++
++    metrics_path = "metrics/path"
++    metrics_mock = Mock()
++    context.telemetry.metrics.return_value = metrics_mock
++
++    @CommandProvider(metrics_path=metrics_path)
++    class CommandFoo(MachCommandBase):
++        @Command("cmd_foo", category="testing")
++        def run_foo(self):
++            assert self.metrics == metrics_mock
++
++    registrar.dispatch("cmd_foo", context)
++
++    context.telemetry.metrics.assert_called_with(metrics_path)
++    assert context.handler.metrics_path == metrics_path
++
++
++def test_register_command_sets_up_class_at_runtime(registrar):
++    inner_function = Mock()
++
++    context = Mock()
++    context.cwd = "."
++
++    # Inside the following class, we test that the virtualenv is set up properly
++    # dynamically on the instance that actually runs the command.
++    @CommandProvider
++    class CommandFoo(MachCommandBase):
++        @Command("cmd_foo", category="testing", virtualenv_name="env_foo")
++        def run_foo(self):
++            assert (
++                os.path.basename(self.virtualenv_manager.virtualenv_root) == "env_foo"
++            )
++            inner_function("foo")
++
++        @Command("cmd_bar", category="testing", virtualenv_name="env_bar")
++        def run_bar(self):
++            assert (
++                os.path.basename(self.virtualenv_manager.virtualenv_root) == "env_bar"
++            )
++            inner_function("bar")
++
++    registrar.dispatch("cmd_foo", context)
++    inner_function.assert_called_with("foo")
++    registrar.dispatch("cmd_bar", context)
++    inner_function.assert_called_with("bar")
++
++
++def test_cannot_create_command_nonexisting_category(registrar):
++    with pytest.raises(MachError):
++
++        @CommandProvider
++        class CommandFoo(MachCommandBase):
++            @Command("cmd_foo", category="bar")
++            def run_foo(self):
++                pass
++
++
++def test_subcommand_requires_parent_to_exist(registrar):
++    with pytest.raises(MachError):
++
++        @CommandProvider
++        class CommandFoo(MachCommandBase):
++            @SubCommand("sub_foo", "foo")
++            def run_foo(self):
++                pass
++
++
++if __name__ == "__main__":
++    main()
+

+ 92 - 0
mozilla-release/patches/1712133-1-90a1.patch

@@ -0,0 +1,92 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128715 0
+# Node ID e1cd8757104d07a74f7f5fa7d52b9a260501c6ac
+# Parent  ac1c74ed9e76fec8229411fac89d745e47ad4a0a
+Bug 1712133: Rename default virtualenv to "common" r=ahal
+
+We had split up `init` from `init_py3` because `mach` had
+traditionally been invoked by either Python 2 or Python 3, and
+the two couldn't share the same virtualenv.
+
+Now that the same context isn't shared by both Python 2 and 3
+3
+(developers always use Python 3, and the remaining Python 2
+usages are CI jobs that never reuse the objdir with Python 3),
+We can centralize on a single default virtualenv.
+
+I've called this "common" instead of "init" to clarify its
+existing position as the virtualenv that's used by many different
+commands. As we associate virtualenvs with requirement definitions,
+it'll also make the file less confusing: it's a "common" requirement
+definition as opposed to an "init" one.
+
+Differential Revision: https://phabricator.services.mozilla.com/D115635
+
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -212,17 +212,17 @@ def help_shell(help, shell):
+ shell = help_shell | shell
+ 
+ 
+ # Python 3
+ # ========
+ 
+ option(env='PYTHON3', nargs=1, help='Python 3 interpreter (3.6 or later)')
+ 
+-option(env='VIRTUALENV_NAME', nargs=1, default='init_py3',
++option(env='VIRTUALENV_NAME', nargs=1, default='common',
+        help='Name of the in-objdir virtualenv')
+ 
+ 
+ @depends('PYTHON3', 'VIRTUALENV_NAME', check_build_environment, mozconfig,
+          '--help')
+ @imports(_from='__builtin__', _import='Exception')
+ @imports('os')
+ @imports('sys')
+diff --git a/js/src/devtools/automation/autospider.py b/js/src/devtools/automation/autospider.py
+--- a/js/src/devtools/automation/autospider.py
++++ b/js/src/devtools/automation/autospider.py
+@@ -551,17 +551,17 @@ if args.variant in ('tsan', 'msan'):
+     # these files will be lost due to being overwritten.
+     command = ['tar', '-C', OUTDIR, '-zcf',
+                os.path.join(env['MOZ_UPLOAD_DIR'], '%s.tar.gz' % args.variant)]
+     command += files
+     subprocess.call(command)
+ 
+ # Generate stacks from minidumps.
+ if use_minidump:
+-    venv_python = os.path.join(OBJDIR, "_virtualenvs", "init", "bin", "python")
++    venv_python = os.path.join(OBJDIR, "_virtualenvs", "common", "bin", "python3")
+     run_command([
+         venv_python,
+         os.path.join(DIR.source, "testing/mozbase/mozcrash/mozcrash/mozcrash.py"),
+         os.getenv("TMPDIR", "/tmp"),
+         os.path.join(OBJDIR, "dist/crashreporter-symbols"),
+     ])
+ 
+ for st in results:
+diff --git a/python/mozbuild/mozbuild/base.py b/python/mozbuild/mozbuild/base.py
+--- a/python/mozbuild/mozbuild/base.py
++++ b/python/mozbuild/mozbuild/base.py
+@@ -105,18 +105,17 @@ class MozbuildObject(ProcessExecutionMix
+ 
+         self.populate_logger()
+         self.log_manager = log_manager
+ 
+         self._make = None
+         self._topobjdir = mozpath.normsep(topobjdir) if topobjdir else topobjdir
+         self._mozconfig = mozconfig
+         self._config_environment = None
+-        self._virtualenv_name = virtualenv_name or (
+-            'init_py3' if six.PY3 else 'init')
++        self._virtualenv_name = virtualenv_name or "common"
+         self._virtualenv_manager = None
+ 
+     @classmethod
+     def from_environment(cls, cwd=None, detect_virtualenv_mozinfo=True, **kwargs):
+         """Create a MozbuildObject by detecting the proper one from the env.
+ 
+         This examines environment state like the current working directory and
+         creates a MozbuildObject from the found source directory, mozconfig, etc.

+ 142 - 0
mozilla-release/patches/1712133-2-90a1.patch

@@ -0,0 +1,142 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128715 0
+# Node ID 2e37a3ce90c2e7e2ecc612d2499a9bf15edb0bf1
+# Parent  9c8ce3db5587fc68652c43c474ee48bcbc15b6a0
+Bug 1712133: Remove build VIRTUALENV_NAME customization r=glandium
+
+This was originally set up so that tests wouldn't "create a new
+`virtualenv` for no reason." However, virtual environments now will have
+different packages installed, and therefore the separation is necessary.
+
+So, for the virtual environment used for builds (regular or for tests):
+* We want it to be able to reuse the build venv, if it already exists.
+* We don't want to pollute a `pytest` virtualenv with build-specific
+  packages.
+
+Differential Revision: https://phabricator.services.mozilla.com/D115641
+
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -212,34 +212,30 @@ def help_shell(help, shell):
+ shell = help_shell | shell
+ 
+ 
+ # Python 3
+ # ========
+ 
+ option(env='PYTHON3', nargs=1, help='Python 3 interpreter (3.6 or later)')
+ 
+-option(env='VIRTUALENV_NAME', nargs=1, default='common',
+-       help='Name of the in-objdir virtualenv')
+ 
+-
+-@depends('PYTHON3', 'VIRTUALENV_NAME', check_build_environment, mozconfig,
+-         '--help')
++@depends("PYTHON3", check_build_environment, mozconfig, "--help")
+ @imports(_from='__builtin__', _import='Exception')
+ @imports('os')
+ @imports('sys')
+ @imports('subprocess')
+ @imports('distutils.sysconfig')
+ @imports(_from='mozbuild.configure.util', _import='LineIO')
+ @imports(_from='mozbuild.virtualenv', _import='VirtualenvManager')
+ @imports(_from='mozbuild.virtualenv', _import='verify_python_version')
+ @imports(_from='mozbuild.pythonutil', _import='find_python3_executable')
+ @imports(_from='mozbuild.pythonutil', _import='python_executable_version')
+ @imports(_from='six', _import='ensure_text')
+-def virtualenv_python3(env_python, virtualenv_name, build_env, mozconfig, help):
++def virtualenv_python3(env_python, build_env, mozconfig, help):
+     # Avoid re-executing python when running configure --help.
+     if help:
+         return
+ 
+     # NOTE: We cannot assume the Python we are calling this code with is the
+     # Python we want to set up a virtualenv for.
+     #
+     # We also cannot assume that the Python the caller is configuring meets our
+@@ -247,17 +243,16 @@ def virtualenv_python3(env_python, virtu
+     #
+     # Because of this the code is written to re-execute itself with the correct
+     # interpreter if required.
+ 
+     log.debug("python3: running with pid %r" % os.getpid())
+     log.debug("python3: sys.executable: %r" % sys.executable)
+ 
+     python = env_python[0] if env_python else None
+-    virtualenv_name = virtualenv_name[0]
+ 
+     # Did our python come from mozconfig? Overrides environment setting.
+     # Ideally we'd rely on the mozconfig injection from mozconfig_options,
+     # but we'd rather avoid the verbosity when we need to reexecute with
+     # a different python.
+     if mozconfig['path']:
+         if 'PYTHON3' in mozconfig['env']['added']:
+             python = mozconfig['env']['added']['PYTHON3']
+@@ -283,17 +278,18 @@ def virtualenv_python3(env_python, virtu
+     topsrcdir, topobjdir = build_env.topsrcdir, build_env.topobjdir
+     if topobjdir.endswith('/js/src'):
+         topobjdir = topobjdir[:-7]
+ 
+     virtualenvs_root = os.path.join(topobjdir, '_virtualenvs')
+     with LineIO(lambda l: log.info(l), 'replace') as out:
+         manager = VirtualenvManager(
+             topsrcdir,
+-            os.path.join(virtualenvs_root, virtualenv_name), out,
++            os.path.join(virtualenvs_root, "common"),
++            out,
+             os.path.join(topsrcdir, 'build', 'build_virtualenv_packages.txt'))
+ 
+     # Update the path to include some necessary modules for find_program.
+     sys.path.insert(0, os.path.join(topsrcdir, "testing", "mozbase", "mozfile"))
+     sys.path.insert(0, os.path.join(topsrcdir, "third_party", "python", "backports"))
+ 
+     # If we know the Python executable the caller is asking for then verify its
+     # version. If the caller did not ask for a specific executable then find
+diff --git a/python/mozbuild/mozbuild/test/configure/common.py b/python/mozbuild/mozbuild/test/configure/common.py
+--- a/python/mozbuild/mozbuild/test/configure/common.py
++++ b/python/mozbuild/mozbuild/test/configure/common.py
+@@ -289,17 +289,17 @@ class BaseConfigureTest(unittest.TestCas
+             mozconfig_path = os.path.join(os.path.dirname(__file__), 'data',
+                                           'empty_mozconfig')
+ 
+         try:
+             environ = dict(
+                 environ,
+                 OLD_CONFIGURE=os.path.join(topsrcdir, 'old-configure'),
+                 MOZCONFIG=mozconfig_path,
+-                VIRTUALENV_NAME='python-test')
++            )
+ 
+             paths = dict(paths)
+             autoconf_dir = mozpath.join(topsrcdir, 'build', 'autoconf')
+             paths[mozpath.join(autoconf_dir,
+                                'config.guess')] = self.config_guess
+             paths[mozpath.join(autoconf_dir, 'config.sub')] = self.config_sub
+ 
+             sandbox = cls(paths, config, environ, ['configure'] + target + args,
+diff --git a/python/mozbuild/mozbuild/test/configure/test_toolkit_moz_configure.py b/python/mozbuild/mozbuild/test/configure/test_toolkit_moz_configure.py
+--- a/python/mozbuild/mozbuild/test/configure/test_toolkit_moz_configure.py
++++ b/python/mozbuild/mozbuild/test/configure/test_toolkit_moz_configure.py
+@@ -24,19 +24,17 @@ class TestToolkitMozConfigure(BaseConfig
+                                 help='Help missing for old configure options')
+ 
+             # Remove all implied options, otherwise, getting
+             # all_configure_options below triggers them, and that triggers
+             # configure parts that aren't expected to run during this test.
+             del sandbox._implied_options[:]
+             result = sandbox._value_for(sandbox['all_configure_options'])
+             shell = mozpath.abspath('/bin/sh')
+-            return (result
+-                    .replace('CONFIG_SHELL=%s ' % shell, '')
+-                    .replace('VIRTUALENV_NAME=python-test ', ''))
++            return result.replace("CONFIG_SHELL=%s " % shell, "")
+ 
+         self.assertEquals('--enable-application=browser',
+                           get_value_for(['--enable-application=browser']))
+ 
+         self.assertEquals('--enable-application=browser '
+                           'MOZ_VTUNE=1',
+                           get_value_for(['--enable-application=browser',
+                                          'MOZ_VTUNE=1']))

+ 84 - 0
mozilla-release/patches/1712133-3-90a1.patch

@@ -0,0 +1,84 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128717 0
+# Node ID 965304eb579934fa8e99162de18f8e86a4e31245
+# Parent  37dc61494ca91729ea361c89067cac099f68d0e3
+Bug 1712133: Use if/else chain instead of early-return in handle_package r=ahal
+
+Accidentally missing a `return` in a code path could mean that
+`handle_package(...)` would accidentally do an action _and_
+raise the "Unknown action" error.
+
+This change resolves that, and it simplifies the code a bit.
+
+Differential Revision: https://phabricator.services.mozilla.com/D115923
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -337,55 +337,44 @@ class VirtualenvManager(VirtualenvHelper
+                 assert len(package) == 2
+ 
+                 src = os.path.join(self.topsrcdir, package[1])
+                 assert os.path.isfile(src), "'%s' does not exist" % src
+                 submanager = VirtualenvManager(
+                     self.topsrcdir, self.virtualenv_root, self.log_handle, src,
+                     populate_local_paths=self.populate_local_paths)
+                 submanager.populate(sitecustomize=sitecustomize)
+-
+-                return True
+-
+-            if package[0].endswith('.pth'):
++            elif package[0].endswith(".pth"):
+                 assert len(package) == 2
+ 
+                 if not self.populate_local_paths:
+-                    return True
++                    return
+ 
+                 path = os.path.join(self.topsrcdir, package[1])
+ 
+                 with open(os.path.join(python_lib, package[0]), 'a') as f:
+                     # This path is relative to the .pth file.  Using a
+                     # relative path allows the srcdir/objdir combination
+                     # to be moved around (as long as the paths relative to
+                     # each other remain the same).
+                     f.write("%s\n" % os.path.relpath(path, python_lib))
+-                return True
+-
+-            if package[0] == "thunderbird":
++            elif package[0] == "thunderbird":
+                 if is_thunderbird:
+-                    return handle_package(package[1:])
+-                else:
+-                    return True
+-
+-            if package[0] in ('windows', '!windows'):
++                    handle_package(package[1:])
++            elif package[0] in ("windows", "!windows"):
+                 for_win = not package[0].startswith('!')
+                 is_win = sys.platform == 'win32'
+                 if is_win == for_win:
+-                    return handle_package(package[1:])
+-                return True
+-
+-            if package[0] in ('python2', 'python3'):
++                    handle_package(package[1:])
++            elif package[0] in ("python2", "python3"):
+                 for_python3 = package[0].endswith('3')
+                 if PY3 == for_python3:
+-                    return handle_package(package[1:])
+-                return True
+-
+-            raise Exception('Unknown action: %s' % package[0])
++                    handle_package(package[1:])
++            else:
++                raise Exception("Unknown action: %s" % package[0])
+ 
+         # We always target the OS X deployment target that Python itself was
+         # built with, regardless of what's in the current environment. If we
+         # don't do # this, we may run into a Python bug. See
+         # http://bugs.python.org/issue9516 and bug 659881.
+         #
+         # Note that this assumes that nothing compiled in the virtualenv is
+         # shipped as part of a distribution. If we do ship anything, the

+ 100 - 0
mozilla-release/patches/1712133-4-90a1.patch

@@ -0,0 +1,100 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128717 0
+# Node ID 7e8e5f4c8e73653e711c24724a3913ebb75688a1
+# Parent  a1e70cdd712e498bfc17558f9fa8e07baa118df9
+Bug 1712133: Simplify virtualenv "sitecustomize" writing r=ahal
+
+Child `handle_package(...)` invocations don't need to modify
+`sitecustomize.py`, so don't pass it to them.
+
+Differential Revision: https://phabricator.services.mozilla.com/D115924
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -275,17 +275,17 @@ class VirtualenvManager(VirtualenvHelper
+ 
+     def packages(self):
+         mode = 'rU' if PY2 else 'r'
+         with open(self.manifest_path, mode) as fh:
+             packages = [line.rstrip().split(':')
+                         for line in fh]
+         return packages
+ 
+-    def populate(self, sitecustomize=None):
++    def populate(self, ignore_sitecustomize=False):
+         """Populate the virtualenv.
+ 
+         The manifest file consists of colon-delimited fields. The first field
+         specifies the action. The remaining fields are arguments to that
+         action. The following actions are supported:
+ 
+         filename.pth -- Adds the path given as argument to filename.pth under
+             the virtualenv site packages directory.
+@@ -322,31 +322,27 @@ class VirtualenvManager(VirtualenvHelper
+         import distutils.sysconfig
+ 
+         thunderbird_dir = os.path.join(self.topsrcdir, "comm")
+         is_thunderbird = os.path.exists(thunderbird_dir) and bool(
+             os.listdir(thunderbird_dir)
+         )
+         packages = self.packages()
+         python_lib = distutils.sysconfig.get_python_lib()
+-        do_close = not bool(sitecustomize)
+-        sitecustomize = sitecustomize or open(
+-            os.path.join(os.path.dirname(python_lib), 'sitecustomize.py'),
+-            mode='w')
+ 
+         def handle_package(package):
+             if package[0] == 'packages.txt':
+                 assert len(package) == 2
+ 
+                 src = os.path.join(self.topsrcdir, package[1])
+                 assert os.path.isfile(src), "'%s' does not exist" % src
+                 submanager = VirtualenvManager(
+                     self.topsrcdir, self.virtualenv_root, self.log_handle, src,
+                     populate_local_paths=self.populate_local_paths)
+-                submanager.populate(sitecustomize=sitecustomize)
++                submanager.populate(ignore_sitecustomize=True)
+             elif package[0].endswith(".pth"):
+                 assert len(package) == 2
+ 
+                 if not self.populate_local_paths:
+                     return
+ 
+                 path = os.path.join(self.topsrcdir, package[1])
+ 
+@@ -406,25 +402,27 @@ class VirtualenvManager(VirtualenvHelper
+ 
+                 old_env_variables[k] = os.environ[k]
+                 del os.environ[k]
+ 
+             for package in packages:
+                 handle_package(package)
+ 
+         finally:
+-            if do_close:
+-                # This hack isn't necessary for Python 3, or for the
+-                # out-of-objdir virtualenvs.
+-                if self.populate_local_paths and PY2:
++            # This hack isn't necessary for Python 3, or for the
++            # out-of-objdir virtualenvs.
++            if PY2 and self.populate_local_paths and not ignore_sitecustomize:
++                with open(
++                    os.path.join(os.path.dirname(python_lib), "sitecustomize.py"),
++                    mode="w",
++                ) as sitecustomize:
+                     sitecustomize.write(
+                         '# Importing mach_bootstrap has the side effect of\n'
+                         '# installing an import hook\n'
+                         'import mach_bootstrap\n')
+-                sitecustomize.close()
+ 
+             os.environ.pop('MACOSX_DEPLOYMENT_TARGET', None)
+ 
+             if old_target is not None:
+                 os.environ['MACOSX_DEPLOYMENT_TARGET'] = old_target
+ 
+             os.environ.update(old_env_variables)
+ 

+ 73 - 0
mozilla-release/patches/1712382-1-90a1.patch

@@ -0,0 +1,73 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128716 0
+# Node ID 922cb1e35a9ecee03da3085e7ec311417512eb42
+# Parent  3365ae0f6f30e6feb61571072938ce2ba212eb18
+Bug 1712382: Remove "setup.py" action support from virtualenvs r=ahal
+
+The `setup.py` action is no longer used, so we can safely remove it.
+
+Depends on D115641
+
+Differential Revision: https://phabricator.services.mozilla.com/D115913
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -282,30 +282,24 @@ class VirtualenvManager(VirtualenvHelper
+ 
+     def populate(self, sitecustomize=None):
+         """Populate the virtualenv.
+ 
+         The manifest file consists of colon-delimited fields. The first field
+         specifies the action. The remaining fields are arguments to that
+         action. The following actions are supported:
+ 
+-        setup.py -- Invoke setup.py for a package. Expects the arguments:
+-            1. relative path directory containing setup.py.
+-            2. argument(s) to setup.py. e.g. "develop". Each program argument
+-               is delimited by a colon. Arguments with colons are not yet
+-               supported.
+-
+         filename.pth -- Adds the path given as argument to filename.pth under
+             the virtualenv site packages directory.
+ 
+         optional -- This denotes the action as optional. The requested action
+             is attempted. If it fails, we issue a warning and go on. The
+             initial "optional" field is stripped then the remaining line is
+             processed like normal. e.g.
+-            "optional:setup.py:python/foo:built_ext:-i"
++            "optional:mozilla.pth:python/foo
+ 
+         packages.txt -- Denotes that the specified path is a child manifest. It
+             will be read and processed as if its contents were concatenated
+             into the manifest being read.
+ 
+         windows -- This denotes that the action should only be taken when run
+             on Windows.
+ 
+@@ -342,24 +336,16 @@ class VirtualenvManager(VirtualenvHelper
+                 var, val = assignment.split('=', 1)
+                 var = var if PY3 else ensure_binary(var)
+                 val = val if PY3 else ensure_binary(val)
+                 sitecustomize.write(
+                     'import os\n'
+                     "os.environ[%s] = %s\n" % (repr(var), repr(val)))
+                 return True
+ 
+-            if package[0] == 'setup.py':
+-                assert len(package) >= 2
+-
+-                self.call_setup(os.path.join(self.topsrcdir, package[1]),
+-                                package[2:])
+-
+-                return True
+-
+             if package[0] == 'packages.txt':
+                 assert len(package) == 2
+ 
+                 src = os.path.join(self.topsrcdir, package[1])
+                 assert os.path.isfile(src), "'%s' does not exist" % src
+                 submanager = VirtualenvManager(
+                     self.topsrcdir, self.virtualenv_root, self.log_handle, src,
+                     populate_local_paths=self.populate_local_paths)

+ 91 - 0
mozilla-release/patches/1712382-2-90a1.patch

@@ -0,0 +1,91 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128716 0
+# Node ID 05c9e4f016fdc5536e59c67760e5ec2233990822
+# Parent  06167336a9882906a35aee2a67f2677757f05015
+Bug 1712382: Remove "set-variable" action support from virtualenvs r=ahal
+
+`MACH_VIRTUALENV` was never used, and `MOZBUILD_VIRTUALENV` was never
+set (the virtualenv was always activated during the build, rather
+than before).
+
+Differential Revision: https://phabricator.services.mozilla.com/D115921
+
+diff --git a/build/build_virtualenv_packages.txt b/build/build_virtualenv_packages.txt
+--- a/build/build_virtualenv_packages.txt
++++ b/build/build_virtualenv_packages.txt
+@@ -1,2 +1,1 @@
+ packages.txt:build/common_virtualenv_packages.txt
+-set-variable MOZBUILD_VIRTUALENV=1
+diff --git a/build/mach_virtualenv_packages.txt b/build/mach_virtualenv_packages.txt
+--- a/build/mach_virtualenv_packages.txt
++++ b/build/mach_virtualenv_packages.txt
+@@ -1,2 +1,1 @@
+ packages.txt:build/common_virtualenv_packages.txt
+-set-variable MACH_VIRTUALENV=1
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -286,28 +286,19 @@ def virtualenv_python3(env_python, virtu
+ 
+     virtualenvs_root = os.path.join(topobjdir, '_virtualenvs')
+     with LineIO(lambda l: log.info(l), 'replace') as out:
+         manager = VirtualenvManager(
+             topsrcdir,
+             os.path.join(virtualenvs_root, virtualenv_name), out,
+             os.path.join(topsrcdir, 'build', 'build_virtualenv_packages.txt'))
+ 
+-    # If we're not in the virtualenv, we need to update the path to include some
+-    # necessary modules for find_program.
+-    try:
+-        import mozfile
+-    except ImportError:
+-        sys.path.insert(
+-            0, os.path.join(topsrcdir, 'testing', 'mozbase', 'mozfile'))
+-        sys.path.insert(
+-            0, os.path.join(topsrcdir, 'third_party', 'python', 'backports'))
+-    else:
+-        if 'MOZBUILD_VIRTUALENV' in os.environ or not python:
+-            python = sys.executable
++    # Update the path to include some necessary modules for find_program.
++    sys.path.insert(0, os.path.join(topsrcdir, "testing", "mozbase", "mozfile"))
++    sys.path.insert(0, os.path.join(topsrcdir, "third_party", "python", "backports"))
+ 
+     # If we know the Python executable the caller is asking for then verify its
+     # version. If the caller did not ask for a specific executable then find
+     # a reasonable default.
+     if python:
+         found_python = find_program(python)
+         if not found_python:
+             die('The PYTHON3 environment variable does not contain '
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -325,27 +325,16 @@ class VirtualenvManager(VirtualenvHelper
+         packages = self.packages()
+         python_lib = distutils.sysconfig.get_python_lib()
+         do_close = not bool(sitecustomize)
+         sitecustomize = sitecustomize or open(
+             os.path.join(os.path.dirname(python_lib), 'sitecustomize.py'),
+             mode='w')
+ 
+         def handle_package(package):
+-            if package[0].startswith('set-variable '):
+-                assert len(package) == 1
+-                assignment = package[0][len('set-variable '):].strip()
+-                var, val = assignment.split('=', 1)
+-                var = var if PY3 else ensure_binary(var)
+-                val = val if PY3 else ensure_binary(val)
+-                sitecustomize.write(
+-                    'import os\n'
+-                    "os.environ[%s] = %s\n" % (repr(var), repr(val)))
+-                return True
+-
+             if package[0] == 'packages.txt':
+                 assert len(package) == 2
+ 
+                 src = os.path.join(self.topsrcdir, package[1])
+                 assert os.path.isfile(src), "'%s' does not exist" % src
+                 submanager = VirtualenvManager(
+                     self.topsrcdir, self.virtualenv_root, self.log_handle, src,
+                     populate_local_paths=self.populate_local_paths)

+ 162 - 0
mozilla-release/patches/1712382-3-90a1.patch

@@ -0,0 +1,162 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622138672 0
+# Node ID c1bda584266eb189c162dabcd3aff2655022b2ac
+# Parent  88015da25629f9f2b2324b38e7ad0991064e048a
+Bug 1712382: Includes virtualenvs when clobbering Python r=glandium
+
+No longer includes `python` in the `./mach clobber` defaults since
+python cache files should no longer be affecting `./mach artifact`.
+
+Removes `third_party/python` purging from `./mach clobber python`
+since we don't build native Python modules there.
+
+Moves virtualenv-purging from `./mach clobber objdir` to
+`./mach clobber python`.
+
+Differential Revision: https://phabricator.services.mozilla.com/D115728
+
+diff --git a/python/mozbuild/mozbuild/controller/clobber.py b/python/mozbuild/mozbuild/controller/clobber.py
+--- a/python/mozbuild/mozbuild/controller/clobber.py
++++ b/python/mozbuild/mozbuild/controller/clobber.py
+@@ -139,20 +139,17 @@ class Clobberer(object):
+         # Determine where cargo build artifacts are stored
+         RUST_TARGET_VARS = ('RUST_HOST_TARGET', 'RUST_TARGET')
+         rust_targets = set([self.substs[x] for x in RUST_TARGET_VARS if x in self.substs])
+         rust_build_kind = 'release'
+         if self.substs.get('MOZ_DEBUG_RUST'):
+             rust_build_kind = 'debug'
+ 
+         # Top-level files and directories to not clobber by default.
+-        no_clobber = {
+-            '.mozbuild',
+-            'msvc',
+-        }
++        no_clobber = {".mozbuild", "msvc", "_virtualenvs"}
+ 
+         # Hold off on clobbering cargo build artifacts
+         no_clobber |= rust_targets
+ 
+         if full:
+             # mozfile doesn't like unicode arguments (bug 818783).
+             paths = [self.topobjdir.encode('utf-8')]
+         else:
+diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py
+--- a/python/mozbuild/mozbuild/mach_commands.py
++++ b/python/mozbuild/mozbuild/mach_commands.py
+@@ -175,49 +175,55 @@ class Doctor(MachCommandBase):
+         from mozbuild.doctor import Doctor
+         doctor = Doctor(self.topsrcdir, self.topobjdir, fix)
+         return doctor.check_all()
+ 
+ 
+ @CommandProvider
+ class Clobber(MachCommandBase):
+     NO_AUTO_LOG = True
+-    CLOBBER_CHOICES = ['objdir', 'python']
++    CLOBBER_CHOICES = {"objdir", "python"}
+ 
+     @Command('clobber', category='build',
+              description='Clobber the tree (delete the object directory).')
+-    @CommandArgument('what', default=['objdir'], nargs='*',
+-                     help='Target to clobber, must be one of {{{}}} (default objdir).'.format(
+-             ', '.join(CLOBBER_CHOICES)))
++    @CommandArgument(
++        'what',
++        default=["objdir"],
++        nargs='*',
++        help="Target to clobber, must be one of {{{}}} (default "
++        "objdir).".format(", ".join(CLOBBER_CHOICES)),
++    )
+     @CommandArgument('--full', action='store_true',
+                      help='Perform a full clobber')
+     def clobber(self, what, full=False):
+         """Clean up the source and object directories.
+ 
+         Performing builds and running various commands generate various files.
+ 
+         Sometimes it is necessary to clean up these files in order to make
+         things work again. This command can be used to perform that cleanup.
+ 
+         By default, this command removes most files in the current object
+         directory (where build output is stored). Some files (like Visual
+         Studio project files) are not removed by default. If you would like
+         to remove the object directory in its entirety, run with `--full`.
+ 
+-        The `python` target will clean up various generated Python files from
+-        the source directory and will remove untracked files from well-known
+-        directories containing Python packages. Run this to remove .pyc files,
+-        compiled C extensions, etc. Note: all files not tracked or ignored by
+-        version control in well-known Python package directories will be
+-        deleted. Run the `status` command of your VCS to see if any untracked
+-        files you haven't committed yet will be deleted.
++        The `python` target will clean up Python's generated files (virtualenvs,
++        ".pyc", "__pycache__", etc).
++
++        By default, the command clobbers the `objdir` and `python` targets.
++        By default, the command clobbers the `objdir` target.
+         """
+         invalid = set(what) - set(self.CLOBBER_CHOICES)
+         if invalid:
+-            print('Unknown clobber target(s): {}'.format(', '.join(invalid)))
++            print(
++                "Unknown clobber target(s): {}. Choose from {{{}}}".format(
++                    ", ".join(invalid), ", ".join(self.CLOBBER_CHOICES)
++                )
++            )
+             return 1
+ 
+         ret = 0
+         if 'objdir' in what:
+             from mozbuild.controller.clobber import Clobberer
+             try:
+                 Clobberer(self.topsrcdir, self.topobjdir, self.substs).remove_objdir(full)
+             except OSError as e:
+@@ -226,27 +232,41 @@ class Clobber(MachCommandBase):
+                         self.log(logging.ERROR, 'file_access_error', {'error': e},
+                                  "Could not clobber because a file was in use. If the "
+                                  "application is running, try closing it. {error}")
+                         return 1
+                 raise
+ 
+         if 'python' in what:
+             if conditions.is_hg(self):
+-                cmd = ['hg', 'purge', '--all', '-I', 'glob:**.py[cdo]',
+-                       '-I', 'path:python/', '-I', 'path:third_party/python/']
++                cmd = [
++                    'hg',
++                    'purge',
++                    '--all',
++                    '-I',
++                    'glob:**.py[cdo]',
++                    '-I',
++                    'path:python/',
++                ]
+             elif conditions.is_git(self):
+-                cmd = ['git', 'clean', '-f', '-x', '*.py[cdo]', 'python/',
+-                       'third_party/python/']
++                cmd = [
++                    'git',
++                    'clean',
++                    '-f',
++                    '-x',
++                    '*.py[cdo]',
++                    'python/',
++                ]
+             else:
+-                # We don't know what is tracked/untracked if we don't have VCS.
+-                # So we can't clean python/ and third_party/python/.
+                 cmd = ['find', '.', '-type', 'f', '-name', '*.py[cdo]',
+                        '-delete']
+             ret = subprocess.call(cmd, cwd=self.topsrcdir)
++            shutil.rmtree(
++                mozpath.join(self.topobjdir, "_virtualenvs"), ignore_errors=True
++            )
+         return ret
+ 
+     @property
+     def substs(self):
+         try:
+             return super(Clobber, self).substs
+         except BuildEnvironmentNotFoundException:
+             return {}

+ 103 - 0
mozilla-release/patches/1712804-1-90a1.patch

@@ -0,0 +1,103 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1622128717 0
+# Node ID 3c8d543d71cf51fd8ff4702cdb6dadc1542f93fd
+# Parent  ac1c74ed9e76fec8229411fac89d745e47ad4a0a
+Bug 1712804: Change comm action to be specific to Thunderbird r=rjl,ahal
+
+Avoid the "Error processing command" warning when building virtualenvs
+in a Firefox checkout
+
+Differential Revision: https://phabricator.services.mozilla.com/D115922
+
+diff --git a/build/common_virtualenv_packages.txt b/build/common_virtualenv_packages.txt
+--- a/build/common_virtualenv_packages.txt
++++ b/build/common_virtualenv_packages.txt
+@@ -1,9 +1,9 @@
+-optional:packages.txt:comm/build/virtualenv_packages.txt
++thunderbird:packages.txt:comm/build/virtualenv_packages.txt
+ mozilla.pth:build
+ mozilla.pth:config
+ mozilla.pth:config/mozunit
+ mozilla.pth:dom/bindings
+ mozilla.pth:dom/bindings/parser
+ mozilla.pth:layout/tools/reftest
+ mozilla.pth:python/mach
+ mozilla.pth:python/mozboot
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -285,21 +285,20 @@ class VirtualenvManager(VirtualenvHelper
+ 
+         The manifest file consists of colon-delimited fields. The first field
+         specifies the action. The remaining fields are arguments to that
+         action. The following actions are supported:
+ 
+         filename.pth -- Adds the path given as argument to filename.pth under
+             the virtualenv site packages directory.
+ 
+-        optional -- This denotes the action as optional. The requested action
+-            is attempted. If it fails, we issue a warning and go on. The
+-            initial "optional" field is stripped then the remaining line is
+-            processed like normal. e.g.
+-            "optional:mozilla.pth:python/foo
++        thunderbird -- This denotes the action as to only occur for Thunderbird
++            checkouts. The initial "thunderbird" field is stripped, then the
++            remaining line is processed like normal. e.g.
++            "thunderbird:comms.pth:python/foo"
+ 
+         packages.txt -- Denotes that the specified path is a child manifest. It
+             will be read and processed as if its contents were concatenated
+             into the manifest being read.
+ 
+         windows -- This denotes that the action should only be taken when run
+             on Windows.
+ 
+@@ -317,16 +316,17 @@ class VirtualenvManager(VirtualenvHelper
+ 
+         Note that the Python interpreter running this function should be the
+         one from the virtualenv. If it is the system Python or if the
+         environment is not configured properly, packages could be installed
+         into the wrong place. This is how virtualenv's work.
+         """
+         import distutils.sysconfig
+ 
++        is_thunderbird = os.path.exists(os.path.join(self.topsrcdir, "comm"))
+         packages = self.packages()
+         python_lib = distutils.sysconfig.get_python_lib()
+         do_close = not bool(sitecustomize)
+         sitecustomize = sitecustomize or open(
+             os.path.join(os.path.dirname(python_lib), 'sitecustomize.py'),
+             mode='w')
+ 
+         def handle_package(package):
+@@ -353,25 +353,21 @@ class VirtualenvManager(VirtualenvHelper
+                 with open(os.path.join(python_lib, package[0]), 'a') as f:
+                     # This path is relative to the .pth file.  Using a
+                     # relative path allows the srcdir/objdir combination
+                     # to be moved around (as long as the paths relative to
+                     # each other remain the same).
+                     f.write("%s\n" % os.path.relpath(path, python_lib))
+                 return True
+ 
+-            if package[0] == 'optional':
+-                try:
+-                    handle_package(package[1:])
++            if package[0] == "thunderbird":
++                if is_thunderbird:
++                    return handle_package(package[1:])
++                else:
+                     return True
+-                except Exception:
+-                    print('Error processing command. Ignoring',
+-                          'because optional. (%s)' % ':'.join(package),
+-                          file=self.log_handle)
+-                    return False
+ 
+             if package[0] in ('windows', '!windows'):
+                 for_win = not package[0].startswith('!')
+                 is_win = sys.platform == 'win32'
+                 if is_win == for_win:
+                     return handle_package(package[1:])
+                 return True
+ 

+ 43 - 0
mozilla-release/patches/1712804-2-90a1.patch

@@ -0,0 +1,43 @@
+# HG changeset patch
+# User Mitchell Hentges <mhentges@mozilla.com>
+# Date 1625596438 0
+# Node ID 9e0ab612cd848e75a0d7ed2bb559f7cbd8ba425d
+# Parent  4ae03b9f434302adb83aea91504eb9c82f5a8a7c
+Bug 1712804: Check if `comm` directory is empty in TB identification r=ahal
+
+Some developers hold onto a `comm` directory as a mount point
+that they conditionally populate depending on whether they're working on
+Firefox or Thunderbird.
+The "`comm` directory exists == is a thunderbird checkout"
+assumption isn't compatible with this workflow.
+
+The fix embraced by this patch is to check if the `comm` directory has
+any contents.
+
+Differential Revision: https://phabricator.services.mozilla.com/D119193
+
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -316,17 +316,20 @@ class VirtualenvManager(VirtualenvHelper
+ 
+         Note that the Python interpreter running this function should be the
+         one from the virtualenv. If it is the system Python or if the
+         environment is not configured properly, packages could be installed
+         into the wrong place. This is how virtualenv's work.
+         """
+         import distutils.sysconfig
+ 
+-        is_thunderbird = os.path.exists(os.path.join(self.topsrcdir, "comm"))
++        thunderbird_dir = os.path.join(self.topsrcdir, "comm")
++        is_thunderbird = os.path.exists(thunderbird_dir) and bool(
++            os.listdir(thunderbird_dir)
++        )
+         packages = self.packages()
+         python_lib = distutils.sysconfig.get_python_lib()
+         do_close = not bool(sitecustomize)
+         sitecustomize = sitecustomize or open(
+             os.path.join(os.path.dirname(python_lib), 'sitecustomize.py'),
+             mode='w')
+ 
+         def handle_package(package):

+ 7 - 7
mozilla-release/patches/1712819-2-90a1.patch

@@ -2,7 +2,7 @@
 # User Mitchell Hentges <mhentges@mozilla.com>
 # Date 1622156646 0
 # Node ID 3a5b335bdc8c52a384f3f3a03a87ea03d12d2935
-# Parent  0d031e6669a2f0b38b49e9eb904c0e1641b86727
+# Parent  b242469bd4982911804a817a1e0781adb558af19
 Bug 1712819: Avoid pip's "outdated" warning in virtualenvs r=ahal
 
 Now, when running mach commands that invoke `pip`, it will no longer
@@ -16,7 +16,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D115940
 diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
 --- a/python/mozbuild/mozbuild/virtualenv.py
 +++ b/python/mozbuild/mozbuild/virtualenv.py
-@@ -263,16 +263,17 @@ class VirtualenvManager(VirtualenvHelper
+@@ -264,16 +264,17 @@ class VirtualenvManager(VirtualenvHelper
          result = self._log_process_output(args)
  
          if result:
@@ -34,7 +34,7 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
          with open(self.manifest_path, mode) as fh:
              packages = [line.rstrip().split(':')
                          for line in fh]
-@@ -607,16 +608,65 @@ class VirtualenvManager(VirtualenvHelper
+@@ -580,16 +581,65 @@ class VirtualenvManager(VirtualenvHelper
          if vendored:
              args.extend([
                  '--no-deps',
@@ -93,10 +93,10 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
 +            file.write("mach")
 +
      def _run_pip(self, args):
+         env = os.environ.copy()
+         env.setdefault("ARCHFLAGS", get_archflags())
+         env = ensure_subprocess_env(env)
+ 
          # It's tempting to call pip natively via pip.main(). However,
          # the current Python interpreter may not be the virtualenv python.
          # This will confuse pip and cause the package to attempt to install
-         # against the executing interpreter. By creating a new process, we
-         # force the virtualenv's interpreter to be used and all is well.
-         # It /might/ be possible to cheat and set sys.executable to
-         # self.python_path. However, this seems more risk than it's worth.

+ 16 - 18
mozilla-release/patches/1714641-02-91a1.patch

@@ -2,7 +2,7 @@
 # User Mitchell Hentges <mhentges@mozilla.com>
 # Date 1623253731 0
 # Node ID d3aaa4e4d0d449074a5ec41a2afff6c8ba8b1286
-# Parent  a4f148e9b2fa5b5c7601517d5b7babc7927e041c
+# Parent  640dec32f080484fd1c683389b5f634dbf0bba0d
 Bug 1714641: Remove `pythonX` actions from virtualenv config r=ahal
 
 The actions are no longer used, so we can delete the associated
@@ -13,7 +13,7 @@ Differential Revision: https://phabricator.services.mozilla.com/D117060
 diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
 --- a/python/mozbuild/mozbuild/virtualenv.py
 +++ b/python/mozbuild/mozbuild/virtualenv.py
-@@ -306,22 +306,16 @@ class VirtualenvManager(VirtualenvHelper
+@@ -300,22 +300,16 @@ class VirtualenvManager(VirtualenvHelper
              into the manifest being read.
  
          windows -- This denotes that the action should only be taken when run
@@ -36,30 +36,28 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
          environment is not configured properly, packages could be installed
          into the wrong place. This is how virtualenv's work.
          """
-@@ -394,22 +388,16 @@ class VirtualenvManager(VirtualenvHelper
- 
-             if package[0] in ('windows', '!windows'):
+@@ -355,20 +349,16 @@ class VirtualenvManager(VirtualenvHelper
+             elif package[0] == "thunderbird":
+                 if is_thunderbird:
+                     handle_package(package[1:])
+             elif package[0] in ("windows", "!windows"):
                  for_win = not package[0].startswith('!')
                  is_win = sys.platform == 'win32'
                  if is_win == for_win:
-                     return handle_package(package[1:])
-                 return True
- 
--            if package[0] in ('python2', 'python3'):
+                     handle_package(package[1:])
+-            elif package[0] in ("python2", "python3"):
 -                for_python3 = package[0].endswith('3')
 -                if PY3 == for_python3:
--                    return handle_package(package[1:])
--                return True
--
-             raise Exception('Unknown action: %s' % package[0])
+-                    handle_package(package[1:])
+             else:
+                 raise Exception("Unknown action: %s" % package[0])
  
          # We always target the OS X deployment target that Python itself was
          # built with, regardless of what's in the current environment. If we
          # don't do # this, we may run into a Python bug. See
          # http://bugs.python.org/issue9516 and bug 659881.
          #
-         # Note that this assumes that nothing compiled in the virtualenv is
-@@ -549,20 +537,17 @@ class VirtualenvManager(VirtualenvHelper
+@@ -522,20 +512,17 @@ class VirtualenvManager(VirtualenvHelper
              # the case that the package requirement is already satisfied.
              from pip._internal.req.constructors import install_req_from_line
  
@@ -81,7 +79,7 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
                  # The setup will by default be performed in an isolated build
                  # environment, and since we're running with --no-index, this
                  # means that pip will be unable to install in the isolated build
-@@ -588,33 +573,26 @@ class VirtualenvManager(VirtualenvHelper
+@@ -561,33 +548,26 @@ class VirtualenvManager(VirtualenvHelper
          If require_hashes is True, each specifier must contain the
          expected hash of the downloaded package. See:
          https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode
@@ -117,8 +115,8 @@ diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/v
  
          "pip" has behaviour to ensure that it doesn't print it's "outdated"
          warning if it's part of a Linux distro package. This is because
-@@ -675,20 +653,17 @@ class VirtualenvManager(VirtualenvHelper
-                               universal_newlines=PY3)
+@@ -666,20 +646,17 @@ def get_archflags():
+     return "-arch {}".format(platform.machine())
  
  
  def verify_python_version(log_handle):

+ 13 - 14
mozilla-release/patches/1714641-05-91a1.patch

@@ -2,7 +2,7 @@
 # User Mitchell Hentges <mhentges@mozilla.com>
 # Date 1623253732 0
 # Node ID fe6e228cb831e7925173550682d6b91543d802ab
-# Parent  a36dc133ab1ca88244ef165a2f32855ba79a40a5
+# Parent  1ec50c80f9724f3ef1c1291478ab3a18cc35a169
 Bug 1714641: Remove usages of vendored "backports" code r=ahal,perftest-reviewers
 
 It provides `shutil.which(...)`, which has been part of `shutil` since
@@ -13,25 +13,24 @@ Differential Revision: https://phabricator.services.mozilla.com/D117063
 diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
 --- a/build/moz.configure/init.configure
 +++ b/build/moz.configure/init.configure
-@@ -307,18 +307,16 @@ def virtualenv_python3(env_python, build
+@@ -284,17 +284,16 @@ def virtualenv_python3(env_python, build
+         manager = VirtualenvManager(
+             topsrcdir,
+             os.path.join(virtualenvs_root, "common"),
+             out,
+             os.path.join(topsrcdir, 'build', 'build_virtualenv_packages.txt'))
  
-     # If we're not in the virtualenv, we need to update the path to include some
-     # necessary modules for find_program.
-     try:
-         import mozfile
-     except ImportError:
-         sys.path.insert(
-             0, os.path.join(topsrcdir, 'testing', 'mozbase', 'mozfile'))
--        sys.path.insert(
--            0, os.path.join(topsrcdir, 'third_party', 'python', 'backports'))
-     else:
-         if 'MOZBUILD_VIRTUALENV' in os.environ or not python:
-             python = sys.executable
+     # Update the path to include some necessary modules for find_program.
+     sys.path.insert(0, os.path.join(topsrcdir, "testing", "mozbase", "mozfile"))
+-    sys.path.insert(0, os.path.join(topsrcdir, "third_party", "python", "backports"))
  
      # If we know the Python executable the caller is asking for then verify its
      # version. If the caller did not ask for a specific executable then find
      # a reasonable default.
      if python:
+         found_python = find_program(python)
+         if not found_python:
+             die('The PYTHON3 environment variable does not contain '
 diff --git a/docs/code-quality/lint/create.rst.1714641_5.later b/docs/code-quality/lint/create.rst.1714641_5.later
 new file mode 100644
 --- /dev/null

+ 95 - 0
mozilla-release/patches/TOP-NOBUG-1712804fix-25320.patch

@@ -0,0 +1,95 @@
+# HG changeset patch
+# User Myckel Habets <gentoo-bugs@habets-dobben.nl>
+# Date 1728397275 -7200
+# Parent  7cd8685cd44a618b542e1e81a1713b8da394109c
+No Bug - Replace hardcoded Thunderbird with comm project in build packages. r=frg a=frg
+
+Rename the "Thunderbird" logic of Bug 1712804 to "commproject".
+The comm dir is used for both SeaMonkey and Thunderbird.
+So far only cosmectic at this point.
+
+diff --git a/build/common_virtualenv_packages.txt b/build/common_virtualenv_packages.txt
+--- a/build/common_virtualenv_packages.txt
++++ b/build/common_virtualenv_packages.txt
+@@ -1,9 +1,9 @@
+-thunderbird:packages.txt:comm/build/virtualenv_packages.txt
++commproject:packages.txt:comm/build/virtualenv_packages.txt
+ mozilla.pth:build
+ mozilla.pth:config
+ mozilla.pth:config/mozunit
+ mozilla.pth:dom/bindings
+ mozilla.pth:dom/bindings/parser
+ mozilla.pth:layout/tools/reftest
+ mozilla.pth:python/mach
+ mozilla.pth:python/mozboot
+diff --git a/python/mozbuild/mozbuild/virtualenv.py b/python/mozbuild/mozbuild/virtualenv.py
+--- a/python/mozbuild/mozbuild/virtualenv.py
++++ b/python/mozbuild/mozbuild/virtualenv.py
+@@ -285,20 +285,20 @@ class VirtualenvManager(VirtualenvHelper
+ 
+         The manifest file consists of colon-delimited fields. The first field
+         specifies the action. The remaining fields are arguments to that
+         action. The following actions are supported:
+ 
+         filename.pth -- Adds the path given as argument to filename.pth under
+             the virtualenv site packages directory.
+ 
+-        thunderbird -- This denotes the action as to only occur for Thunderbird
+-            checkouts. The initial "thunderbird" field is stripped, then the
++        commproject -- This denotes the action as to only occur for comm project
++            checkouts. The initial "commproject" field is stripped, then the
+             remaining line is processed like normal. e.g.
+-            "thunderbird:comms.pth:python/foo"
++            "commproject:comms.pth:python/foo"
+ 
+         packages.txt -- Denotes that the specified path is a child manifest. It
+             will be read and processed as if its contents were concatenated
+             into the manifest being read.
+ 
+         windows -- This denotes that the action should only be taken when run
+             on Windows.
+ 
+@@ -310,19 +310,19 @@ class VirtualenvManager(VirtualenvHelper
+ 
+         Note that the Python interpreter running this function should be the
+         one from the virtualenv. If it is the system Python or if the
+         environment is not configured properly, packages could be installed
+         into the wrong place. This is how virtualenv's work.
+         """
+         import distutils.sysconfig
+ 
+-        thunderbird_dir = os.path.join(self.topsrcdir, "comm")
+-        is_thunderbird = os.path.exists(thunderbird_dir) and bool(
+-            os.listdir(thunderbird_dir)
++        commproject_dir = os.path.join(self.topsrcdir, "comm")
++        is_commproject = os.path.exists(commproject_dir) and bool(
++            os.listdir(commproject_dir)
+         )
+         packages = self.packages()
+         python_lib = distutils.sysconfig.get_python_lib()
+ 
+         def handle_package(package):
+             if package[0] == 'packages.txt':
+                 assert len(package) == 2
+ 
+@@ -341,18 +341,18 @@ class VirtualenvManager(VirtualenvHelper
+                 path = os.path.join(self.topsrcdir, package[1])
+ 
+                 with open(os.path.join(python_lib, package[0]), 'a') as f:
+                     # This path is relative to the .pth file.  Using a
+                     # relative path allows the srcdir/objdir combination
+                     # to be moved around (as long as the paths relative to
+                     # each other remain the same).
+                     f.write("%s\n" % os.path.relpath(path, python_lib))
+-            elif package[0] == "thunderbird":
+-                if is_thunderbird:
++            elif package[0] == "commproject":
++                if is_commproject:
+                     handle_package(package[1:])
+             elif package[0] in ("windows", "!windows"):
+                 for_win = not package[0].startswith('!')
+                 is_win = sys.platform == 'win32'
+                 if is_win == for_win:
+                     handle_package(package[1:])
+             else:
+                 raise Exception("Unknown action: %s" % package[0])

+ 13 - 0
mozilla-release/patches/series

@@ -6889,6 +6889,7 @@ NOBUG-removenonascii67a1-25314.patch
 1638981-2-84a1.patch
 1638977-84a1.patch
 1638947-84a1.patch
+1670197-84a1.patch
 1677187-84a1.patch
 1672940-84a1.patch
 1674923-84a1.patch
@@ -6914,6 +6915,7 @@ NOBUG-removenonascii67a1-25314.patch
 1678291-3-85a1.patch
 1680152-2-85a1.patch
 1680152-3-85a1.patch
+1680353-85a1.patch
 1671545-85a1.patch
 1680345-85a1.patch
 1679056-85a1.patch
@@ -6975,6 +6977,7 @@ NOBUG-20210216-9b29bb9d-87a1.patch
 1682959-1-88a1.patch
 1682959-2-88a1.patch
 1696206-1-88a1.patch
+1696251-1-88a1.patch
 1699950-1-88a1.patch
 1699950-2-88a1.patch
 1699950-3-88a1.patch
@@ -7030,6 +7033,15 @@ NOBUG-20210216-9b29bb9d-87a1.patch
 1665836-7812.patch
 1711576-7812.patch
 1709976-7812.patch
+1712382-1-90a1.patch
+1712382-2-90a1.patch
+1712382-3-90a1.patch
+1712804-1-90a1.patch
+1712804-2-90a1.patch
+1712133-1-90a1.patch
+1712133-2-90a1.patch
+1712133-3-90a1.patch
+1712133-4-90a1.patch
 1712819-1-90a1.patch
 1712819-2-90a1.patch
 1704784-90a1.patch
@@ -7665,3 +7677,4 @@ TOP-NOBUG-fixnasmcheck-25320.patch
 1862395-incorrect-version-resistfingerprinting-v2-25320.patch
 1737436-use-mozilla-compat-version-define-25320.patch
 9999999-removebinary-25320.patch
+TOP-NOBUG-1712804fix-25320.patch