home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / dh_pysupport < prev    next >
Encoding:
Text File  |  2010-09-14  |  11.8 KB  |  383 lines

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