def main() -> None: parser = argparse.ArgumentParser( description="Create rules to incrementally fetch needed \ dependencies from a fully resolved requirements lock file.") parser.add_argument( "--requirements_lock", action="store", required=True, help= "Path to fully resolved requirements.txt to use as the source of repos.", ) parser.add_argument( "--quiet", type=bool, action="store", required=True, help="Whether to print stdout / stderr from child repos.", ) parser.add_argument( "--timeout", type=int, action="store", required=True, help="timeout to use for pip operation.", ) arguments.parse_common_args(parser) args = parser.parse_args() with open("requirements.bzl", "w") as requirement_file: requirement_file.write(generate_parsed_requirements_contents(args))
def main() -> None: """Main program. Exits zero on successful program termination, non-zero otherwise. """ configure_reproducible_wheels() parser = argparse.ArgumentParser( description="Resolve and fetch artifacts transitively from PyPI") parser.add_argument( "--requirements", action="store", required=True, help="Path to requirements.txt from where to install dependencies", ) arguments.parse_common_args(parser) args = parser.parse_args() deserialized_args = dict(vars(args)) arguments.deserialize_structured_args(deserialized_args) # Pip is run with the working directory changed to the folder containing the requirements.txt file, to allow for # relative requirements to be correctly resolved. The --wheel-dir is therefore required to be repointed back to the # current calling working directory (the repo root in .../external/name), where the wheel files should be written to pip_args = ([sys.executable, "-m", "pip"] + (["--isolated"] if args.isolated else []) + ["wheel", "-r", args.requirements] + ["--wheel-dir", os.getcwd()] + deserialized_args["extra_pip_args"]) env = os.environ.copy() env.update(deserialized_args["environment"]) # Assumes any errors are logged by pip so do nothing. This command will fail if pip fails subprocess.run(pip_args, check=True, env=env, cwd=str(pathlib.Path(args.requirements).parent.resolve())) extras = requirements.parse_extras(args.requirements) repo_label = "@%s" % args.repo targets = [ '"%s%s"' % ( repo_label, bazel.extract_wheel(whl, extras, deserialized_args["pip_data_exclude"], args.enable_implicit_namespace_pkgs), ) for whl in glob.glob("*.whl") ] with open("requirements.bzl", "w") as requirement_file: requirement_file.write( bazel.generate_requirements_file_contents(repo_label, targets))
def main() -> None: parser = argparse.ArgumentParser( description= "Build and/or fetch a single wheel based on the requirement passed in") parser.add_argument( "--requirement", action="store", required=True, help="A single PEP508 requirement specifier string.", ) arguments.parse_common_args(parser) args = parser.parse_args() deserialized_args = dict(vars(args)) arguments.deserialize_structured_args(deserialized_args) configure_reproducible_wheels() pip_args = ([sys.executable, "-m", "pip"] + (["--isolated"] if args.isolated else []) + ["wheel", "--no-deps"] + deserialized_args["extra_pip_args"]) requirement_file = NamedTemporaryFile(mode='wb', delete=False) try: requirement_file.write(args.requirement.encode("utf-8")) requirement_file.flush() # Close the file so pip is allowed to read it when running on Windows. # For more information, see: https://bugs.python.org/issue14243 requirement_file.close() # Requirement specific args like --hash can only be passed in a requirements file, # so write our single requirement into a temp file in case it has any of those flags. pip_args.extend(["-r", requirement_file.name]) env = os.environ.copy() env.update(deserialized_args["environment"]) # Assumes any errors are logged by pip so do nothing. This command will fail if pip fails subprocess.run(pip_args, check=True, env=env) finally: try: os.unlink(requirement_file.name) except OSError as e: if e.errno != errno.ENOENT: raise name, extras_for_pkg = requirements._parse_requirement_for_extra( args.requirement) extras = {name: extras_for_pkg} if extras_for_pkg and name else dict() whl = next(iter(glob.glob("*.whl"))) bazel.extract_wheel(whl, extras, deserialized_args["pip_data_exclude"], args.enable_implicit_namespace_pkgs, incremental=True, incremental_repo_prefix=bazel.whl_library_repo_prefix( args.repo))
def main() -> None: """Main program. Exits zero on successful program termination, non-zero otherwise. """ configure_reproducible_wheels() parser = argparse.ArgumentParser( description="Resolve and fetch artifacts transitively from PyPI") parser.add_argument( "--requirements", action="store", required=True, help="Path to requirements.txt from where to install dependencies", ) arguments.parse_common_args(parser) args = parser.parse_args() pip_args = [ sys.executable, "-m", "pip", "--isolated", "wheel", "-r", args.requirements ] if args.extra_pip_args: pip_args += json.loads(args.extra_pip_args)["args"] # Assumes any errors are logged by pip so do nothing. This command will fail if pip fails subprocess.run(pip_args, check=True) extras = requirements.parse_extras(args.requirements) if args.pip_data_exclude: pip_data_exclude = json.loads(args.pip_data_exclude)["exclude"] else: pip_data_exclude = [] repo_label = "@%s" % args.repo targets = [ '"%s%s"' % ( repo_label, bazel.extract_wheel(whl, extras, pip_data_exclude, args.enable_implicit_namespace_pkgs), ) for whl in glob.glob("*.whl") ] with open("requirements.bzl", "w") as requirement_file: requirement_file.write( bazel.generate_requirements_file_contents(repo_label, targets))
def main() -> None: parser = argparse.ArgumentParser( description="Build and/or fetch a single wheel based on the requirement passed in" ) parser.add_argument( "--requirement", action="store", required=True, help="A single PEP508 requirement specifier string.", ) arguments.parse_common_args(parser) args = parser.parse_args() configure_reproducible_wheels() pip_args = [sys.executable, "-m", "pip", "--isolated", "wheel", "--no-deps"] if args.extra_pip_args: pip_args += json.loads(args.extra_pip_args)["args"] with NamedTemporaryFile(mode='wb') as requirement_file: requirement_file.write(args.requirement.encode("utf-8")) requirement_file.flush() # Requirement specific args like --hash can only be passed in a requirements file, # so write our single requirement into a temp file in case it has any of those flags. pip_args.extend(["-r", requirement_file.name]) # Assumes any errors are logged by pip so do nothing. This command will fail if pip fails subprocess.run(pip_args, check=True) name, extras_for_pkg = requirements._parse_requirement_for_extra(args.requirement) extras = {name: extras_for_pkg} if extras_for_pkg and name else dict() if args.pip_data_exclude: pip_data_exclude = json.loads(args.pip_data_exclude)["exclude"] else: pip_data_exclude = [] whl = next(iter(glob.glob("*.whl"))) bazel.extract_wheel( whl, extras, pip_data_exclude, args.enable_implicit_namespace_pkgs, incremental=True, incremental_repo_prefix=bazel.whl_library_repo_prefix(args.repo) )
def main() -> None: parser = argparse.ArgumentParser( description="Create rules to incrementally fetch needed \ dependencies from a fully resolved requirements lock file." ) parser.add_argument( "--requirements_lock", action="store", required=True, help="Path to fully resolved requirements.txt to use as the source of repos.", ) parser.add_argument( "--python_interpreter", help="The python interpreter that will be used to download and unpack the wheels.", ) parser.add_argument( "--python_interpreter_target", help="Bazel target of a python interpreter.\ It will be used in repository rules so it must be an already built interpreter.\ If set, it will take precedence over python_interpreter.", ) parser.add_argument( "--quiet", type=coerce_to_bool, default=True, required=True, help="Whether to print stdout / stderr from child repos.", ) parser.add_argument( "--timeout", type=int, action="store", required=True, help="timeout to use for pip operation.", ) arguments.parse_common_args(parser) args = parser.parse_args() with open("requirements.bzl", "w") as requirement_file: requirement_file.write( generate_parsed_requirements_contents(args) )
def test_arguments(self) -> None: parser = argparse.ArgumentParser() parser = arguments.parse_common_args(parser) repo_name = "foo" index_url = "--index_url=pypi.org/simple" args_dict = vars(parser.parse_args( args=["--repo", repo_name, "--extra_pip_args={index_url}".format(index_url=json.dumps({"args": index_url}))])) args_dict = deserialize_structured_args(args_dict) self.assertIn("repo", args_dict) self.assertIn("extra_pip_args", args_dict) self.assertEqual(args_dict["pip_data_exclude"], None) self.assertEqual(args_dict["enable_implicit_namespace_pkgs"], False) self.assertEqual(args_dict["repo"], repo_name) self.assertEqual(args_dict["extra_pip_args"], index_url)
def test_arguments(self) -> None: parser = argparse.ArgumentParser() parser = arguments.parse_common_args(parser) repo_name = "foo" index_url = "--index_url=pypi.org/simple" extra_pip_args = [index_url] args_dict = vars(parser.parse_args( args=["--repo", repo_name, f"--extra_pip_args={json.dumps({'arg': extra_pip_args})}"])) args_dict = arguments.deserialize_structured_args(args_dict) self.assertIn("repo", args_dict) self.assertIn("extra_pip_args", args_dict) self.assertEqual(args_dict["pip_data_exclude"], []) self.assertEqual(args_dict["enable_implicit_namespace_pkgs"], False) self.assertEqual(args_dict["repo"], repo_name) self.assertEqual(args_dict["extra_pip_args"], extra_pip_args)