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