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