Advertisement
rockdrilla

dpkg-source-raw

Nov 20th, 2018
692
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 10.22 KB | None | 0 0
  1. #!/usr/bin/perl
  2. #
  3. # dpkg-source-raw:
  4. #   hackish script based on original dpkg-source
  5. #
  6. # Copyright © 1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
  7. # Copyright © 1997 Klee Dienes <klee@debian.org>
  8. # Copyright © 1999-2003 Wichert Akkerman <wakkerma@debian.org>
  9. # Copyright © 1999 Ben Collins <bcollins@debian.org>
  10. # Copyright © 2000-2003 Adam Heath <doogie@debian.org>
  11. # Copyright © 2005 Brendan O'Dea <bod@debian.org>
  12. # Copyright © 2006-2008 Frank Lichtenheld <djpig@debian.org>
  13. # Copyright © 2006-2009,2012 Guillem Jover <guillem@debian.org>
  14. # Copyright © 2008-2011 Raphaël Hertzog <hertzog@debian.org>
  15. #
  16. # This program is free software; you can redistribute it and/or modify
  17. # it under the terms of the GNU General Public License as published by
  18. # the Free Software Foundation; either version 2 of the License, or
  19. # (at your option) any later version.
  20. #
  21. # This program is distributed in the hope that it will be useful,
  22. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24. # GNU General Public License for more details.
  25. #
  26. # You should have received a copy of the GNU General Public License
  27. # along with this program.  If not, see <https://www.gnu.org/licenses/>.
  28.  
  29. use strict;
  30. use warnings;
  31.  
  32. use List::Util qw(any none);
  33. use Cwd;
  34. use File::Basename;
  35. use File::Spec;
  36.  
  37. use Dpkg ();
  38. use Dpkg::Gettext;
  39. use Dpkg::ErrorHandling;
  40. use Dpkg::Arch qw(:operators);
  41. use Dpkg::Deps;
  42. use Dpkg::Compression;
  43. use Dpkg::Conf;
  44. use Dpkg::Control::Info;
  45. use Dpkg::Control::Tests;
  46. use Dpkg::Control::Fields;
  47. use Dpkg::Substvars;
  48. use Dpkg::Version;
  49. use Dpkg::Vars;
  50. use Dpkg::Changelog::Parse;
  51. use Dpkg::Source::Package;
  52. use Dpkg::Vendor;
  53.  
  54. # textdomain('dpkg-dev');
  55.  
  56. my $build_format;
  57. my %options = ();
  58.  
  59. my $substvars = Dpkg::Substvars->new();
  60.  
  61. my @options;
  62.  
  63. # --format options are not allowed, they would take precedence
  64. # over real command line options, debian/source/format should be used
  65. # instead
  66. # --unapply-patches is only allowed in local-options as it's a matter
  67. # of personal taste and the default should be to keep patches applied
  68. my $forbidden_opts_re = {
  69.     'options' => qr/^--(?:format=|unapply-patches$|abort-on-upstream-changes$)/,
  70.     'local-options' => qr/^--format=/,
  71. };
  72.  
  73. foreach my $filename ('local-options', 'options') {
  74.     my $conf = Dpkg::Conf->new();
  75.     my $optfile = "debian/source/$filename";
  76.     next unless -f $optfile;
  77.     $conf->load($optfile);
  78.     $conf->filter(remove => sub { $_[0] =~ $forbidden_opts_re->{$filename} });
  79.     if (@$conf) {
  80.         unshift @options, @$conf;
  81.     }
  82. }
  83.  
  84. $options{origtardir} = $ARGV[0];
  85. # report_options(quiet_warnings => 1);
  86. # $options{quiet} = 1;
  87.  
  88. my %ch_options = (file => "debian/changelog");
  89. my $changelog = changelog_parse(%ch_options);
  90. my $control = Dpkg::Control::Info->new("debian/control");
  91.  
  92. # <https://reproducible-builds.org/specs/source-date-epoch/>
  93. $ENV{SOURCE_DATE_EPOCH} ||= $changelog->{timestamp} || time;
  94.  
  95. my $srcpkg = Dpkg::Source::Package->new(options => \%options);
  96. my $fields = $srcpkg->{fields};
  97.  
  98. my @sourcearch;
  99. my %archadded;
  100. my @binarypackages;
  101.  
  102. # Scan control info of source package
  103. my $src_fields = $control->get_source();
  104. error(g_("debian/control doesn't contain any information about the source package")) unless defined $src_fields;
  105. my $src_sect = $src_fields->{'Section'} || 'unknown';
  106. my $src_prio = $src_fields->{'Priority'} || 'unknown';
  107.  
  108. foreach (keys %{$src_fields}) {
  109.     my $v = $src_fields->{$_};
  110.     if (m/^Source$/i) {
  111.         set_source_package($v);
  112.         $fields->{$_} = $v;
  113.     } elsif (m/^Uploaders$/i) {
  114.         ($fields->{$_} = $v) =~ s/\s*[\r\n]\s*/ /g; # Merge in a single-line
  115.     } elsif (m/^Build-(?:Depends|Conflicts)(?:-Arch|-Indep)?$/i) {
  116.         my $dep;
  117.         my $type = field_get_dep_type($_);
  118.         $dep = deps_parse($v, build_dep => 1, union => $type eq 'union');
  119.         error(g_('error occurred while parsing %s'), $_) unless defined $dep;
  120.         my $facts = Dpkg::Deps::KnownFacts->new();
  121.         $dep->simplify_deps($facts);
  122.         $dep->sort() if $type eq 'union';
  123.         $fields->{$_} = $dep->output();
  124.     } else {
  125.         field_transfer_single($src_fields, $fields);
  126.     }
  127. }
  128.  
  129. # Scan control info of binary packages
  130. my @pkglist;
  131. foreach my $pkg ($control->get_packages()) {
  132.     my $p = $pkg->{'Package'};
  133.     my $sect = $pkg->{'Section'} || $src_sect;
  134.     my $prio = $pkg->{'Priority'} || $src_prio;
  135.     my $type = $pkg->{'Package-Type'} ||
  136.             $pkg->get_custom_field('Package-Type') || 'deb';
  137.     my $arch = $pkg->{'Architecture'};
  138.     my $profile = $pkg->{'Build-Profiles'};
  139.  
  140.     my $pkg_summary = sprintf('%s %s %s %s', $p, $type, $sect, $prio);
  141.  
  142.     $pkg_summary .= ' arch=' . join ',', split ' ', $arch;
  143.  
  144.     if (defined $profile) {
  145.         # If the string does not contain brackets then it is using the
  146.         # old syntax. Emit a fatal error.
  147.         if ($profile !~ m/^\s*<.*>\s*$/) {
  148.             error(g_('binary package stanza %s is using an obsolete ' .
  149.                      'Build-Profiles field syntax'), $p);
  150.         }
  151.  
  152.         # Instead of splitting twice and then joining twice, we just do
  153.         # simple string replacements:
  154.  
  155.         # Remove the enclosing <>
  156.         $profile =~ s/^\s*<(.*)>\s*$/$1/;
  157.         # Join lists with a plus (OR)
  158.         $profile =~ s/>\s+</+/g;
  159.         # Join their elements with a comma (AND)
  160.         $profile =~ s/\s+/,/g;
  161.         $pkg_summary .= " profile=$profile";
  162.     }
  163.  
  164.     if (defined $pkg->{'Essential'} and $pkg->{'Essential'} eq 'yes') {
  165.         $pkg_summary .= ' essential=yes';
  166.     }
  167.  
  168.     push @pkglist, $pkg_summary;
  169.     push @binarypackages, $p;
  170.     foreach (keys %{$pkg}) {
  171.         my $v = $pkg->{$_};
  172.         if (m/^Architecture$/) {
  173.             # Gather all binary architectures in one set. 'any' and 'all'
  174.             # are special-cased as they need to be the only ones in the
  175.             # current stanza if present.
  176.             if (debarch_eq($v, 'any') || debarch_eq($v, 'all')) {
  177.                 push(@sourcearch, $v) unless $archadded{$v}++;
  178.             } else {
  179.                 for my $a (split(/\s+/, $v)) {
  180.                     error(g_("'%s' is not a legal architecture string"), $a)
  181.                         if debarch_is_illegal($a);
  182.                     error(g_('architecture %s only allowed on its ' .
  183.                              "own (list for package %s is '%s')"),
  184.                           $a, $p, $a)
  185.                         if $a eq 'any' or $a eq 'all';
  186.                     push(@sourcearch, $a) unless $archadded{$a}++;
  187.                 }
  188.             }
  189.         } elsif (m/^(?:Homepage|Description)$/) {
  190.             # Do not overwrite the same field from the source entry
  191.         } else {
  192.             field_transfer_single($pkg, $fields);
  193.         }
  194.     }
  195. }
  196.  
  197. unless (scalar(@pkglist)) {
  198.     error(g_("debian/control doesn't list any binary package"));
  199. }
  200.  
  201. if (any { $_ eq 'any' } @sourcearch) {
  202.     # If we encounter one 'any' then the other arches become insignificant
  203.     # except for 'all' that must also be kept
  204.     if (any { $_ eq 'all' } @sourcearch) {
  205.         @sourcearch = qw(any all);
  206.     } else {
  207.         @sourcearch = qw(any);
  208.     }
  209. } else {
  210.     # Minimize arch list, by removing arches already covered by wildcards
  211.     my @arch_wildcards = grep { debarch_is_wildcard($_) } @sourcearch;
  212.     my @mini_sourcearch = @arch_wildcards;
  213.     foreach my $arch (@sourcearch) {
  214.         if (none { debarch_is($arch, $_) } @arch_wildcards) {
  215.             push @mini_sourcearch, $arch;
  216.         }
  217.     }
  218.     @sourcearch = @mini_sourcearch;
  219. }
  220. $fields->{'Architecture'} = join(' ', @sourcearch);
  221. $fields->{'Package-List'} = "\n" . join("\n", sort @pkglist);
  222.  
  223. # Scan fields of dpkg-parsechangelog
  224. foreach (keys %{$changelog}) {
  225.     my $v = $changelog->{$_};
  226.  
  227.     if (m/^Source$/) {
  228.         set_source_package($v);
  229.         $fields->{$_} = $v;
  230.     } elsif (m/^Version$/) {
  231.         my ($ok, $error) = version_check($v);
  232.         error($error) unless $ok;
  233.         $fields->{$_} = $v;
  234.     } elsif (m/^Binary-Only$/) {
  235.         error(g_('building source for a binary-only release'))
  236.             if $v eq 'yes';
  237.     } elsif (m/^Maintainer$/i) {
  238.         # Do not replace the field coming from the source entry
  239.     } else {
  240.         field_transfer_single($changelog, $fields);
  241.     }
  242. }
  243.  
  244. $fields->{'Binary'} = join(', ', @binarypackages);
  245. # Avoid overly long line by splitting over multiple lines
  246. if (length($fields->{'Binary'}) > 980) {
  247.     $fields->{'Binary'} =~ s/(.{0,980}), ?/$1,\n/g;
  248. }
  249.  
  250. # Select the format to use
  251. if (not defined $build_format) {
  252.     if (-e "debian/source/format") {
  253.         open(my $format_fh, '<', "debian/source/format")
  254.             or syserr(g_('cannot read debian/source/format'));
  255.         $build_format = <$format_fh>;
  256.         chomp($build_format) if defined $build_format;
  257.         error(g_('debian/source/format is empty'))
  258.             unless defined $build_format and length $build_format;
  259.         close($format_fh);
  260.     } else {
  261.         $build_format = '1.0';
  262.     }
  263. }
  264.  
  265. $fields->{'Format'} = $build_format;
  266. $srcpkg->upgrade_object_type(); # Fails if format is unsupported
  267. # Parse command line options
  268. $srcpkg->init_options();
  269.  
  270. my $basenamerev = $srcpkg->get_basename(1);
  271.  
  272.     ## portions from /usr/share/perl5/Dpkg/Source/Package/V2.pm
  273.     ## Dpkg::Source::Package::V2::_generate_patch
  274.  
  275.     my ($tarfile);
  276.     my $comp_ext_regex = compression_get_file_extension_regex();
  277.     foreach my $file (sort $srcpkg->find_original_tarballs()) {
  278.         if ($file =~ /\.orig\.tar\.$comp_ext_regex$/) {
  279.             if (defined($tarfile)) {
  280.                 error(g_('several orig.tar files found (%s and %s) but only ' .
  281.                          'one is allowed'), $tarfile, $file);
  282.             }
  283.             $srcpkg->add_file($file);
  284.         } elsif ($file =~ /\.orig-([[:alnum:]-]+)\.tar\.$comp_ext_regex$/) {
  285.             $srcpkg->add_file($file);
  286.         }
  287.     }
  288.  
  289.     ## portions from /usr/share/perl5/Dpkg/Source/Package/V2.pm
  290.     ## Dpkg::Source::Package::V2::do_build
  291.  
  292.     $srcpkg->add_file("$ARGV[0]/$basenamerev.debian.tar.xz");
  293.  
  294. # Write the .dsc
  295. my $dscname = "$ARGV[0]/$basenamerev.dsc";
  296. $srcpkg->write_dsc(filename => $dscname, substvars => $substvars);
  297. exit(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement