Esempio n. 1
0
def test_path_globs_to_digest_entries(rule_runner: RuleRunner) -> None:
    setup_fs_test_tar(rule_runner)

    def get_entries(globs: Iterable[str]) -> Set[Union[FileEntry, Directory]]:
        return set(rule_runner.request(DigestEntries, [PathGlobs(globs)]))

    assert get_entries(["4.txt", "a/4.txt.ln"]) == {
        FileEntry(
            "4.txt",
            FileDigest("ab929fcd5594037960792ea0b98caf5fdaf6b60645e4ef248c28db74260f393e", 5),
        ),
        FileEntry(
            "a/4.txt.ln",
            FileDigest("ab929fcd5594037960792ea0b98caf5fdaf6b60645e4ef248c28db74260f393e", 5),
        ),
    }
    assert get_entries(["c.ln/../3.txt"]) == {
        FileEntry(
            "c.ln/../3.txt",
            FileDigest("f6936912184481f5edd4c304ce27c5a1a827804fc7f329f43d273b8621870776", 6),
        )
    }

    # Directories are empty.
    assert get_entries(["a/b"]) == {Directory("a/b")}
    assert get_entries(["c.ln"]) == {Directory("c.ln")}
Esempio n. 2
0
async def render_war_deployment_descriptor(
    request: RenderWarDeploymentDescriptorRequest,
) -> RenderedWarDeploymentDescriptor:
    descriptor_sources = await Get(
        HydratedSources,
        HydrateSourcesRequest(request.descriptor),
    )

    descriptor_sources_entries = await Get(DigestEntries, Digest,
                                           descriptor_sources.snapshot.digest)
    if len(descriptor_sources_entries) != 1:
        raise AssertionError(
            f"Expected `descriptor` field for {request.descriptor.address} to only refer to one file."
        )
    descriptor_entry = descriptor_sources_entries[0]
    if not isinstance(descriptor_entry, FileEntry):
        raise AssertionError(
            f"Expected `descriptor` field for {request.descriptor.address} to produce a file."
        )

    descriptor_digest = await Get(
        Digest,
        CreateDigest([
            FileEntry("__war__/WEB-INF/web.xml", descriptor_entry.file_digest)
        ]),
    )

    return RenderedWarDeploymentDescriptor(descriptor_digest)
Esempio n. 3
0
async def package_debian_package(field_set: DebianPackageFieldSet,
                                 tar_binary_path: TarBinary) -> BuiltPackage:
    dpkg_deb_path = await Get(
        BinaryPaths,
        BinaryPathRequest(
            binary_name="dpkg-deb",
            search_path=["/usr/bin"],
        ),
    )
    if not dpkg_deb_path.first_path:
        raise OSError(
            f"Could not find the `{dpkg_deb_path.binary_name}` program in `/usr/bin`."
        )

    hydrated_sources = await Get(HydratedSources,
                                 HydrateSourcesRequest(field_set.sources_dir))

    # Since all the sources are coming only from a single directory, it is
    # safe to pick an arbitrary file and get its root directory name.
    # Validation of the resolved files has been called on the target, so it is known that
    # snapshot.files isn't empty.
    sources_directory_name = PurePath(
        hydrated_sources.snapshot.files[0]).parts[0]

    result = await Get(
        ProcessResult,
        Process(
            argv=(
                dpkg_deb_path.first_path.path,
                "--build",
                sources_directory_name,
            ),
            description="Create a Debian package from the produced packages.",
            input_digest=hydrated_sources.snapshot.digest,
            # dpkg-deb produces a file with the same name as the input directory
            output_files=(f"{sources_directory_name}.deb", ),
            env={"PATH": str(PurePath(tar_binary_path.path).parent)},
        ),
    )
    # The output Debian package file needs to be renamed to match the output_path field.
    output_filename = field_set.output_path.value_or_default(
        file_ending="deb", )
    digest_entries = await Get(DigestEntries, Digest, result.output_digest)
    assert len(digest_entries) == 1
    result_file_entry = digest_entries[0]
    assert isinstance(result_file_entry, FileEntry)
    new_file = FileEntry(output_filename, result_file_entry.file_digest)

    final_result = await Get(Digest, CreateDigest([new_file]))
    return BuiltPackage(final_result,
                        artifacts=(BuiltPackageArtifact(output_filename), ))
