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