home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / bin / dh_pysupport < prev    next >
Encoding:
Text File  |  2006-08-10  |  11.4 KB  |  328 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> [S<I<debhelper options>>] [-V I<X.Y>] [-X I<item> [...]] [-n] [S<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/share/python-support> and generate appropriate
  21. postinst/prerm scripts to byte-compile modules installed there for all
  22. available python versions.
  23.  
  24. It will also look for private Python modules and will byte-compile them
  25. with the current Python version. You may have to list the directories
  26. containing private Python modules.
  27.  
  28. If a file named I<debian/pyversions> exists, it is installed in 
  29. I</usr/share/python-support/$PACKAGE/.version>.
  30.  
  31. =head1 OPTIONS
  32.  
  33. =over 4
  34.  
  35. =item I<module dirs>
  36.  
  37. If your package installs private python modules in non-standard directories, you
  38. can make dh_pysupport check those directories by passing their names on the
  39. command line. By default, it will check /usr/lib/$PACKAGE,
  40. /usr/share/$PACKAGE, /usr/lib/games/$PACKAGE and /usr/share/games/$PACKAGE
  41.  
  42. =item B<-n>, B<--noscripts>
  43.  
  44. Do not modify postinst/postrm scripts.
  45.  
  46. =item B<-d>
  47.  
  48. Force generation of dependency information.
  49. In normal operation, dh_pysupport only generates complete dependency information when no I<debian/pycompat> file is found. With this option, it will be generated regardless.
  50.  
  51. =item B<-V> I<X.Y>
  52.  
  53. Force private modules to be bytecompiled with the specific I<X.Y> python version, regardless of the default python version on the system.
  54.  
  55. =item B<-X> I<item>, B<--exclude=>I<item>
  56.  
  57. Exclude files that contain "item" anywhere in their filename from being
  58. taken into account to generate the python dependency. You may use this
  59. option multiple times to build up a list of things to exclude.
  60.  
  61. =back
  62.  
  63. =head1 CONFORMS TO
  64.  
  65. Python policy as of 2006-08-10
  66.  
  67. =cut
  68.  
  69. init();
  70.  
  71. sub next_minor_version {
  72.     my $version = shift;
  73.     # Handles 2.10 -> 2.11 gracefully
  74.     my @items = split(/\./, $version);
  75.     $items[1] += 1;
  76.     $version = join(".", @items);
  77.     return $version;
  78. }
  79.  
  80. # The current default python version
  81. my $default=`pyversions -dv`;
  82. chomp $default;
  83.  
  84. # All supported versions
  85. my $allversions_string=`pyversions -sv`;
  86. chomp $allversions_string;
  87. my @allversions=split " ", $allversions_string;
  88.  
  89. # Use a specific version for private modules (doesn't affect public modules)
  90. my $useversion;
  91. if($dh{V_FLAG_SET}) {
  92.     $useversion = $dh{V_FLAG};
  93.     if (! grep { $_ eq $useversion } @allversions) {
  94.         error("Unknown python version $useversion");
  95.     }
  96. }
  97.  
  98. # Generate dependencies if dh_python's debian/pycompat file isn't here
  99. my $do_deps=1;
  100. if (-f "debian/pycompat" && ! $dh{D_FLAG}) {
  101.     $do_deps=0;
  102. }
  103.  
  104.  
  105. foreach my $package (@{$dh{DOPACKAGES}}) {
  106.     my $tmp = tmpdir($package);
  107.     my $have_pydep=0; # This variable tells whether we have added some dependency
  108.               # on python one way or another.
  109.     
  110.     # 1) Handle public python modules
  111.     # Move them to the python-support directories
  112.     doit (("pysupport-movemodules",$tmp));
  113.     # Then look for what the script found
  114.     foreach my $ps_dir (glob("$tmp/usr/share/python-support/*")) {
  115.         if (-d $ps_dir && ! excludefile($ps_dir)) {
  116.             my $verfile = "debian/pyversions";
  117.                 if (-f $verfile) {
  118.                     # TODO: debian/package.pyversions ?
  119.                     doit("install","-p","-m644",$verfile,"$ps_dir/.version");
  120.                 }
  121.                 my $ext_dir=$ps_dir;
  122.                 $ext_dir =~ s,/usr/share/,/usr/lib/,;
  123.              my $supported;
  124.                 if (-d $ext_dir) {
  125.                     if (-f "$ps_dir/.version") {
  126.                         # Just ignore the .version file when there are extensions.
  127.                         # The extensions dictate which versions to handle.
  128.                         doit(("rm","-f","$ps_dir/.version"));
  129.                     }
  130.                     my @provides;
  131.                     foreach my $pydir (glob("$ext_dir/python*")) {
  132.                         if (-d $pydir && $pydir =~ m/python(\d+).(\d+)/) {
  133.                             push @provides, "$1.$2";
  134.                         }
  135.                     }
  136.                     my $a=join ",",@provides;
  137.                     $supported=`echo $a | pysupport-parseversions --minmax`;
  138.                 } elsif (! -f "$ps_dir/.version") {
  139.                     my $doko_versions=`pysupport-parseversions --raw --pycentral debian/control`;
  140.                     chomp $doko_versions;
  141.                     if ($doko_versions !~ /not found/) {
  142.                         print "Compatibility mode: using detected XS-Python-Version.\n";
  143.                         complex_doit("echo $doko_versions > $ps_dir/.version");
  144.                     }
  145.                 }
  146.                 if (-f "$ps_dir/.version") {
  147.                     $supported=`pysupport-parseversions --minmax $ps_dir/.version`;
  148.                 }
  149.                 if ($do_deps && defined $supported) {
  150.                     # Generate the provides field
  151.                     my @ar=split "\n",$supported;
  152.                     my @provides=split " ",$ar[0];
  153.                     if ($package =~ /^python-/) {
  154.                         foreach my $pyversion (@provides) {
  155.                             my $virtual = $package;
  156.                         $virtual =~ s/^python-/python$pyversion-/;
  157.                         addsubstvar($package, "python:Provides", $virtual);
  158.                         }
  159.                     }
  160.                     my @minmax=split " ",$ar[1];
  161.                     my $minversion=$minmax[0];
  162.                     if ( grep { $_ eq $default } @provides ) {
  163.                         # The default version is in the supported versions
  164.                         if ($minversion ne "None") {
  165.                             addsubstvar($package, "python:Depends", "python (>= $minversion)");
  166.                         }
  167.                     } elsif ($minversion ne "None") {
  168.                         # The default version is less than all supported versions
  169.                         addsubstvar($package, "python:Depends", "python (>= $minversion) | python$minversion");
  170.                     } else {
  171.                         error("The default python version is greater than all supported versions");
  172.                     }
  173.                     my $maxversion=$minmax[1];
  174.                     if ($maxversion ne "None") {
  175.                     $maxversion = next_minor_version($maxversion);
  176.                     addsubstvar($package, "python:Depends", "python (<< $maxversion)");
  177.                 }
  178.                 $have_pydep=1;
  179.                 }
  180.             $ps_dir =~ s/^$tmp//;
  181.             if (! $dh{NOSCRIPTS}) {
  182.                 autoscript($package, "postinst", "postinst-python-support", "s,#OPTIONS#,-i,;s,#DIRS#,$ps_dir,");
  183.                 autoscript($package, "prerm", "prerm-python-support", "s,#OPTIONS#,-i,;s,#DIRS#,$ps_dir,");
  184.             }
  185.         }
  186.     }
  187.  
  188.         # 2) Look for private python modules
  189.     my @dirs = ("/usr/lib/$package", "/usr/share/$package",
  190.             "/usr/lib/games/$package", "/usr/share/games/$package", @ARGV );
  191.     @dirs = grep -d, map "$tmp$_", @dirs;
  192.         my @dirlist;
  193.         my $have_pyversion=0;
  194.         my $need_pydep=0;
  195.         my $strong_pydep=0;
  196.     my %need_verdep = ();
  197.     foreach (@allversions) {
  198.         $need_verdep{$_} = 0;
  199.     }
  200.         if (@dirs) {
  201.                 foreach my $curdir (@dirs) {
  202.                         my $has_module = 0;
  203.                         my $has_extension = 0;
  204.                         find sub {
  205.                                 return unless -f;
  206.                                 return if excludefile($File::Find::name);
  207.                                 if (/.py$/) {
  208.                                     $has_module=1;
  209.                                     doit(("rm","-f",$_."c",$_."o"));
  210.                                 }
  211.                                 if (/.so$/ && `nm -Du "$_" | grep "U Py_InitModule"`) {
  212.                                     $has_extension=1;
  213.                                 }
  214.                         }, $curdir ;
  215.                         if ( ($has_module or $has_extension) and not grep { $_ eq "$curdir" } @dirlist ) {
  216.                                 if ( $useversion ) {
  217.                                 # Create .pyversion to tell update-python-modules for which
  218.                                 # version to compile
  219.                                     open(VERFILE, "> $curdir/.pyversion") ||
  220.                                         error("Can't create $curdir/.pyversion: $!");
  221.                                     print VERFILE "$useversion\n";
  222.                                     close(VERFILE);
  223.                                     $have_pyversion=1;
  224.                                     $need_verdep{$useversion}=1;
  225.                                 } else {
  226.                                     $need_pydep=1;
  227.                                     $strong_pydep=1 if $has_extension;
  228.                                 }
  229.                 $curdir =~ s%^$tmp%%;
  230.                                 push @dirlist, "$curdir" if $has_module;
  231.                         }
  232.                 }
  233.         }
  234.     if (@dirlist) {
  235.         # We have private python modules
  236.         # Use python-support to ensure that they are always
  237.         # byte-compiled for the current version
  238.         mkdir("$tmp/usr/share/python-support");
  239.         open(DIRLIST, "> $tmp/usr/share/python-support/$package.dirs") ||
  240.             error("Can't create $tmp/usr/share/python-support/$package.dirs: $!");
  241.         print DIRLIST map "$_\n", @dirlist;
  242.         close(DIRLIST);
  243.         autoscript($package, "postinst", "postinst-python-support", "s,#OPTIONS#,-b,;s,#DIRS#,$package.dirs,");
  244.         autoscript($package, "prerm", "prerm-python-support", "s,#OPTIONS#,-b,;s,#DIRS#,$package.dirs,");
  245.     }
  246.  
  247.     # 3) Add python-support dependency depending on what we found
  248.         if (-d "$tmp/usr/share/python-support") {
  249.             if ( $have_pyversion ) {
  250.                 # .pyversion introduced in 0.4
  251.                 addsubstvar($package, "python:Depends", "python-support (>= 0.4) ");
  252.         } elsif (-d "$tmp/usr/lib/python-support") {
  253.             # /usr/lib split introduced in 0.3
  254.                     addsubstvar($package, "python:Depends", "python-support (>= 0.3.4) ");
  255.         } else {
  256.             # stateless stuff introduced in 0.2
  257.                     addsubstvar($package, "python:Depends", "python-support (>= 0.2) ");
  258.         }
  259.         }
  260.         
  261.            # 4) Look for python scripts
  262.            if ($do_deps) {
  263.                find sub {
  264.                    return unless -f and -x;
  265.                    return if excludefile($File::Find::name);
  266.                    local *F;
  267.                    return unless open F, $_;
  268.             if (read F, local $_, 32 and m%^#!\s*/usr/bin/(env\s+)?(python(\d+\.\d+)?)\s%) {
  269.                        if ( "python" eq $2 ) {
  270.                     $need_pydep=1;
  271.                        } elsif (defined $need_verdep{$3}) {
  272.                            $need_verdep{$3}=1;
  273.                        }
  274.                    }
  275.                    close F;
  276.                }, $tmp;
  277.     }
  278.            
  279.            # 5) Generate remaining dependencies
  280.            if ($do_deps) {
  281.                foreach (@allversions) {
  282.                    if ($need_verdep{$_}) {
  283.                        addsubstvar($package, "python:Depends", "python$_");
  284.                    }
  285.                }
  286.                if (not $have_pydep) {
  287.                    if ($strong_pydep) {
  288.                        addsubstvar($package, "python:Depends", "python (>= $default)");
  289.                        my $maxversion = next_minor_version($default);
  290.                        addsubstvar($package, "python:Depends", "python (<< $maxversion)");
  291.                        $have_pydep=1;
  292.                    } elsif ($need_pydep and -f "debian/pyversions") {
  293.                        my $supported=`pysupport-parseversions --minmax debian/pyversions`;
  294.                        my @ar=split "\n",$supported;
  295.                        my @minmax=split " ",$ar[1];
  296.                     my $minversion=$minmax[0];
  297.                     if ($minversion ne "None") {
  298.                         addsubstvar($package, "python:Depends", "python (>= $minversion)");
  299.                         $have_pydep=1;
  300.                 }
  301.                 my $maxversion=$minmax[1];
  302.                     if ($maxversion ne "None") {
  303.                     $maxversion = next_minor_version($maxversion);
  304.                     addsubstvar($package, "python:Depends", "python (<< $maxversion)");
  305.                     $have_pydep=1;
  306.                 }
  307.                    }
  308.                }
  309.                # If nothing has added a python dependency yet, add it
  310.         if ($need_pydep and not $have_pydep and not -d "$tmp/usr/share/python-support") {
  311.                    addsubstvar($package, "python:Depends", "python");
  312.         }
  313.     }
  314. }
  315.  
  316. =head1 SEE ALSO
  317.  
  318. L<debhelper(7)>
  319.  
  320. This program is a part of python-support but is made to work with debhelper.
  321.  
  322. =head1 AUTHORS
  323.  
  324. Josselin Mouette <joss@debian.org>,
  325. Raphael Hertzog <hertzog@debian.org>
  326.  
  327. =cut
  328.