Esempio n. 4
0
def test_digest_entries_handles_empty_directory(rule_runner: RuleRunner) -> None:
    digest = rule_runner.request(
        Digest, [CreateDigest([Directory("a/b"), FileContent("a/foo.txt", b"four\n")])]
    )
    entries = rule_runner.request(DigestEntries, [digest])
    assert entries == DigestEntries(
        [
            Directory("a/b"),
            FileEntry(
                "a/foo.txt",
                FileDigest("ab929fcd5594037960792ea0b98caf5fdaf6b60645e4ef248c28db74260f393e", 5),
            ),
        ]
    )
Esempio n. 5
0
async def handle_bsp_scalac_options_request(
    request: HandleScalacOptionsRequest,
    build_root: BuildRoot,
    workspace: Workspace,
) -> HandleScalacOptionsResult:
    bsp_target = await Get(BSPBuildTargetInternal, BuildTargetIdentifier,
                           request.bsp_target_id)
    targets = await Get(
        Targets,
        AddressSpecs,
        bsp_target.specs.address_specs,
    )
    coarsened_targets = await Get(CoarsenedTargets,
                                  Addresses(tgt.address for tgt in targets))
    resolve = await Get(CoursierResolveKey, CoarsenedTargets,
                        coarsened_targets)
    lockfile = await Get(CoursierResolvedLockfile, CoursierResolveKey, resolve)

    resolve_digest = await Get(
        Digest,
        CreateDigest([
            FileEntry(entry.file_name, entry.file_digest)
            for entry in lockfile.entries
        ]),
    )

    resolve_digest = await Get(
        Digest, AddPrefix(resolve_digest, f"jvm/resolves/{resolve.name}/lib"))

    workspace.write_digest(resolve_digest, path_prefix=".pants.d/bsp")

    classpath = [
        build_root.pathlib_path.joinpath(
            f".pants.d/bsp/jvm/resolves/{resolve.name}/lib/{entry.file_name}").
        as_uri() for entry in lockfile.entries
    ]

    return HandleScalacOptionsResult(
        ScalacOptionsItem(
            target=request.bsp_target_id,
            options=(),
            classpath=tuple(classpath),
            class_directory=build_root.pathlib_path.joinpath(
                f".pants.d/bsp/jvm/resolves/{resolve.name}/classes").as_uri(),
        ))
Esempio n. 6
0
async def _hydrate_asset_source(
        request: GenerateSourcesRequest) -> GeneratedSources:
    target = request.protocol_target
    source_field = target[AssetSourceField]
    if isinstance(source_field.value, str):
        return GeneratedSources(request.protocol_sources)

    http_source = source_field.value
    file_digest = FileDigest(http_source.sha256, http_source.len)
    # NB: This just has to run, we don't actually need the result because we know the Digest's
    # FileEntry metadata.
    await Get(Digest, DownloadFile(http_source.url, file_digest))
    snapshot = await Get(
        Snapshot,
        CreateDigest([
            FileEntry(
                path=source_field.file_path,
                file_digest=file_digest,
            )
        ]),
    )

    return GeneratedSources(snapshot)
