Coverage for src/debputy/build_support/build_context.py: 60%
45 statements
« prev ^ index » next coverage.py v7.6.0, created at 2025-01-27 13:59 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2025-01-27 13:59 +0000
1from typing import Mapping, Optional, TYPE_CHECKING
3from debputy.architecture_support import DpkgArchitectureBuildProcessValuesTable
4from debputy.manifest_conditions import _run_build_time_tests
6if TYPE_CHECKING:
7 from debputy.commands.debputy_cmd.context import CommandContext
10class BuildContext:
11 @staticmethod
12 def from_command_context(
13 cmd_context: "CommandContext",
14 ) -> "BuildContext":
15 return BuildContextImpl(cmd_context)
17 @property
18 def deb_build_options(self) -> Mapping[str, Optional[str]]:
19 raise NotImplementedError
21 def parallelization_limit(self, *, support_zero_as_unlimited: bool = False) -> int:
22 """Parallelization limit of the build
24 This is accessor that reads the `parallel` option from `DEB_BUILD_OPTIONS` with relevant
25 fallback behavior.
27 :param support_zero_as_unlimited: The debhelper framework allowed `0` to mean unlimited
28 in some build systems. If the build system supports this, it should set this option
29 to True, which will allow `0` as a possible return value. WHen this option is False
30 (which is the default), `0` will be remapped to a high number to preserve the effect
31 in spirit (said fallback number is also from `debhelper`).
32 """
33 limit = self.deb_build_options.get("parallel")
34 if limit is None:
35 return 1
36 try:
37 v = int(limit)
38 except ValueError:
39 return 1
40 if v == 0 and not support_zero_as_unlimited:
41 # debhelper allowed "0" to be used as unlimited in some cases. Preserve that feature
42 # for callers that are prepared for it. For everyone else, remap 0 to an obscene number
43 # that de facto has the same behavior
44 #
45 # The number is taken out of `cmake.pm` from `debhelper` to be "Bug compatible" with
46 # debhelper on the fallback as well.
47 return 999
48 return v
50 @property
51 def is_terse_build(self) -> bool:
52 """Whether the build is terse
54 This is a shorthand for testing for `terse` in DEB_BUILD_OPTIONS
55 """
56 return "terse" in self.deb_build_options
58 @property
59 def is_cross_compiling(self) -> bool:
60 """Whether the build is considered a cross build
62 Note: Do **not** use this as indicator for whether tests should run. Use `should_run_tests` instead.
63 To the naive eye, they seem like they overlap in functionality, but they do not. There are cross
64 builds where tests can be run. Additionally, there are non-cross-builds where tests should be
65 skipped.
66 """
67 return self.dpkg_architecture_variables.is_cross_compiling
69 def cross_tool(self, command: str) -> str:
70 if not self.is_cross_compiling:
71 return command
72 cross_prefix = self.dpkg_architecture_variables["DEB_HOST_GNU_TYPE"]
73 return f"{cross_prefix}-{command}"
75 @property
76 def dpkg_architecture_variables(self) -> DpkgArchitectureBuildProcessValuesTable:
77 raise NotImplementedError
79 @property
80 def should_run_tests(self) -> bool:
81 return _run_build_time_tests(self.deb_build_options)
84class BuildContextImpl(BuildContext):
85 def __init__(
86 self,
87 cmd_context: "CommandContext",
88 ) -> None:
89 self._cmd_context = cmd_context
91 @property
92 def deb_build_options(self) -> Mapping[str, Optional[str]]:
93 return self._cmd_context.deb_build_options
95 @property
96 def dpkg_architecture_variables(self) -> DpkgArchitectureBuildProcessValuesTable:
97 return self._cmd_context.dpkg_architecture_variables()