Beispiel #1
0
    def write_setup(self, root_target, reduced_dependencies, chroot):
        """Write the setup.py of a target.

        Must be run after writing the contents to the chroot.
        """
        setup_keywords = root_target.provides.setup_py_keywords.copy()

        package_dir = {"": self.SOURCE_ROOT}
        packages, namespace_packages, resources = self.find_packages(root_target, chroot)

        if namespace_packages:
            setup_keywords["namespace_packages"] = list(sorted(namespace_packages))

        if packages:
            setup_keywords.update(
                package_dir=package_dir,
                packages=list(sorted(packages)),
                package_data=dict(
                    (str(package), list(map(str, rs))) for (package, rs) in resources.items()
                ),
            )

        setup_keywords["install_requires"] = list(self.install_requires(reduced_dependencies))

        for binary_name, entry_point in self.iter_entry_points(root_target):
            if "entry_points" not in setup_keywords:
                setup_keywords["entry_points"] = {}
            if "console_scripts" not in setup_keywords["entry_points"]:
                setup_keywords["entry_points"]["console_scripts"] = []
            setup_keywords["entry_points"]["console_scripts"].append(
                "{} = {}".format(binary_name, entry_point)
            )

        setup_py = self._setup_boilerplate().format(
            setup_dict=distutils_repr(setup_keywords), setup_target=root_target.address.reference()
        )
        chroot.write(ensure_binary(setup_py), "setup.py")

        # Make sure that `setup.py` is included.
        chroot.write("include *.py", "MANIFEST.in", mode="w")
Beispiel #2
0
async def generate_chroot(request: SetupPyChrootRequest) -> SetupPyChroot:
    exported_target = request.exported_target

    owned_deps = await Get[OwnedDependencies](DependencyOwner(exported_target))
    targets = Targets(od.target for od in owned_deps)
    sources = await Get[SetupPySources](SetupPySourcesRequest(targets,
                                                              py2=request.py2))
    requirements = await Get[ExportedTargetRequirements](
        DependencyOwner(exported_target))

    # Nest the sources under the src/ prefix.
    src_digest = await Get[Digest](DirectoryWithPrefixToAdd(
        sources.digest, CHROOT_SOURCE_ROOT))

    target = exported_target.target
    provides = exported_target.provides

    # Generate the kwargs to the setup() call.
    setup_kwargs = provides.setup_py_keywords.copy()
    setup_kwargs.update({
        "package_dir": {
            "": CHROOT_SOURCE_ROOT
        },
        "packages": sources.packages,
        "namespace_packages": sources.namespace_packages,
        "package_data": dict(sources.package_data),
        "install_requires": tuple(requirements),
    })
    key_to_binary_spec = provides.binaries
    keys = list(key_to_binary_spec.keys())
    binaries = await Get[Targets](Addresses(
        Address.parse(key_to_binary_spec[key],
                      relative_to=target.address.spec_path) for key in keys))
    for key, binary in zip(keys, binaries):
        binary_entry_point = binary.get(PythonEntryPoint).value
        if not binary_entry_point:
            raise InvalidEntryPoint(
                f"The binary {key} exported by {target.address.reference()} is not a valid entry "
                f"point.")
        entry_points = setup_kwargs["entry_points"] = setup_kwargs.get(
            "entry_points", {})
        console_scripts = entry_points["console_scripts"] = entry_points.get(
            "console_scripts", [])
        console_scripts.append(f"{key}={binary_entry_point}")

    # Generate the setup script.
    setup_py_content = SETUP_BOILERPLATE.format(
        target_address_spec=target.address.reference(),
        setup_kwargs_str=distutils_repr(setup_kwargs),
    ).encode()
    extra_files_digest = await Get[Digest](
        InputFilesContent([
            FileContent("setup.py", setup_py_content),
            FileContent(
                "MANIFEST.in",
                "include *.py".encode()),  # Make sure setup.py is included.
        ]))

    chroot_digest = await Get[Digest](DirectoriesToMerge(
        (src_digest, extra_files_digest)))
    return SetupPyChroot(chroot_digest, json.dumps(setup_kwargs,
                                                   sort_keys=True))
Beispiel #3
0
async def generate_chroot(request: SetupPyChrootRequest) -> SetupPyChroot:
    exported_target = request.exported_target

    owned_deps = await Get(OwnedDependencies, DependencyOwner(exported_target))
    transitive_targets = await Get(TransitiveTargets,
                                   Addresses([exported_target.target.address]))
    # files() targets aren't owned by a single exported target - they aren't code, so
    # we allow them to be in multiple dists. This is helpful for, e.g., embedding
    # a standard license file in a dist.
    files_targets = (tgt for tgt in transitive_targets.closure
                     if tgt.has_field(FilesSources))
    targets = Targets(
        itertools.chain((od.target for od in owned_deps), files_targets))
    sources = await Get(SetupPySources,
                        SetupPySourcesRequest(targets, py2=request.py2))
    requirements = await Get(ExportedTargetRequirements,
                             DependencyOwner(exported_target))

    # Nest the sources under the src/ prefix.
    src_digest = await Get(Digest, AddPrefix(sources.digest,
                                             CHROOT_SOURCE_ROOT))

    target = exported_target.target
    provides = exported_target.provides

    # Generate the kwargs to the setup() call.
    setup_kwargs = provides.setup_py_keywords.copy()
    setup_kwargs.update({
        "package_dir": {
            "": CHROOT_SOURCE_ROOT
        },
        "packages": sources.packages,
        "namespace_packages": sources.namespace_packages,
        "package_data": dict(sources.package_data),
        "install_requires": tuple(requirements),
    })
    key_to_binary_spec = provides.binaries
    keys = list(key_to_binary_spec.keys())
    binaries = await Get(
        Targets,
        Addresses(
            Address.parse(key_to_binary_spec[key],
                          relative_to=target.address.spec_path)
            for key in keys),
    )
    for key, binary in zip(keys, binaries):
        binary_entry_point = binary.get(PythonEntryPoint).value
        if not binary_entry_point:
            raise InvalidEntryPoint(
                f"The binary {key} exported by {target.address} is not a valid entry point."
            )
        entry_points = setup_kwargs["entry_points"] = setup_kwargs.get(
            "entry_points", {})
        console_scripts = entry_points["console_scripts"] = entry_points.get(
            "console_scripts", [])
        console_scripts.append(f"{key}={binary_entry_point}")

    # Generate the setup script.
    setup_py_content = SETUP_BOILERPLATE.format(
        target_address_spec=target.address.spec,
        setup_kwargs_str=distutils_repr(setup_kwargs),
    ).encode()
    extra_files_digest = await Get(
        Digest,
        CreateDigest([
            FileContent("setup.py", setup_py_content),
            FileContent(
                "MANIFEST.in",
                "include *.py".encode()),  # Make sure setup.py is included.
        ]),
    )

    chroot_digest = await Get(Digest,
                              MergeDigests((src_digest, extra_files_digest)))
    return SetupPyChroot(chroot_digest, json.dumps(setup_kwargs,
                                                   sort_keys=True))
Beispiel #4
0
def test_distutils_repr() -> None:
    assert expected == distutils_repr(testdata)