Esempio n. 7
0
async def package_war(
    field_set: PackageWarFileFieldSet,
    bash: BashBinary,
    zip: ZipBinary,
) -> BuiltPackage:
    classpath = await Get(Classpath,
                          DependenciesRequest(field_set.dependencies))
    all_jar_files_digest = await Get(Digest, MergeDigests(classpath.digests()))

    prefixed_jars_digest, content, descriptor, input_setup_digest = await MultiGet(
        Get(Digest, AddPrefix(all_jar_files_digest, "__war__/WEB-INF/lib")),
        Get(RenderedWarContent, RenderWarContentRequest(field_set.content)),
        Get(
            RenderedWarDeploymentDescriptor,
            RenderWarDeploymentDescriptorRequest(field_set.descriptor,
                                                 field_set.address),
        ),
        Get(
            Digest,
            CreateDigest([
                FileContent(
                    "make_war.sh",
                    textwrap.dedent(f"""\
                    cd __war__
                    {zip.path} ../output.war -r .
                    """).encode(),
                    is_executable=True,
                ),
                Directory("__war__/WEB-INF/classes"),
                Directory("__war__/WEB-INF/lib"),
            ]),
        ),
    )

    input_digest = await Get(
        Digest,
        MergeDigests([
            prefixed_jars_digest,
            descriptor.digest,
            content.digest,
            input_setup_digest,
        ]),
    )

    result = await Get(
        ProcessResult,
        Process(
            [bash.path, "make_war.sh"],
            input_digest=input_digest,
            output_files=("output.war", ),
            description=f"Assemble WAR file for {field_set.address}",
        ),
    )

    output_entries = await Get(DigestEntries, Digest, result.output_digest)
    if len(output_entries) != 1:
        raise AssertionError("No output from war assembly step.")
    output_entry = output_entries[0]
    if not isinstance(output_entry, FileEntry):
        raise AssertionError("Unexpected digest entry")
    output_filename = PurePath(
        field_set.output_path.value_or_default(file_ending="war"))
    package_digest = await Get(
        Digest,
        CreateDigest(
            [FileEntry(str(output_filename), output_entry.file_digest)]))
    artifact = BuiltPackageArtifact(relpath=str(output_filename))
    return BuiltPackage(digest=package_digest, artifacts=(artifact, ))
Esempio n. 8
0
async def scala_bsp_dependency_modules(
    request: ScalaBSPDependencyModulesRequest,
    build_root: BuildRoot,
) -> BSPDependencyModulesResult:
    coarsened_targets = await Get(
        CoarsenedTargets, Addresses([fs.address for fs in request.field_sets]))
    resolve = await Get(CoursierResolveKey, CoarsenedTargets,
                        coarsened_targets)
    lockfile = await Get(CoursierResolvedLockfile, CoursierResolveKey, resolve)

    # TODO: Can this use ClasspathEntryRequest?
    transitive_targets = await Get(
        TransitiveTargets,
        TransitiveTargetsRequest(roots=[
            tgt.address for coarsened_target in coarsened_targets
            for tgt in coarsened_target.members
        ]),
    )

    artifact_requirements = [
        ArtifactRequirement.from_jvm_artifact_target(tgt)
        for tgt in transitive_targets.closure
        if JvmArtifactFieldSet.is_applicable(tgt)
    ]

    applicable_lockfile_entries: set[CoursierLockfileEntry] = set()
    for artifact_requirement in artifact_requirements:
        entry = get_entry_for_coord(lockfile, artifact_requirement.coordinate)
        if not entry:
            _logger.warning(
                f"No lockfile entry for {artifact_requirement.coordinate} in resolve {resolve.name}."
            )
            continue
        applicable_lockfile_entries.add(entry)

    resolve_digest = await Get(
        Digest,
        CreateDigest([
            FileEntry(entry.file_name, entry.file_digest)
            for entry in applicable_lockfile_entries
        ]),
    )

    resolve_digest = await Get(
        Digest, AddPrefix(resolve_digest, f"jvm/resolves/{resolve.name}/lib"))

    modules = [
        DependencyModule(
            name=f"{entry.coord.group}:{entry.coord.artifact}",
            version=entry.coord.version,
            data=MavenDependencyModule(
                organization=entry.coord.group,
                name=entry.coord.artifact,
                version=entry.coord.version,
                scope=None,
                artifacts=(MavenDependencyModuleArtifact(
                    uri=build_root.pathlib_path.joinpath(
                        f".pants.d/bsp/jvm/resolves/{resolve.name}/lib/{entry.file_name}"
                    ).as_uri()), ),
            ),
        ) for entry in applicable_lockfile_entries
    ]

    return BSPDependencyModulesResult(
        modules=tuple(modules),
        digest=resolve_digest,
    )