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