Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

- start support for arch linux, code mostly written by Nikolay Rysev …

…<mad.f3ka@gmail.com>
  • Loading branch information...
commit af05d931c1537bdfeec1b5d518077152f177d152 1 parent bf3a5a3
Michael Schroeder authored
10  Build.pm
@@ -10,20 +10,25 @@ our $expand_dbg;
10 10
 our $do_rpm;
11 11
 our $do_deb;
12 12
 our $do_kiwi;
  13
+our $do_arch;
13 14
 
14 15
 sub import {
15 16
   for (@_) {
16 17
     $do_rpm = 1 if $_ eq ':rpm';
17 18
     $do_deb = 1 if $_ eq ':deb';
18 19
     $do_kiwi = 1 if $_ eq ':kiwi';
  20
+    $do_arch = 1 if $_ eq ':arch';
19 21
   }
20  
-  $do_rpm = $do_deb = $do_kiwi = 1 if !$do_rpm && !$do_deb && !$do_kiwi;
  22
+  $do_rpm = $do_deb = $do_kiwi = $do_arch = 1 if !$do_rpm && !$do_deb && !$do_kiwi && !$do_arch;
21 23
   if ($do_deb) {
22 24
     require Build::Deb;
23 25
   }
24 26
   if ($do_kiwi) {
25 27
     require Build::Kiwi;
26 28
   }
  29
+  if ($do_arch) {
  30
+    require Build::Arch;
  31
+  }
27 32
 }
28 33
 
