diff options
Diffstat (limited to 'python/mozbuild/mozbuild/vendor/mach_commands.py')
-rw-r--r-- | python/mozbuild/mozbuild/vendor/mach_commands.py | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/vendor/mach_commands.py b/python/mozbuild/mozbuild/vendor/mach_commands.py new file mode 100644 index 0000000000..30fb0e16a5 --- /dev/null +++ b/python/mozbuild/mozbuild/vendor/mach_commands.py @@ -0,0 +1,232 @@ +# 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/. + +import logging +import sys + +from mach.decorators import Command, CommandArgument, SubCommand + +from mozbuild.vendor.moz_yaml import MozYamlVerifyError, load_moz_yaml + + +# Fun quirk of ./mach - you can specify a default argument as well as subcommands. +# If the default argument matches a subcommand, the subcommand gets called. If it +# doesn't, we wind up in the default command. +@Command( + "vendor", + category="misc", + description="Vendor third-party dependencies into the source repository.", +) +@CommandArgument( + "--check-for-update", + action="store_true", + help="For scripted use, prints the new commit to update to, or nothing if up to date.", + default=False, +) +@CommandArgument( + "--add-to-exports", + action="store_true", + help="Will attempt to add new header files into any relevant EXPORTS block.", + default=False, +) +@CommandArgument( + "--ignore-modified", + action="store_true", + help="Ignore modified files in current checkout.", + default=False, +) +@CommandArgument("-r", "--revision", help="Repository tag or commit to update to.") +@CommandArgument( + "-f", + "--force", + action="store_true", + help="Force a re-vendor even if we're up to date", +) +@CommandArgument( + "--verify", "-v", action="store_true", help="(Only) verify the manifest." +) +@CommandArgument( + "--patch-mode", + help="Select how vendored patches will be imported. 'none' skips patch import, and" + "'only' imports patches and skips library vendoring.", + default="", +) +@CommandArgument("library", nargs=1, help="The moz.yaml file of the library to vendor.") +def vendor( + command_context, + library, + revision, + ignore_modified=False, + check_for_update=False, + add_to_exports=False, + force=False, + verify=False, + patch_mode="", +): + """ + Vendor third-party dependencies into the source repository. + + Vendoring rust and python can be done with ./mach vendor [rust/python]. + Vendoring other libraries can be done with ./mach vendor [arguments] path/to/file.yaml + """ + library = library[0] + assert library not in ["rust", "python"] + + command_context.populate_logger() + command_context.log_manager.enable_unstructured() + if check_for_update: + logging.disable(level=logging.CRITICAL) + + try: + manifest = load_moz_yaml(library) + if verify: + print("%s: OK" % library) + sys.exit(0) + except MozYamlVerifyError as e: + print(e) + sys.exit(1) + + if "vendoring" not in manifest: + raise Exception( + "Cannot perform update actions if we don't have a 'vendoring' section in the moz.yaml" + ) + + if patch_mode and patch_mode not in ["none", "only"]: + print( + "Unknown patch mode given '%s'. Please use one of: 'none' or 'only'." + % patch_mode + ) + sys.exit(1) + if ( + manifest["vendoring"].get("patches", []) + and not patch_mode + and not check_for_update + ): + print( + "Patch mode was not given when required. Please use one of: 'none' or 'only'" + ) + sys.exit(1) + if patch_mode == "only" and not manifest["vendoring"].get("patches", []): + print( + "Patch import was specified for %s but there are no vendored patches defined." + % library + ) + sys.exit(1) + + if not ignore_modified and not check_for_update: + check_modified_files(command_context) + elif ignore_modified and not check_for_update: + print( + "Because you passed --ignore-modified we will not be " + + "able to detect spurious upstream updates." + ) + + if not revision: + revision = "HEAD" + + from mozbuild.vendor.vendor_manifest import VendorManifest + + vendor_command = command_context._spawn(VendorManifest) + vendor_command.vendor( + command_context, + library, + manifest, + revision, + ignore_modified, + check_for_update, + force, + add_to_exports, + patch_mode, + ) + + sys.exit(0) + + +def check_modified_files(command_context): + """ + Ensure that there aren't any uncommitted changes to files + in the working copy, since we're going to change some state + on the user. + """ + modified = command_context.repository.get_changed_files("M") + if modified: + command_context.log( + logging.ERROR, + "modified_files", + {}, + """You have uncommitted changes to the following files: + +{files} + +Please commit or stash these changes before vendoring, or re-run with `--ignore-modified`. +""".format( + files="\n".join(sorted(modified)) + ), + ) + sys.exit(1) + + +# ===================================================================== + + +@SubCommand( + "vendor", + "rust", + description="Vendor rust crates from crates.io into third_party/rust", +) +@CommandArgument( + "--ignore-modified", + action="store_true", + help="Ignore modified files in current checkout", + default=False, +) +@CommandArgument( + "--build-peers-said-large-imports-were-ok", + action="store_true", + help=( + "Permit overly-large files to be added to the repository. " + "To get permission to set this, raise a question in the #build " + "channel at https://chat.mozilla.org." + ), + default=False, +) +@CommandArgument( + "--issues-json", + help="Path to a code-review issues.json file to write out", +) +def vendor_rust(command_context, **kwargs): + from mozbuild.vendor.vendor_rust import VendorRust + + vendor_command = command_context._spawn(VendorRust) + issues_json = kwargs.pop("issues_json", None) + ok = vendor_command.vendor(**kwargs) + if issues_json: + with open(issues_json, "w") as fh: + fh.write(vendor_command.serialize_issues_json()) + sys.exit(0 if ok else 1) + + +# ===================================================================== + + +@SubCommand( + "vendor", + "python", + description="Vendor Python packages from pypi.org into third_party/python. " + "Some extra files like docs and tests will automatically be excluded." + "Installs the packages listed in third_party/python/requirements.in and " + "their dependencies.", + virtualenv_name="vendor", +) +@CommandArgument( + "--keep-extra-files", + action="store_true", + default=False, + help="Keep all files, including tests and documentation.", +) +def vendor_python(command_context, keep_extra_files): + from mozbuild.vendor.vendor_python import VendorPython + + vendor_command = command_context._spawn(VendorPython) + vendor_command.vendor(keep_extra_files) |