/usr/bin/dh_pysupport is in python-support 1.0.14ubuntu2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | #!/usr/bin/perl -w
=head1 NAME
dh_pysupport - use the python-support framework to handle Python modules
=cut
use strict;
use File::Find;
use Debian::Debhelper::Dh_Lib;
=head1 SYNOPSIS
B<dh_pysupport> [I<debhelper options>] [-V I<X.Y>] [-X I<item> [...]] [-n] [I<module dirs ...>]
=head1 DESCRIPTION
dh_pysupport is a debhelper program that will scan your package, detect
public modules in I</usr/lib/pythonX.Y/site-packages>, and move them to
the shared Python modules location. It will generate appropriate
postinst/prerm scripts to byte-compile modules installed there for all
available python versions.
It will also look for private Python modules and will byte-compile them
with the current Python version. You may have to list the directories
containing private Python modules.
If a file named I<debian/pyversions> exists, it is used to determine the
python versions with which the package can work.
Appropriate dependencies on python-support, python and pythonI<X.Y> are
put in ${python:Depends}. The ${python:Versions} and ${python:Provides}
optional substitution variables are made available as well.
=head1 OPTIONS
=over 4
=item I<module dirs>
If your package installs private python modules in non-standard directories, you
can make dh_pysupport check those directories by passing their names on the
command line. By default, it will check /usr/lib/$PACKAGE,
/usr/share/$PACKAGE, /usr/lib/games/$PACKAGE and /usr/share/games/$PACKAGE
=item B<-n>, B<--noscripts>
Do not modify postinst/postrm scripts.
=item B<-d>
This option is deprecated.
=item B<-V> I<X.Y>
Force private modules to be bytecompiled with the specific I<X.Y> python version, regardless of the default python version on the system.
=item B<-X> I<item>, B<--exclude=>I<item>
Exclude files that contain "item" anywhere in their filename from being
taken into account to generate the python dependency. It also excludes
them from byte-compilation. You may use this option multiple times to
build up a list of things to exclude.
=back
=head1 CONFORMS TO
Python policy as of 2006-08-10
=cut
init();
warning("This program is deprecated, you should use dh_python2 instead. Migration guide: http://deb.li/dhs2p");
sub next_minor_version {
my $version = shift;
# Handles 2.10 -> 2.11 gracefully
my @items = split(/\./, $version);
$items[1] += 1;
$version = join(".", @items);
return $version;
}
sub specified_deps_in_package {
my $package = shift;
my $curpackage = 0;
my @deps = ();
open (CONTROL, 'debian/control') || error("cannot read debian/control: $!\n");
while (<CONTROL>) {
chomp;
s/\s+$//;
if (/^Package:\s*(.*)$/ && $package eq $1) {
$curpackage = 1;
}
if ($curpackage == 2) {
if (/^\s+(.*)$/) {
push @deps, split ",",$1;
if ($1 !~ /,$/) {
return @deps;
}
} else {
return @deps;
}
}
if ($curpackage && /^Python-Depends:\s*(.*)$/) {
@deps = split ",",$1;
if ($1 =~ /,$/) {
$curpackage = 2;
} else {
return @deps;
}
}
}
return @deps;
}
sub trim {
my $tmp = shift;
$tmp =~ s/^\s+//;
$tmp =~ s/\s+$//;
return $tmp;
}
# The current default python version
my $default=`readlink /usr/bin/python`;
$default =~ s/^python//;
chomp $default;
# Versions supported by python-defaults
my @debian_pysupported = split(/ /, `/usr/bin/pyversions -sv`);
chomp @debian_pysupported;
my $privdir="/usr/share/python-support/private";
# All supported versions
my $allversions_string=`$privdir/parseversions --all`;
chomp $allversions_string;
my @allversions=split " ", $allversions_string;
if (! grep { $_ eq $default } @allversions) {
error("Cannot detect default Python version");
}
# Use a specific version for private modules (doesn't affect public modules)
my $useversion;
if($dh{V_FLAG_SET}) {
$useversion = $dh{V_FLAG};
if (! grep { $_ eq $useversion } @allversions) {
error("Unknown python version $useversion");
}
}
foreach my $package (@{$dh{DOPACKAGES}}) {
next if ($package =~ /^python3-/); # ignore Python 3 packages
my $tmp = tmpdir($package);
my $need_pydep=0; # This variable tells whether we need a Python dependency
# regardless of the rest
my $have_pydep=0; # This variable tells whether we have added some dependency
# on python one way or another.
my @specified_deps = specified_deps_in_package ($package);
my $do_scripts = "";
# 1) Handle public python modules
# Move them to the python-support directories
my $verfile = "debian/pyversions";
my $versions = "";
if (open (VERFILE, $verfile)) {
# read first non-empty line
local $/ = "";
$versions = <VERFILE>;
chomp $versions;
close (VERFILE);
$versions = trim $versions;
# TODO: debian/package.pyversions ?
} else {
my $doko_versions=`$privdir/parseversions --raw --pycentral debian/control`;
chomp $doko_versions;
if ($doko_versions !~ /not found/) {
$versions=$doko_versions;
}
}
if ($versions) {
doit (("$privdir/movemodules","-V", $versions, $tmp))
} else {
doit (("$privdir/movemodules",$tmp));
}
# Then look for what the script found
foreach my $list_file (glob("$tmp/usr/share/python-support/*.public")) {
if (-f $list_file) {
my $supported=`$privdir/parseversions --minmax $list_file`;
# Add the packages explicitly asked by the maintainer
foreach my $dep (@specified_deps) {
$dep = trim $dep;
addsubstvar($package, "python:Depends", $dep);
}
my @ar=split "\n",$supported;
my @provides=split " ",$ar[0];
foreach my $pyversion (@provides) {
# Skip the substvars part for versions that might not
# be provided by packages depended upon.
next if (! grep { $_ eq $pyversion } @debian_pysupported);
# Generate the useless versions field
addsubstvar($package, "python:Versions", $pyversion);
# ... and the provides field
if ($package =~ /^python-/) {
my $virtual = $package;
$virtual =~ s/^python-/python$pyversion-/;
addsubstvar($package, "python:Provides", $virtual);
}
# Use the provides fields in packages dependended upon
foreach my $dep (@specified_deps) {
$dep = trim $dep;
# I have no idea why this wouldn't be the case, but well
if ($dep =~ /^python-(\S+)/) {
addsubstvar($package, "python:Depends", "python$pyversion-$1");
}
}
}
my @minmax=split " ",$ar[1];
my $minversion=$minmax[0];
if ( grep { $_ eq $default } @provides ) {
# The default version is in the supported versions
if ($minversion ne "None") {
addsubstvar($package, "python:Depends", "python (>= $minversion)");
$have_pydep=1;
}
} elsif ($minversion ne "None") {
# The default version is less than all supported versions
addsubstvar($package, "python:Depends", "python (>= $minversion) | python$minversion");
$have_pydep=1;
} else {
error("The default python version is greater than all supported versions");
}
my $maxversion=$minmax[1];
if ($maxversion ne "None") {
$maxversion = next_minor_version($maxversion);
addsubstvar($package, "python:Depends", "python (<< $maxversion)");
$have_pydep=1;
}
$list_file =~ s,^.*/,,;
$do_scripts = "$do_scripts $list_file";
$need_pydep = 1;
}
}
# 2) Look for private python modules
my @dirs = ("/usr/lib/$package", "/usr/share/$package",
"/usr/lib/games/$package", "/usr/share/games/$package", @ARGV );
@dirs = grep -d, map "$tmp$_", @dirs;
my @filelist;
my $file;
my $has_module = 0;
my $has_extension = 0;
my $strong_pydep=0;
my %need_verdep = ();
foreach (@allversions) {
$need_verdep{$_} = 0;
}
if (@dirs) {
foreach my $curdir (@dirs) {
find sub {
return unless -f;
return if excludefile($File::Find::name);
if (/\.py$/) {
$has_module=1;
doit(("rm","-f",$_."c",$_."o"));
( $file=$File::Find::name ) =~ s%^$tmp%%;
if (! grep { $_ eq $file } @filelist) {
push @filelist, $file;
}
}
if (/\.so$/ &&
`nm -Du "$_" | grep "U Py_InitModule"` &&
! `objdump -p "$_" | grep "NEEDED *libpython"`) {
$has_extension=1;
}
}, $curdir ;
}
}
if ( ($has_module or $has_extension) ) {
if ( $useversion ) {
$need_verdep{$useversion}=1;
} else {
$need_pydep=1;
$strong_pydep=1 if $has_extension;
}
}
if (@filelist) {
# We have private python modules
# Use python-support to ensure that they are always
# byte-compiled for the current version
doit("mkdir", "-p", "-m", "755", "$tmp/usr/share/python-support");
open(FILELIST, "> $tmp/usr/share/python-support/$package.private") ||
error("Can't create $tmp/usr/share/python-support/$package.private: $!");
if ( $useversion ) {
print FILELIST "pyversion=$useversion\n\n";
}
print FILELIST map "$_\n", @filelist;
close(FILELIST);
$do_scripts = "$do_scripts $package.private";
}
# 3) Add python-support dependency depending on what we found
if (-d "$tmp/usr/share/python-support") {
addsubstvar($package, "python:Depends", "python-support (>= 0.90.0)");
}
# 4) Look for python scripts
find sub {
return unless -f and -x;
return if excludefile($File::Find::name);
local *F;
return unless open F, $_;
if (read F, local $_, 32 and m%^#!\s*/usr/bin/(env\s+)?(python(\d+\.\d+)?)\s%) {
if ( "python" eq $2 ) {
$need_pydep=1;
} elsif (defined $need_verdep{$3}) {
$need_verdep{$3}=1;
}
}
close F;
}, $tmp;
# 5) Generate remaining dependencies
foreach my $version (@allversions) {
if ($need_verdep{$version}) {
addsubstvar($package, "python:Depends", "python$version");
}
}
if (not $have_pydep) {
if ($strong_pydep) {
addsubstvar($package, "python:Depends", "python (>= $default)");
my $maxversion = next_minor_version($default);
addsubstvar($package, "python:Depends", "python (<< $maxversion)");
$have_pydep=1;
} elsif ($need_pydep and $versions) {
my $supported=`echo $versions | $privdir/parseversions --minmax`;
my @ar=split "\n",$supported;
my @minmax=split " ",$ar[1];
my $minversion=$minmax[0];
if ($minversion ne "None") {
addsubstvar($package, "python:Depends", "python (>= $minversion)");
$have_pydep=1;
}
my $maxversion=$minmax[1];
if ($maxversion ne "None") {
$maxversion = next_minor_version($maxversion);
addsubstvar($package, "python:Depends", "python (<< $maxversion)");
$have_pydep=1;
}
}
}
# If nothing has added a python dependency yet, add it
if ($need_pydep and not $have_pydep) {
addsubstvar($package, "python:Depends", "python");
}
# 6) Generate the scripts
if ($do_scripts && ! $dh{NOSCRIPTS}) {
autoscript($package, "postinst", "postinst-python-support", "s,#ARGS#,$do_scripts,");
autoscript($package, "prerm", "prerm-python-support", "s,#ARGS#,$do_scripts,");
}
}
=head1 SEE ALSO
L<debhelper(7)>
This program is a part of python-support but is made to work with debhelper.
=head1 AUTHORS
Josselin Mouette <joss@debian.org>,
Raphael Hertzog <hertzog@debian.org>
=cut
|