Coverage for src/debputy/dh_migration/dh_related_migrations.py: 13%
81 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-09-07 09:27 +0000
1import os.path
2import subprocess
3from typing import Optional
5from debian.debian_support import Version
7from debputy.analysis.debian_dir import resolve_debhelper_config_files
8from debputy.dh.debhelper_emulation import dhe_pkgfile
9from debputy.dh.dh_assistant import read_dh_addon_sequences, extract_dh_compat_level
10from debputy.dh_migration.models import AcceptableMigrationIssues, FeatureMigration
11from debputy.highlevel_manifest import HighLevelManifest
12from debputy.plugin.api import VirtualPath
13from debputy.plugin.api.impl import plugin_metadata_for_debputys_own_plugin
14from debputy.plugin.api.spec import DebputyIntegrationMode
17def _installed_debhelper_version_is_at_least(desired_version: str) -> bool:
18 try:
19 output = subprocess.check_output(
20 [
21 "dpkg-query",
22 "-W",
23 "--showformat=${Version} ${db:Status-Status}\n",
24 "debhelper",
25 ]
26 ).decode("utf-8")
27 except (FileNotFoundError, subprocess.CalledProcessError):
28 return False
29 else:
30 parts = output.split()
31 if len(parts) != 2:
32 return False
33 if parts[1] != "installed":
34 return False
35 return Version(parts[0]) >= Version(desired_version)
38def dh_mbm_migrate_package_files(
39 debian_dir: VirtualPath,
40 manifest: HighLevelManifest,
41 _acceptable_migration_issues: AcceptableMigrationIssues,
42 feature_migration: FeatureMigration,
43 _migration_target: Optional[DebputyIntegrationMode],
44) -> None:
45 feature_migration.tagline = "Add explicit package name to debhelper config files"
46 debputy_plugin_metadata = plugin_metadata_for_debputys_own_plugin()
47 dh_compat_level, _ = extract_dh_compat_level()
48 r = read_dh_addon_sequences(debian_dir)
49 if r is not None:
50 bd_sequences, dr_sequences, uses_dh_sequencer = r
51 dh_sequences = bd_sequences | dr_sequences
52 uses_dh_sequencer = True
53 else:
54 dh_sequences = set()
55 uses_dh_sequencer = False
57 (
58 all_dh_ppfs,
59 missing_introspection,
60 _,
61 _,
62 ) = resolve_debhelper_config_files(
63 debian_dir,
64 {p.name: p for p in manifest.all_packages},
65 debputy_plugin_metadata,
66 manifest.plugin_provided_feature_set,
67 dh_sequences,
68 dh_compat_level,
69 uses_dh_sequencer,
70 )
71 for ppf in all_dh_ppfs:
72 if (
73 ppf.uses_explicit_package_name
74 or ppf.definition.packageless_is_fallback_for_all_packages
75 ):
76 continue
77 basename = ppf.path.name
78 new_basename = f"{ppf.package_name}.{basename}"
79 ppf_parent = ppf.path.parent_dir
80 assert ppf_parent is not None
81 parent_path = ppf_parent.path
82 new_path = os.path.join(parent_path, new_basename)
83 feature_migration.rename_on_success(ppf.path.path, new_path)
85 if not missing_introspection and not _installed_debhelper_version_is_at_least(
86 "13.26~"
87 ):
88 feature_migration.warn(
89 "Please upgrade to `debhelper/13.26` to ensure reliability. Some files might be silently missed."
90 )
92 for command in missing_introspection:
93 feature_migration.warn(
94 f"The command `{command}` is used but `dh_assistant` was not aware of whether it had configuration files."
95 )
97 if missing_introspection:
98 feature_migration.warn(
99 "Please file a bug against the provider of the commands asking them to supply the relevant hints (see doc/PROGRAMMING.md in debhelper/13.26+) with the debhelper maintainers in CC."
100 )
102 feature_migration.warn(
103 "Any architecture restricted file (such `debian/install.amd64`) and templating based files (such as debian/install.tmpl) may be missed. Please validate these manually."
104 )
107def dh_mbm_migrate_manual_warnings(
108 debian_dir: VirtualPath,
109 manifest: HighLevelManifest,
110 _acceptable_migration_issues: AcceptableMigrationIssues,
111 feature_migration: FeatureMigration,
112 _migration_target: Optional[DebputyIntegrationMode],
113) -> None:
114 feature_migration.tagline = "Manual parts"
115 r = read_dh_addon_sequences(debian_dir)
116 if r is not None:
117 bd_sequences, dr_sequences, uses_dh_sequencer = r
118 dh_sequences = bd_sequences | dr_sequences
119 uses_dh_sequencer = True
120 else:
121 dh_sequences = set()
122 uses_dh_sequencer = False
123 drules = debian_dir.get("rules")
124 if drules and drules.is_file:
125 with drules.open() as fd:
126 migrated_auto_install = 0
127 for line in fd:
128 line = line.lstrip()
129 if not line or line.startswith("#"):
130 continue
131 if line.startswith("\t") and "dh_auto_install" in line:
132 migrated_auto_install += 1 if "--destdir" in line else 0
133 used_dh_install_files = 0
134 for dctrl_bin in manifest.all_packages:
135 dh_config_file = dhe_pkgfile(debian_dir, dctrl_bin, "install")
136 if dh_config_file is not None:
137 used_dh_install_files += 1
138 main_pkg = [p for p in manifest.all_packages if p.is_main_package][0]
139 if not migrated_auto_install and not used_dh_install_files:
140 feature_migration.warn(
141 f"Ensure `dh_auto_install --destdir debian/{main_pkg.name}` or `dh_install` is used. Remember Replaces/Breaks if files are moved"
142 )
143 if uses_dh_sequencer and "single-binary" in dh_sequences:
144 feature_migration.warn("Remove `single-binary` add-on")