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

1from typing import Mapping, Optional, TYPE_CHECKING 

2 

3from debputy.architecture_support import DpkgArchitectureBuildProcessValuesTable 

4from debputy.manifest_conditions import _run_build_time_tests 

5 

6if TYPE_CHECKING: 

7 from debputy.commands.debputy_cmd.context import CommandContext 

8 

9 

10class BuildContext: 

11 @staticmethod 

12 def from_command_context( 

13 cmd_context: "CommandContext", 

14 ) -> "BuildContext": 

15 return BuildContextImpl(cmd_context) 

16 

17 @property 

18 def deb_build_options(self) -> Mapping[str, Optional[str]]: 

19 raise NotImplementedError 

20 

21 def parallelization_limit(self, *, support_zero_as_unlimited: bool = False) -> int: 

22 """Parallelization limit of the build 

23 

24 This is accessor that reads the `parallel` option from `DEB_BUILD_OPTIONS` with relevant 

25 fallback behavior. 

26 

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 

49 

50 @property 

51 def is_terse_build(self) -> bool: 

52 """Whether the build is terse 

53 

54 This is a shorthand for testing for `terse` in DEB_BUILD_OPTIONS 

55 """ 

56 return "terse" in self.deb_build_options 

57 

58 @property 

59 def is_cross_compiling(self) -> bool: 

60 """Whether the build is considered a cross build 

61 

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 

68 

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}" 

74 

75 @property 

76 def dpkg_architecture_variables(self) -> DpkgArchitectureBuildProcessValuesTable: 

77 raise NotImplementedError 

78 

79 @property 

80 def should_run_tests(self) -> bool: 

81 return _run_build_time_tests(self.deb_build_options) 

82 

83 

84class BuildContextImpl(BuildContext): 

85 def __init__( 

86 self, 

87 cmd_context: "CommandContext", 

88 ) -> None: 

89 self._cmd_context = cmd_context 

90 

91 @property 

92 def deb_build_options(self) -> Mapping[str, Optional[str]]: 

93 return self._cmd_context.deb_build_options 

94 

95 @property 

96 def dpkg_architecture_variables(self) -> DpkgArchitectureBuildProcessValuesTable: 

97 return self._cmd_context.dpkg_architecture_variables()