Example #1
0
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))
Example #2
0
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)
    )
Example #3
0
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))
Example #4
0
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 test_generated_build_file_has_filegroup_target(self) -> None:
     wheel_name = "example_minimal_package-0.0.1-py3-none-any.whl"
     wheel_dir = "examples/wheel/"
     wheel_path = wheel_dir + wheel_name
     generated_bazel_dir = bazel.extract_wheel(
         wheel_path,
         extras={},
         pip_data_exclude=[],
         enable_implicit_namespace_pkgs=False,
     )[2:]  # Take off the leading // from the returned label.
     # Assert that the raw wheel ends up in the package.
     self.assertIn(wheel_name, os.listdir(generated_bazel_dir))
     with open("{}/BUILD.bazel".format(generated_bazel_dir)) as build_file:
         build_file_content = build_file.read()
         self.assertIn('filegroup', build_file_content)
Example #6
0
 def _run(
     self,
     incremental: bool = False,
     incremental_repo_prefix: Optional[str] = None,
 ) -> None:
     generated_bazel_dir = bazel.extract_wheel(
         self.wheel_path,
         extras={},
         pip_data_exclude=[],
         enable_implicit_namespace_pkgs=False,
         incremental=incremental,
         incremental_repo_prefix=incremental_repo_prefix)[
             2:]  # Take off the leading // from the returned label.
     # Assert that the raw wheel ends up in the package.
     self.assertIn(self.wheel_name, os.listdir(generated_bazel_dir))
     with open("{}/BUILD.bazel".format(generated_bazel_dir)) as build_file:
         build_file_content = build_file.read()
         self.assertIn('filegroup', build_file_content)
Example #7
0
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",
    )
    parser.add_argument(
        "--repo",
        action="store",
        required=True,
        help="The external repo name to install dependencies. In the format '@{REPO_NAME}'",
    )
    parser.add_argument(
        "--extra_pip_args", action="store", help="Extra arguments to pass down to pip.",
    )
    parser.add_argument(
        "--pip_data_exclude",
        action="store",
        help="Additional data exclusion parameters to add to the pip packages BUILD file.",
    )
    parser.add_argument(
        "--enable_implicit_namespace_pkgs",
        action="store_true",
        help="Disables conversion of implicit namespace packages into pkg-util style packages.",
    )
    args = parser.parse_args()

    pip_args = [sys.executable, "-m", "pip", "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 = []

    targets = [
        '"%s%s"'
        % (
            args.repo,
            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(args.repo, targets)
        )