• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25259185675

02 May 2026 06:47PM UTC coverage: 92.141% (-0.8%) from 92.955%
25259185675

push

github

web-flow
Fix the dynamic UI. (#23306)

In #23114 we upgraded to indicatif 0.18.4,
which included a fix to respect TERM, and 
display nothing if it's unset.

Since we did not pass TERM through pantsd, the
dynamic ui is now not shown. 

This change fixes that, and also pass NO_COLOR
through, since indicatif inspects it too.

88773 of 96345 relevant lines covered (92.14%)

3.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/python/pants/backend/debian/rules.py
1
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

4
from __future__ import annotations
×
5

6
from collections.abc import Iterable
×
7
from dataclasses import dataclass
×
8
from pathlib import PurePath
×
9

10
from pants.backend.debian.target_types import (
×
11
    DebianInstallPrefix,
12
    DebianPackageDependencies,
13
    DebianSources,
14
)
15
from pants.core.goals.package import (
×
16
    BuiltPackage,
17
    BuiltPackageArtifact,
18
    OutputPathField,
19
    PackageFieldSet,
20
)
21
from pants.core.util_rules.system_binaries import BinaryPathRequest, TarBinary, find_binary
×
22
from pants.engine.fs import CreateDigest, FileEntry
×
23
from pants.engine.internals.graph import hydrate_sources
×
24
from pants.engine.intrinsics import create_digest, get_digest_entries
×
25
from pants.engine.process import Process, execute_process_or_raise
×
26
from pants.engine.rules import Rule, collect_rules, implicitly, rule
×
27
from pants.engine.target import HydrateSourcesRequest
×
28
from pants.engine.unions import UnionRule
×
29
from pants.util.logging import LogLevel
×
30

31

32
@dataclass(frozen=True)
×
33
class DebianPackageFieldSet(PackageFieldSet):
×
34
    required_fields = (DebianSources, DebianInstallPrefix, DebianPackageDependencies)
×
35

36
    sources_dir: DebianSources
×
37
    install_prefix: DebianInstallPrefix
×
38
    packages: DebianPackageDependencies
×
39
    output_path: OutputPathField
×
40

41

42
@rule(level=LogLevel.INFO)
×
43
async def package_debian_package(
×
44
    field_set: DebianPackageFieldSet, tar_binary_path: TarBinary
45
) -> BuiltPackage:
46
    dpkg_deb_path = await find_binary(
×
47
        BinaryPathRequest(
48
            binary_name="dpkg-deb",
49
            search_path=["/usr/bin"],
50
        ),
51
        **implicitly(),
52
    )
53
    if not dpkg_deb_path.first_path:
×
54
        raise OSError(f"Could not find the `{dpkg_deb_path.binary_name}` program in `/usr/bin`.")
×
55

56
    hydrated_sources = await hydrate_sources(
×
57
        HydrateSourcesRequest(field_set.sources_dir), **implicitly()
58
    )
59

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

66
    result = await execute_process_or_raise(
×
67
        **implicitly(
68
            Process(
69
                argv=(
70
                    dpkg_deb_path.first_path.path,
71
                    "--build",
72
                    sources_directory_name,
73
                ),
74
                description="Create a Debian package from the produced packages.",
75
                input_digest=hydrated_sources.snapshot.digest,
76
                # dpkg-deb produces a file with the same name as the input directory
77
                output_files=(f"{sources_directory_name}.deb",),
78
                env={"PATH": str(PurePath(tar_binary_path.path).parent)},
79
            )
80
        )
81
    )
82
    # The output Debian package file needs to be renamed to match the output_path field.
83
    output_filename = field_set.output_path.value_or_default(
×
84
        file_ending="deb",
85
    )
86
    digest_entries = await get_digest_entries(result.output_digest)
×
87
    assert len(digest_entries) == 1
×
88
    result_file_entry = digest_entries[0]
×
89
    assert isinstance(result_file_entry, FileEntry)
×
90
    new_file = FileEntry(output_filename, result_file_entry.file_digest)
×
91

92
    final_result = await create_digest(CreateDigest([new_file]))
×
93
    return BuiltPackage(final_result, artifacts=(BuiltPackageArtifact(output_filename),))
×
94

95

96
def rules() -> Iterable[Rule | UnionRule]:
×
97
    return (
×
98
        *collect_rules(),
99
        UnionRule(PackageFieldSet, DebianPackageFieldSet),
100
    )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc