4 unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
12 my ($config, $str) = @_;
15 $cf{'save_expanded'} = 1;
16 Build::Rpm::parse(\%cf, [ "$str" ], \@xspec);
17 return @xspec && ref($xspec[0]) ? $xspec[0]->[1] : '';
20 my ($dist, $buildroot, $rpmdeps, $archs, $configdir, $release, $changelog);
23 if ($ARGV[0] eq '--root') {
25 $buildroot = shift @ARGV;
28 if ($ARGV[0] eq '--dist') {
33 if ($ARGV[0] eq '--archpath') {
38 if ($ARGV[0] eq '--configdir') {
40 $configdir = shift @ARGV;
43 if ($ARGV[0] eq '--release') {
45 $release = shift @ARGV;
48 if ($ARGV[0] eq '--changelog') {
50 $changelog = shift @ARGV;
55 die("Usage: substitutedeps --dist <dist> --archpath <archpath> [--configdir <configdir>] <specin> <specout>\n") unless @ARGV == 2;
58 $specdir =~ s/[^\/]*$//;
59 $specdir = "./" if $specdir eq '';
61 my $newspec = $ARGV[1];
63 my $cf = Build::read_config_dist($dist, $archs, $configdir);
64 $cf->{'warnings'} = 1;
66 #######################################################################
69 my $d = Build::parse($cf, $spec, $xspec) || {};
70 my @sdeps = @{$d->{'deps'} || []};
71 my @neg = map {substr($_, 1)} grep {/^-/} @{$d->{'deps'} || []};
72 my %neg = map {$_ => 1} @neg;
73 @sdeps = grep {!$neg{$_}} @sdeps;
74 @sdeps = Build::do_subst($cf, @sdeps);
75 @sdeps = grep {!$neg{$_}} @sdeps;
76 my %sdeps = map {$_ => 1} @sdeps;
78 open(F, '>', $newspec) || die("$newspec: $!\n");
85 for my $line (@$xspec) {
88 if (!defined($line->[1])) {
97 $inchangelog = 0 if $line =~ /^\s*%[^%]/;
100 if ($changelog && ($line =~ /\s*\%changelog\b/)) {
105 if ($line =~ /^Name\s*:\s*(\S+)/i) {
106 $pkg = $mainpkg = $1 unless $mainpkg;
108 if ($line =~ /^\s*%package\s+(-n\s+)?(\S+)/) {
112 $pkg = "$mainpkg-$2";
116 if ($line =~ /^Release:(.*)\s*$/i) {
117 my $spec_rel = $1; # User-provided value
119 if (defined $release) {
120 $line =~ s/<SPEC_REL>/$spec_rel/;
121 if (!($line =~ s/<RELEASE\d*>/$release/g)) {
122 if ($line =~ /<(?:CI_CNT|B_CNT)>/) {
123 # XXX: should pass ci_cnt/b_cnt instead
124 if ($release =~ /(\d+)\.(\d+)$/) {
125 my ($ci, $b) = ($1, $2);
126 $line =~ s/<CI_CNT>/$ci/;
127 $line =~ s/<B_CNT>/$b/;
128 } elsif ($release =~ /(\d+)$/) {
130 $b = '0' if $line =~ s/<CI_CNT>/$b/;
131 $line =~ s/<B_CNT>/$b/;
134 $line =~ s/^(Release:\s*).*/$1$release/i;
138 # remove macros, as rpm doesn't like them
139 $line =~ s/<RELEASE\d*>/0/;
140 $line =~ s/<CI_CNT>/0/;
141 $line =~ s/<B_CNT>/0/;
142 $line =~ s/<SPEC_REL>/0/;
144 # this is to be compatible to legacy autobuild.
145 # you can specify a releaseprg in the project configuration,
146 # if your package contains this file it is executed and its
147 # output is used as a release.
148 # use only if you really must.
149 if ($cf->{'releaseprg'} && -f "$specdir$cf->{'releaseprg'}") {
151 $newl =~ s/^Release:\s*//;
152 $oldl =~ s/^Release:\s*//;
153 my $project = expand($cf, "%?_project") || 'BUILD_BASENAME';
154 my $arch = expand($cf, "%?_target_cpu") || 'noarch';
155 $::ENV{'BUILD_OLDRELEASE'} = $oldl;
157 my $interpreter = "/bin/bash";
158 if (open(RP, '<', "$specdir$cf->{'releaseprg'}")) {
161 if (@nl && $nl[0] =~ /^#!\s*(\S*)/) {
167 $sd =~ s/^\Q$buildroot\E//;
168 open(RP, "-|", 'chroot', $buildroot, $interpreter, "$sd$cf->{'releaseprg'}", $project, $newl, $pkg, $arch) || die("$cf->{'releaseprg'}: $!\n");
170 open(RP, "-|", $interpreter, "$specdir$cf->{'releaseprg'}", $project, $newl, $pkg, $arch) || die("$cf->{'releaseprg'}: $!\n");
172 @nl = grep {$_ ne ''} <RP>;
174 warn("$cf->{'releaseprg'} failed: $?\n");
176 # and another compatibility hack: if the prg returns pkg:<package>,
177 # the release of the package will be used. yuck...
178 if (@nl && $nl[0] =~ s/^pkg://) {
182 open(RP, "-|", 'chroot', $buildroot, 'rpm', '-q', '--qf', '%{RELEASE}', $relpkg) || die("rpm: $!\n");
184 open(RP, "-|", 'rpm', '-q', '--qf', '%{RELEASE}', $relpkg) || die("rpm: $!\n");
186 @nl = grep {$_ ne ''} <RP>;
188 warn("rpm package query of '$relpkg' failed: $?\n");
193 $line =~ s/^(Release:\s*).*/$1$nl[0]/i;
194 if (defined $release) {
195 if (!($line =~ s/<RELEASE\d*>/$release/g)) {
196 if ($line =~ /<(?:CI_CNT|B_CNT)>/) {
197 # XXX: should pass ci_cnt/b_cnt instead
198 if ($release =~ /(\d+)\.(\d+)$/) {
199 my ($ci, $b) = ($1, $2);
200 $line =~ s/<CI_CNT>/$ci/;
201 $line =~ s/<B_CNT>/$b/;
202 } elsif ($release =~ /(\d+)$/) {
204 $line =~ s/<B_CNT>/$b/ unless $line =~ s/<CI_CNT>/$b/;
211 # all compat stuff done. we return to your scheduled program
214 if (!$used || ($line !~ /^(?:Build)?Requires:/i)) {
218 if ($line =~ /%\(/) {
224 my $isbuildrequires = 0;
225 $isbuildrequires = 1 if $line =~ /^BuildRequires:/i;
227 $r =~ s/^[^:]*:\s*//;
228 my @deps = $r =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?[\s,]*/g;
231 my @f2 = Build::do_subst_vers($cf, @deps);
233 if ($isbuildrequires) {
234 delete $f2{$_} for @neg;
235 delete $f2{$_} for grep {/^-/} keys %f2;
238 my ($pack, $vers) = splice(@deps, 0, 2);
239 $vers = '' unless defined $vers;
240 if (($isbuildrequires && $sdeps{$pack}) || exists($f2{$pack})) {
241 push @ndeps, "$pack$vers";
249 my ($pack, $vers) = splice(@f2, 0, 2);
250 next unless exists $f2{$pack};
251 $vers = '' unless defined $vers;
252 push @ndeps, "$pack$vers";
257 $line =~ /^(.*?:\s*)/;
258 print F $1.join(' ', @ndeps)."\n" if @ndeps;
265 print F "%changelog\n";
266 if (open(CF, '<', $changelog)) {
274 close(F) || die("close: $!\n");