29 34
 my $std_macros = q{
@@ -854,6 +859,7 @@ sub parse {
854 859
   return Build::Deb::parse($cf, $fn, @args) if $do_deb && $fn =~ /\.dsc$/;
855 860
   return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /config\.xml$/;
856 861
   return Build::Kiwi::parse($cf, $fn, @args) if $do_kiwi && $fn =~ /\.kiwi$/;
  862
+  return Build::Arch::parse($cf, $fn, @args) if $do_arch && $fn =~ /PKGBUILD$/;
857 863
   return undef;
858 864
 }
859 865
 
@@ -867,6 +873,7 @@ sub query {
867 873
   return Build::Rpm::query($handle, %opts) if $do_rpm && $binname =~ /\.rpm$/;
868 874
   return Build::Deb::query($handle, %opts) if $do_deb && $binname =~ /\.deb$/;
869 875
   return Build::Kiwi::queryiso($handle, %opts) if $do_kiwi && $binname =~ /\.iso$/;
  876
+  return Build::Arch::query($handle, %opts) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
870 877
   return undef;
871 878
 }
872 879
 
@@ -877,6 +884,7 @@ sub queryhdrmd5 {
877 884
   return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.iso$/;
878 885
   return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw$/;
879 886
   return Build::Kiwi::queryhdrmd5(@_) if $do_kiwi && $binname =~ /\.raw.install$/;
  887
+  return Build::Arch::queryhdrmd5(@_) if $do_arch && $binname =~ /\.pkg\.tar(?:\.gz|\.xz)?$/;
880 888
   return undef;
881 889
 }
882 890
 
162  Build/Arch.pm
... ...
@@ -0,0 +1,162 @@
  1
+package Build::Arch;
  2
+
  3
+use strict;
  4
+use Digest::MD5;
  5
+use Data::Dumper;
  6
+use Archive::Tar;
  7
+
  8
+# Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com>
  9
+
  10
+# parse a PKGBUILD file
  11
+
  12
+sub quote {
  13
+  my ($str) = @_;
  14
+  $str =~ s/([ \t\"\'])/sprintf("%%%02X", ord($1))/ge;
  15
+  return $str;
  16
+}
  17
+
  18
+sub unquotesplit {
  19
+  my ($str) = @_;
  20
+  $str =~ s/%/%25/g;
  21
+  $str =~ s/^[ \t]+//;
  22
+  while ($str =~ /([\"\'])/) {
  23
+    my $q = $1;
  24
+    $str =~ s/$q(.*?)$q/quote($1)/e;
  25
+  }
  26
+  my @args = split(/[ \t]+/, $str);
  27
+  for (@args) {
  28
+    s/%([a-fA-F0-9]{2})/chr(hex($1))/ge
  29
+  }
  30
+  return @args;
  31
+}
  32
+
  33
+sub parse {
  34
+  my ($config, $pkgbuild) = @_;
  35
+  my $ret;
  36
+  local *PKG;
  37
+  if (!open(PKG, '<', $pkgbuild)) {
  38
+    $ret->{'error'} = "$pkgbuild: $!";
  39
+    return $ret;
  40
+  }
  41
+  my %vars;
  42
+  while (<PKG>) {
  43
+    chomp;
  44
+    next if /^\s*$/;
  45
+    next if /^\s*#/;
  46
+    last unless /^([a-zA-Z0-9_]*)=(\(?)(.*?)$/;
  47
+    my $var = $1;
  48
+    my $val = $3;
  49
+    if ($2) {
  50
+      while ($val !~ s/\)\s*$//s) {
  51
+	my $nextline = <PKG>;
  52
+	last unless defined $nextline;
  53
+	chomp $nextline;
  54
+	$val .= ' ' . $nextline;
  55
+      }
  56
+    }
  57
+    $vars{$var} = [ unquotesplit($val) ];
  58
+  }
  59
+  close PKG;
  60
+  $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
  61
+  $ret->{'version'} = $vars{'pkgver'}->[0] if $vars{'pkgver'};
  62
+  $ret->{'deps'} = $vars{'makedepends'} || [];
  63
+  return $ret;
  64
+}
  65
+
  66
+sub query {
  67
+  my ($handle, %opts) = @_;
  68
+  if (ref($handle)) {
  69
+    die("arch pkg query not implemented for file handles\n");
  70
+  }
  71
+  if ($handle =~ /\.xz$/) {
  72
+    my $nh;
  73
+    open($nh, '-|', 'xzdec', '-dc', $handle) || die("$handle: $!\n");
  74
+    $handle = $nh;
  75
+  }
  76
+  my $tar = Archive::Tar->new;
  77
+  my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
  78
+  die("$handle: not an arch package file\n") unless @read ==  1;
  79
+  my $pkginfo = $read[0]->get_content;
  80
+  die("$handle: not an arch package file\n") unless $pkginfo;
  81
+  my %vars;
  82
+  for my $l (split('\n', $pkginfo)) {
  83
+    next unless $l =~ /^(.*?) = (.*)$/;
  84
+    push @{$vars{$1}}, $2;
  85
+  }
  86
+  my $ret = {};
  87
+  $ret->{'name'} = $vars{'pkgname'}->[0] if $vars{'pkgname'};
  88
+  $ret->{'hdrmd5'} = Digest::MD5::md5_hex($pkginfo);
  89
+  $ret->{'provides'} = $vars{'provides'} || [];
  90
+  $ret->{'requires'} = $vars{'depends'} || [];
  91
+  if ($vars{'pkgname'}) {
  92
+    my $selfprovides = $vars{'pkgname'}->[0];
  93
+    $selfprovides .= "=$vars{'pkgver'}->[0]" if $vars{'pkgver'};
  94
+    push @{$ret->{'provides'}}, $selfprovides unless @{$ret->{'provides'} || []} && $ret->{'provides'}->[-1] eq $selfprovides;
  95
+  }
  96
+  if ($opts{'evra'}) {
  97
+    if ($vars{'pkgver'}) {
  98
+      my $evr = $vars{'pkgver'}->[0];
  99
+      if ($evr =~ /^([0-9]+):(.*)$/) {
  100
+	$ret->{'epoch'} = $1;
  101
+	$evr = $2;
  102
+      }
  103
+      $ret->{'version'} = $evr;
  104
+      if ($evr =~ /^(.*)-(.*?)$/) {
  105
+	$ret->{'version'} = $1;
  106
+	$ret->{'release'} = $2;
  107
+      }
  108
+    }
  109
+    $ret->{'arch'} = $vars{'arch'}->[0] if $vars{'arch'};
  110
+  }
  111
+  if ($opts{'description'}) {
  112
+    $ret->{'description'} = $vars{'pkgdesc'}->[0] if $vars{'pkgdesc'};
  113
+  }
  114
+  return $ret;
  115
+}
  116
+
  117
+sub queryhdrmd5 {
  118
+  my ($handle) = @_;
  119
+  if (ref($handle)) {
  120
+    die("arch pkg query not implemented for file handles\n");
  121
+  }
  122
+  if ($handle =~ /\.xz$/) {
  123
+    my $nh;
  124
+    open($nh, '-|', 'xzdec', '-dc', $handle) || die("$handle: $!\n");
  125
+    $handle = $nh;
  126
+  }
  127
+  my $tar = Archive::Tar->new;
  128
+  my @read = $tar->read($handle, 1, {'filter' => '^\.PKGINFO$', 'limit' => 1});
  129
+  die("$handle: not an arch package file\n") unless @read ==  1;
  130
+  my $pkginfo = $read[0]->get_content;
  131
+  die("$handle: not an arch package file\n") unless $pkginfo;
  132
+  return Digest::MD5::md5_hex($pkginfo);
  133
+}
  134
+
  135
+sub parserepodata {
  136
+  my ($d, $data) = @_;
  137
+  $d ||= {};
  138
+  $data =~ s/^\n+//s;
  139
+  my @parts = split(/\n\n+/s, $data);
  140
+  for my $part (@parts) {
  141
+    my @p = split("\n", $part);
  142
+    my $p = shift @p;
  143
+    if ($p eq '%NAME%') {
  144
+      $d->{'name'} = $p[0];
  145
+    } elsif ($p eq '%VERSION%') {
  146
+      $d->{'version'} = $p[0];
  147
+    } elsif ($p eq '%ARCH%') {
  148
+      $d->{'arch'} = $p[0];
  149
+    } elsif ($p eq '%BUILDDATE%') {
  150
+      $d->{'buildtime'} = $p[0];
  151
+    } elsif ($p eq '%FILENAME%') {
  152
+      $d->{'filename'} = $p[0];
  153
+    } elsif ($p eq '%PROVIDES%') {
  154
+      push @{$d->{'provides'}}, @p;
  155
+    } elsif ($p eq '%DEPENDS%') {
  156
+      push @{$d->{'requires'}}, @p;
  157
+    }
  158
+  }
  159
+  return $d;
  160
+}
  161
+
  162
+1;
1  Makefile
@@ -48,6 +48,7 @@ install:
48 48
 	    debtransformzip \
49 49
 	    mkbaselibs \
50 50
 	    mkdrpms \
  51
+	    createarchdeps \
51 52
 	    createrepomddeps \
52 53
 	    createyastdeps \
53 54
 	    changelog2spec \
67  createarchdeps
... ...
@@ -0,0 +1,67 @@
  1
+#!/usr/bin/perl -w
  2
+
  3
+# Archlinux support, based on the GSoC work of Nikolay Rysev <mad.f3ka@gmail.com>
  4
+
  5
+BEGIN {
  6
+  unshift @INC, ($::ENV{"BUILD_DIR"} || "/usr/lib/build");
  7
+}
  8
+
  9
+use strict;
  10
+use Archive::Tar;
  11
+use Build::Arch;
  12
+use Digest::MD5;
  13
+use File::Path;
  14
+
  15
+my $cachedir = "/var/cache/build";
  16
+
  17
+sub getrepodb {
  18
+  my ($url, $reponame, $dir) = @_;
  19
+  File::Path::mkpath($dir);
  20
+  system($INC[0]."/download", $dir, "$url$reponame.db");
  21
+}
  22
+
  23
+sub getreponame {
  24
+  my ($url) = @_;
  25
+  return $1 if "/$url/" =~ /.*\/([^\/]+)\/os\//;
  26
+  return undef;
  27
+}
  28
+
  29
+sub printpkginfo {
  30
+  my ($d, $repourl)  = @_;
  31
+  my $id = $d->{'name'} . "." . $d->{'arch'} . "-" . $d->{'buildtime'} . "/0/0";
  32
+  my $pkgurl = $repourl . $d->{'filename'};
  33
+  my $selfprovides = $d->{'name'};
  34
+  $selfprovides .= "=$d->{'version'}" if defined $d->{'version'};
  35
+  push @{$d->{'provides'}}, $selfprovides unless @{$d->{'provides'} || []} && $d->{'provides'}->[-1] eq $selfprovides;
  36
+  print "F:$id: $pkgurl\n";
  37
+  print "P:$id: " . join(' ', @{$d->{'provides'}}) . "\n" if $d->{'provides'};
  38
+  print "R:$id: " . join(' ', @{$d->{'requires'}}) . "\n" if $d->{'requires'};
  39
+  print "I:$id: $d->{name}-$d->{'version'} $d->{'buildtime'}\n";
  40
+}
  41
+
  42
+for my $url (@ARGV) {
  43
+  die("Not an Archlinux repo") unless $url =~ /^(ht|f)tp:\/\/([^\/]*)\/?/;
  44
+  $url .= '/' unless $url =~ /\/$/;
  45
+  my $reponame = getreponame($url);
  46
+
  47
+  my $repoid = Digest::MD5::md5_hex($url);
  48
+  my $dir = "$cachedir/$repoid";
  49
+  getrepodb($url, $reponame, $dir);
  50
+
  51
+  my $repodb = Archive::Tar->iter("$dir/$reponame.db", 1);
  52
+  my $e;
  53
+  my $lastfn = '';
  54
+  my $d;
  55
+  while ($e = $repodb->()) {
  56
+    next unless $e->type() == Archive::Tar::Constant::FILE;
  57
+    my $fn = $e->name();
  58
+    next unless $fn =~ s/\/(?:depends|desc)$//s;
  59
+    if ($lastfn ne $fn) {
  60
+      printpkginfo($d, $url) if $d->{'name'};
  61
+      $d = {};
  62
+      $lastfn = $fn;
  63
+    }
  64
+    Build::Arch::parserepodata($d, $e->get_content());
  65
+  }
  66
+  printpkginfo($d, $url) if $d->{'name'};
  67
+}
2  createrepomddeps
@@ -402,6 +402,8 @@ for my $url (@ARGV) {
402 402
     $baseurl = $url;
403 403
     $baseurl .= '/' unless $baseurl =~ /\/$/;
404 404
     getmetadata($baseurl, $dir);
  405
+  } elsif ($url =~ /^arch\@/) {
  406
+    exec ($INC[0].'/createarchdeps', substr($url, 5));
405 407
   } else {
406 408
     $dir = $url;
407 409
     $dir .= '/' unless $dir =~ /\/$/;

0 notes on commit af05d93

Please sign in to comment.
Something went wrong with that request. Please try again.