openpkg/dev.pl

Thu, 04 Oct 2012 20:30:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Oct 2012 20:30:05 +0200
changeset 715
c10fb90893b9
permissions
-rw-r--r--

Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.

michael@428 1 ##
michael@428 2 ## openpkg dev -- OpenPKG Package Development Tool
michael@428 3 ## Copyright (c) 2008-2012 OpenPKG GmbH <http://openpkg.com/>
michael@428 4 ##
michael@428 5 ## This software is property of the OpenPKG GmbH, DE MUC HRB 160208.
michael@428 6 ## All rights reserved. Licenses which grant limited permission to use,
michael@428 7 ## copy, modify and distribute this software are available from the
michael@428 8 ## OpenPKG GmbH.
michael@428 9 ##
michael@428 10 ## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
michael@428 11 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@428 12 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@428 13 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@428 14 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@428 15 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@428 16 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@428 17 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@428 18 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@428 19 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@428 20 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@428 21 ## SUCH DAMAGE.
michael@428 22 ##
michael@428 23
michael@428 24 require 5;
michael@428 25
michael@428 26 # OpenPKG instance prefix and RPM
michael@428 27 my $openpkg_prefix = $ENV{'OPENPKG_PREFIX'};
michael@428 28 delete $ENV{'OPENPKG_PREFIX'};
michael@428 29
michael@428 30 # program identification
michael@428 31 my $prog_name = "dev";
michael@428 32 my $prog_vers = "20100111";
michael@428 33
michael@428 34 # home-brewn getopt(3) style option parser
michael@428 35 sub getopts ($$@) {
michael@428 36 my ($opt_spec, $opts, @argv_orig) = @_;
michael@428 37 my (%optf) = map { m/(\w)/; $1 => $_ } $opt_spec =~ m/(\w:|\w)/g;
michael@428 38 my (@argv, $optarg);
michael@428 39
michael@428 40 foreach (@argv_orig) {
michael@428 41 if (@argv) {
michael@428 42 push @argv, $_;
michael@428 43 } elsif (defined $optarg) {
michael@428 44 if (exists $opts->{$optarg}) {
michael@428 45 $opts->{$optarg} .= " $_";
michael@428 46 } else {
michael@428 47 $opts->{$optarg} = $_;
michael@428 48 }
michael@428 49 $optarg = undef;
michael@428 50 } elsif (!/^[-]/) {
michael@428 51 push @argv, $_;
michael@428 52 } else {
michael@428 53 while (/^\-(\w)(.*)/) {
michael@428 54 if (exists $optf{$1}) {
michael@428 55 if (length($optf{$1}) > 1) {
michael@428 56 if ($2 ne '') {
michael@428 57 if (exists $opts->{$1}) {
michael@428 58 $opts->{$1} .= " $2";
michael@428 59 } else {
michael@428 60 $opts->{$1} = $2;
michael@428 61 }
michael@428 62 } else {
michael@428 63 $optarg = $1;
michael@428 64 }
michael@428 65 last;
michael@428 66 } else {
michael@428 67 $opts->{$1} = 1;
michael@428 68 }
michael@428 69 } else {
michael@428 70 warn "openpkg:$prog_name:WARNING: unknown option $_\n";
michael@428 71 }
michael@428 72 $_ = "-$2";
michael@428 73 }
michael@428 74 }
michael@428 75 }
michael@428 76 if (defined $optarg) {
michael@428 77 warn "openpkg:$prog_name:WARNING: option $optarg requires an argument\n";
michael@428 78 }
michael@428 79 foreach my $opt (keys %optf) {
michael@428 80 if (not exists $opts->{$opt}) {
michael@428 81 $opts->{$opt} = (length($optf{$opt}) > 1 ? "" : 0);
michael@428 82 }
michael@428 83 }
michael@428 84 return @argv;
michael@428 85 }
michael@428 86
michael@428 87 # determine reasonable temporary directory
michael@428 88 my $tmpdir = ($ENV{"TMPDIR"} || "/tmp");
michael@428 89 $tmpdir .= "/openpkg-$prog_name-$$";
michael@428 90 my $rc = system("umask 022; $openpkg_prefix/lib/openpkg/shtool mkdir -f -p -m 755 $tmpdir || exit $?");
michael@428 91 if ($rc != 0) {
michael@428 92 die "failed to create temporary directory: $tmpdir";
michael@428 93 }
michael@428 94
michael@428 95 # parse command line options
michael@428 96 my $opts = {};
michael@428 97 @ARGV = getopts("h", $opts, @ARGV);
michael@428 98
michael@428 99 # usage sanity check and usage help
michael@428 100 sub usage {
michael@428 101 my ($rc) = @_;
michael@428 102 my $usage =
michael@428 103 "openpkg:$prog_name:USAGE: openpkg dev <command> [<options>]\n";
michael@428 104 if ($rc == 0) {
michael@428 105 print STDOUT $usage;
michael@428 106 }
michael@428 107 else {
michael@428 108 print STDERR $usage;
michael@428 109 }
michael@428 110 exit($rc);
michael@428 111 }
michael@428 112 if ($opts->{"h"}) {
michael@428 113 usage(0);
michael@428 114 }
michael@428 115 if (@ARGV == 0) {
michael@428 116 usage(1);
michael@428 117 }
michael@428 118
michael@428 119 # command map
michael@428 120 my $map = {
michael@428 121 "unpack " => { -alias => qr/^(up|ex)$/, -key => "x" },
michael@428 122 "edit\n" => { -alias => qr/^(ed|vi)$/, -key => "v" },
michael@428 123 "build -s track\n" => { -alias => qr/^(bt|tr)$/, -key => "t" },
michael@428 124 "build -s fetch\n" => { -alias => qr/^(bf|fe)$/, -key => "f" },
michael@428 125 "build\n" => { -alias => qr/^(ba|bu)$/, -key => "b" },
michael@428 126 "build -s prep\n" => { -alias => qr/^bp$/, -key => "1" },
michael@428 127 "build -s compile\n" => { -alias => qr/^bc$/, -key => "2" },
michael@428 128 "build -s install\n" => { -alias => qr/^bi$/, -key => "3" },
michael@428 129 "build -s binary\n" => { -alias => qr/^bb$/, -key => "4" },
michael@428 130 "build -s source\n" => { -alias => qr/^bs$/, -key => "s" },
michael@428 131 "peek\n" => { -alias => qr/^pe$/, -key => "p" },
michael@428 132 "diff\n" => { -alias => qr/^di$/, -key => "d" },
michael@428 133 "install\n" => { -alias => qr/^in(?:st)?$/, -key => "i" },
michael@428 134 "erase\n" => { -alias => qr/^er$/, -key => "e" },
michael@428 135 "lint\n" => { -alias => qr/^li$/, -key => "l" },
michael@428 136 "release " => { -alias => qr/^rel?$/, -key => "r" },
michael@428 137 };
michael@428 138
michael@428 139 # dispatch command
michael@428 140 my $cmd = shift(@ARGV);
michael@428 141 foreach my $c (keys %{$map}) {
michael@428 142 my $a = $map->{$c}->{-alias};
michael@428 143 if ($cmd =~ $a) {
michael@428 144 $c =~ s/\n$//;
michael@428 145 my @args = split(/\s+/, $c);
michael@428 146 $cmd = shift(@args);
michael@428 147 unshift(@ARGV, @args);
michael@428 148 print STDOUT "\033[34m\$ opd $cmd " . join(" ", map {
michael@428 149 my $x = $_;
michael@428 150 $x =~ s/"/\\"/g;
michael@428 151 $x =~ s/^(.*[ \t].*)$/"$1"/;
michael@428 152 $x
michael@428 153 } @ARGV) . "\033[0m\n";
michael@428 154 }
michael@428 155 }
michael@428 156 my $func = "cmd_$cmd";
michael@428 157 if (not defined(&$func)) {
michael@428 158 print STDERR "openpkg:$prog_name:ERROR: invalid command \"$cmd\"\n";
michael@428 159 usage(1);
michael@428 160 }
michael@428 161 my $rc = &$func($opts, @ARGV);
michael@428 162 exit($rc);
michael@428 163
michael@428 164 # execute a shell command
michael@428 165 sub run {
michael@428 166 my ($cmd) = @_;
michael@428 167 print STDOUT "\033[34m\$ $cmd\033[0m\n";
michael@428 168 my $rc = system($cmd);
michael@428 169 return $rc;
michael@428 170 }
michael@428 171
michael@428 172 # determine path to package specification
michael@428 173 sub specfile {
michael@428 174 my $specfile = (glob("*.spec"))[0];
michael@428 175 if (not defined $specfile) {
michael@428 176 $specfile = (glob("src/*.spec"))[0];
michael@428 177 if (not defined $specfile) {
michael@428 178 $specfile = (glob("*/*.spec"))[0];
michael@428 179 if (not defined $specfile) {
michael@428 180 print STDERR "openpkg:$prog_name:ERROR: unable to determine package specification file\n";
michael@428 181 exit(1);
michael@428 182 }
michael@428 183 }
michael@428 184 }
michael@428 185 return $specfile;
michael@428 186 }
michael@428 187
michael@428 188 # command: interactive shell
michael@428 189 sub cmd_shell ($@) {
michael@428 190 my ($gopts, @argv) = @_;
michael@428 191 my $rc = 0;
michael@428 192
michael@428 193 # command line argument processing
michael@428 194 my $lopts = {};
michael@428 195 @argv = getopts("s", $lopts, @argv);
michael@428 196
michael@428 197 # determine release
michael@428 198 my $release = `$openpkg_prefix/bin/openpkg release -F '%t'`;
michael@428 199 $release =~ s/\n$//s;
michael@428 200
michael@428 201 # create dot files
michael@428 202 my $screenrc = "$tmpdir/dot.screenrc";
michael@428 203 my $bashsh = "$tmpdir/bash.sh";
michael@428 204 my $bashrc = "$tmpdir/dot.bashrc";
michael@428 205 my $inputrc = "$tmpdir/dot.inputrc";
michael@428 206 unlink("$screenrc");
michael@428 207 unlink("$bashsh");
michael@428 208 unlink("$bashrc");
michael@428 209 unlink("$inputrc");
michael@428 210 my $title = "openpkg dev";
michael@428 211 $title .= '%? %{= rW} %n %{-}%?';
michael@428 212 $title .= ' %=%-w%{= rW}%50>%n %t%{-}%+w';
michael@428 213 my $screenrc_data = "";
michael@428 214 $screenrc_data .= "source \"$ENV{HOME}/.screenrc\"\n" if (-f "$ENV{HOME}/.screenrc");
michael@428 215 $screenrc_data .=
michael@428 216 "escape ^Aa\n" .
michael@428 217 "startup_message off\n" .
michael@428 218 "vbell off\n" .
michael@428 219 "defscrollback 10000\n" .
michael@428 220 "defmonitor off\n" .
michael@428 221 "msgminwait 1\n" .
michael@428 222 "msgwait 1\n" .
michael@428 223 "hardstatus alwayslastline \" $title \"\n" .
michael@428 224 "shell $bashsh\n";
michael@428 225 my $bashsh_data =
michael@428 226 "##\n" .
michael@428 227 "##\ bash.sh -- \"openpkg dev shell\" GNU bash wrapper script\n" .
michael@428 228 "##\n" .
michael@428 229 "\n" .
michael@428 230 "OPENPKG_PREFIX=\"$openpkg_prefix\"\n" .
michael@428 231 "export OPENPKG_PREFIX\n" .
michael@428 232 "INPUTRC=\"$inputrc\"\n" .
michael@428 233 "export INPUTRC\n" .
michael@428 234 "SHELL=\"$openpkg_prefix/lib/openpkg/bash\"\n" .
michael@428 235 "export SHELL\n" .
michael@428 236 "eval `$openpkg_prefix/bin/openpkg rpm --eval 'T=\"\%{_tmppath}\"; S=\"\%{_specdir}\"; D=\"\%{_sourcedir}\"'`\n" .
michael@428 237 "export T S D\n" .
michael@428 238 "\$SHELL --rcfile $bashrc";
michael@428 239 my $bashrc_data =
michael@428 240 "##\n" .
michael@428 241 "## dot.bashrc -- \"openpkg dev shell\" GNU bash configuration\n" .
michael@428 242 "##\n" .
michael@428 243 "\n" .
michael@428 244 "# load user's standard bash run-command script\n" .
michael@428 245 "if [ -f ~/.bashrc ]; then\n" .
michael@428 246 " . ~/.bashrc\n" .
michael@428 247 "fi\n" .
michael@428 248 "\n" .
michael@428 249 "# configure a special command-line prompt\n" .
michael@428 250 "if [ \".\$TERM\" = .screen ]; then\n" .
michael@428 251 " PS1=\"\\\\u@\\\\h:\\\\w [P=\\\\e[1m\\\${OPENPKG_PREFIX}\\\\e[0m]\\n\\\\\\\$ \\\\ek\\\\W\\\\e\\\\\\\\\"\n" .
michael@428 252 "else\n" .
michael@428 253 " PS1=\"\\\\u@\\\\h:\\\\w [P=\\\\e[1m\\\${OPENPKG_PREFIX}\\\\e[0m]\\n\\\\\\\$ \"\n" .
michael@428 254 "fi\n" .
michael@428 255 "alias openpkg=\"\\\${OPENPKG_PREFIX}/bin/openpkg\"\n" .
michael@428 256 "alias opd=\"\\\${OPENPKG_PREFIX}/bin/openpkg dev\"\n" .
michael@428 257 "\n";
michael@428 258 my $inputrc_data =
michael@428 259 "##\n" .
michael@428 260 "## dot.inputrc -- \"openpkg dev shell\" GNU readline configuration\n" .
michael@428 261 "##\n" .
michael@428 262 "\n";
michael@428 263 foreach my $c (keys %{$map}) {
michael@428 264 my $k = $map->{$c}->{-key};
michael@428 265 $c =~ s/\n/\\n/sg;
michael@428 266 $inputrc_data .= "\"\\e$k\": \"opd $c\"\n";
michael@428 267 }
michael@428 268 $inputrc_data .= "\n";
michael@428 269 open(SCREENRC, ">$screenrc");
michael@428 270 print(SCREENRC $screenrc_data);
michael@428 271 close(SCREENRC);
michael@428 272 open(BASHSH, ">$bashsh");
michael@428 273 print(BASHSH $bashsh_data);
michael@428 274 close(BASHSH);
michael@428 275 system("chmod a+x $bashsh");
michael@428 276 open(BASHRC, ">$bashrc");
michael@428 277 print(BASHRC $bashrc_data);
michael@428 278 close(BASHRC);
michael@428 279 open(INPUTRC, ">$inputrc");
michael@428 280 print(INPUTRC $inputrc_data);
michael@428 281 close(INPUTRC);
michael@428 282
michael@428 283 # run interactive shell
michael@428 284 print STDOUT "\033[34m++ entering OpenPKG $release development shell\033[0m\n";
michael@428 285 my $rc;
michael@428 286 if ($lopts->{"s"}) {
michael@428 287 $rc = system("screen -c $screenrc -S 'openpkg-dev-shell' -d -R");
michael@428 288 }
michael@428 289 else {
michael@428 290 $rc = system("$bashsh");
michael@428 291 }
michael@428 292
michael@428 293 # cleanup
michael@428 294 unlink("$tmpdir/dot.screenrc");
michael@428 295 unlink("$tmpdir/bash.sh");
michael@428 296 unlink("$tmpdir/dot.bashrc");
michael@428 297 unlink("$tmpdir/dot.inputrc");
michael@428 298 unlink("$tmpdir");
michael@428 299
michael@428 300 return $rc;
michael@428 301 }
michael@428 302
michael@428 303 # command: unpack source RPM
michael@428 304 sub cmd_unpack ($@) {
michael@428 305 my ($gopts, @argv) = @_;
michael@428 306 my $rc = 0;
michael@428 307
michael@428 308 # command line argument processing
michael@428 309 my $lopts = {};
michael@428 310 @argv = getopts("l:b:sd", $lopts, @argv);
michael@428 311 if ($lopts->{"l"} eq "") {
michael@428 312 $lopts->{"l"} = "structured";
michael@428 313 }
michael@428 314 if ($lopts->{"l"} !~ m/^(global|local|simple|structured|distributed)$/) {
michael@428 315 die sprintf("invalid layout type \"%s\"", $lopts->{"l"});
michael@428 316 }
michael@428 317 if (@argv != 1) {
michael@428 318 die sprintf("exactly one SRPM has to be given");
michael@428 319 }
michael@428 320 my $srpm = $argv[0];
michael@428 321 if (not -f $srpm) {
michael@428 322 die sprintf("SRPM \"%s\" has to be a regular file", $srpm);
michael@428 323 }
michael@428 324 my $name = `$openpkg_prefix/bin/openpkg rpm -qp --qf '\%{NAME}' $srpm 2>/dev/null || true`;
michael@428 325 $name =~ s/\r?\n$//s;
michael@428 326 if ($name eq '') {
michael@428 327 die sprintf("unable to determine package name from SRPM \"%s\"", $srpm);
michael@428 328 }
michael@428 329 if ($lopts->{"b"} eq "") {
michael@428 330 $lopts->{"b"} = $srpm;
michael@428 331 if ($lopts->{"b"} =~ m/\.src\.rpm$/) {
michael@428 332 $lopts->{"b"} =~ s/\.src\.rpm$//;
michael@428 333 }
michael@428 334 else {
michael@428 335 my $subdir = `$openpkg_prefix/bin/openpkg rpm -qp --qf '\%{NAME}-\%{VERSION}-\%{RELEASE}' $srpm 2>/dev/null || true`;
michael@428 336 $lopts->{"b"} = $subdir;
michael@428 337 }
michael@428 338 }
michael@428 339
michael@428 340 # determine result directory
michael@428 341 my $basedir = $lopts->{"b"};
michael@428 342 my ($macrosfile, $specdir, $sourcedir);
michael@428 343 if ($lopts->{"l"} eq "global") {
michael@428 344 $macrosdir = "$openpkg_prefix/etc/openpkg";
michael@428 345 $macrosfile = "$openpkg_prefix/etc/openpkg/rpmmacros";
michael@428 346 $specdir = "$openpkg_prefix/RPM/SRC/$name";
michael@428 347 $sourcedir = "$openpkg_prefix/RPM/SRC/$name";
michael@428 348 $builddir = "$openpkg_prefix/RPM/TMP";
michael@428 349 $tmpdir = "$openpkg_prefix/RPM/TMP";
michael@428 350 $binrpmdir = "$openpkg_prefix/RPM/PKG";
michael@428 351 $srcrpmdir = "$openpkg_prefix/RPM/PKG";
michael@428 352 }
michael@428 353 elsif ($lopts->{"l"} eq "local") {
michael@428 354 $macrosdir = "$basedir/.openpkg";
michael@428 355 $macrosfile = "$basedir/.openpkg/rpmmacros";
michael@428 356 $specdir = "$basedir";
michael@428 357 $sourcedir = "$basedir";
michael@428 358 $builddir = "$basedir";
michael@428 359 $tmpdir = "$basedir";
michael@428 360 $binrpmdir = "$basedir";
michael@428 361 $srcrpmdir = "$basedir";
michael@428 362 }
michael@428 363 elsif ($lopts->{"l"} eq "simple") {
michael@428 364 $macrosdir = "$basedir/.openpkg";
michael@428 365 $macrosfile = "$basedir/.openpkg/rpmmacros";
michael@428 366 $specdir = "$basedir";
michael@428 367 $sourcedir = "$basedir";
michael@428 368 $builddir = "$tmpdir";
michael@428 369 $tmpdir = "$tmpdir";
michael@428 370 $binrpmdir = "$basedir/..";
michael@428 371 $srcrpmdir = "$basedir/..";
michael@428 372 }
michael@428 373 elsif ($lopts->{"l"} eq "structured") {
michael@428 374 $macrosdir = "$basedir/.openpkg";
michael@428 375 $macrosfile = "$basedir/.openpkg/rpmmacros";
michael@428 376 $specdir = "$basedir/src";
michael@428 377 $sourcedir = "$basedir/dst";
michael@428 378 $builddir = "$basedir/tmp";
michael@428 379 $tmpdir = "$basedir/tmp";
michael@428 380 $binrpmdir = "$basedir/pkg/bin";
michael@428 381 $srcrpmdir = "$basedir/pkg/src";
michael@428 382 }
michael@428 383 elsif ($lopts->{"l"} eq "distributed") {
michael@428 384 $macrosdir = "$basedir/.openpkg";
michael@428 385 $macrosfile = "$basedir/.openpkg/rpmmacros";
michael@428 386 $specdir = "$basedir/src/$name";
michael@428 387 $sourcedir = "$basedir/dst/$name";
michael@428 388 $builddir = "$basedir/tmp";
michael@428 389 $tmpdir = "$basedir/tmp";
michael@428 390 $binrpmdir = "$basedir/pkg/bin";
michael@428 391 $srcrpmdir = "$basedir/pkg/src";
michael@428 392 }
michael@428 393
michael@428 394 # create still missing directories
michael@428 395 foreach my $dir ($macrosdir, $specdir, $sourcedir, $builddir, $tmpdir, $binrpmdir, $srcrpmdir) {
michael@428 396 if (not -d $dir) {
michael@428 397 print STDOUT "openpkg:$prog_name: creating directory \"$dir\"\n";
michael@428 398 system("$openpkg_prefix/lib/openpkg/shtool mkdir -f -p -m 755 $dir");
michael@428 399 }
michael@428 400 }
michael@428 401
michael@428 402 # unpack SRPM
michael@428 403 print STDOUT "openpkg:$prog_name: unpacking source: \"$srpm\"\n";
michael@428 404 print STDOUT "openpkg:$prog_name: unpacking target: \"$specdir\"\n";
michael@428 405 print STDOUT "openpkg:$prog_name: unpacking target: \"$sourcedir\"\n";
michael@428 406 my $abs_specdir = $specdir;
michael@428 407 my $abs_sourcedir = $sourcedir;
michael@428 408 my $pwd = `pwd`; $pwd =~ s/\r?\n$//s;
michael@428 409 $abs_specdir = "$pwd/$abs_specdir" if ($abs_specdir !~ m/^\//);
michael@428 410 $abs_sourcedir = "$pwd/$abs_sourcedir" if ($abs_sourcedir !~ m/^\//);
michael@428 411 my $rc = system(
michael@428 412 "$openpkg_prefix/bin/openpkg" .
michael@428 413 " --keep-privileges" .
michael@428 414 " rpm" .
michael@428 415 " -i" .
michael@428 416 " --define '_specdir $abs_specdir'" .
michael@428 417 " --define '_sourcedir $abs_sourcedir'" .
michael@428 418 " $srpm"
michael@428 419 );
michael@428 420
michael@428 421 # fix location of files
michael@428 422 if (not -f "$specdir/$name.spec") {
michael@428 423 die sprintf("failed to install package \"%s\": file \"%s\" not found\n", $srpm, "$specdir/$name.spec");
michael@428 424 }
michael@428 425 open(SPEC, "<$specdir/$name.spec");
michael@428 426 my $spec = ""; { local $/; $spec = <SPEC>; }
michael@428 427 close(SPEC);
michael@428 428 my $src = {};
michael@428 429 $spec =~ s/^(?:Source|Patch)\d+:\s+(\S+)/$src->{$1} = 1, ''/mgei;
michael@428 430 foreach my $file (keys %{$src}) {
michael@428 431 if ($file !~ m/^(https?|ftp):\/\//) {
michael@428 432 if (not -f "$specdir/$file" and -f "$sourcedir/$file") {
michael@428 433 system("mv $sourcedir/$file $specdir/$file");
michael@428 434 }
michael@428 435 }
michael@428 436 }
michael@428 437
michael@428 438 # create .openpkg/rpmmacros file
michael@428 439 if (not -f $macrosfile) {
michael@428 440 print STDOUT "openpkg:$prog_name: creating file: \"$macrosfile\"\n";
michael@428 441 my $rpmmacros =
michael@428 442 "##\n" .
michael@428 443 "## .openpkg/rpmmacros -- local OpenPKG RPM macro definitions\n" .
michael@428 444 "##\n" .
michael@428 445 "\n" .
michael@428 446 "\%openpkg_layout" .
michael@428 447 " macrosfile=\%{macrosfile}" .
michael@428 448 " layout=" . $lopts->{"l"} .
michael@428 449 " shared=" . ($lopts->{"s"} ? "yes" : "no") .
michael@428 450 " debug=" . ($lopts->{"d"} ? "yes" : "no") .
michael@428 451 "\n" .
michael@428 452 "\n";
michael@428 453 open(MACROS, ">$macrosfile");
michael@428 454 print(MACROS $rpmmacros);
michael@428 455 close(MACROS);
michael@428 456 }
michael@428 457
michael@428 458 return $rc;
michael@428 459 }
michael@428 460
michael@428 461 # command: edit package specification
michael@428 462 sub cmd_edit ($@) {
michael@428 463 my ($gopts, @argv) = @_;
michael@428 464 my $rc = 0;
michael@428 465
michael@428 466 # run editor
michael@428 467 my $editor = ($ENV{"EDITOR"} || "vi");
michael@428 468 my $specfile = ($argv[0] || specfile());
michael@428 469 run("$editor $specfile");
michael@428 470
michael@428 471 return $rc;
michael@428 472 }
michael@428 473
michael@428 474 # command: build package
michael@428 475 sub cmd_build ($@) {
michael@428 476 my ($gopts, @argv) = @_;
michael@428 477 my $rc = 0;
michael@428 478
michael@428 479 # command line argument processing
michael@428 480 my $lopts = {};
michael@428 481 @argv = getopts("s:D:w:", $lopts, @argv);
michael@428 482 if ($lopts->{"s"} eq '') {
michael@428 483 $lopts->{"s"} = "all";
michael@428 484 }
michael@428 485 if ($lopts->{"s"} !~ m/^(track|fetch|prep|compile|install|binary|source|all)$/) {
michael@428 486 die "invalid step";
michael@428 487 }
michael@428 488
michael@428 489 # assembly defines
michael@428 490 my $defs = "";
michael@428 491 if ($lopts->{"D"}) {
michael@428 492 foreach my $def (split(/\s+/, $lopts->{"D"})) {
michael@428 493 if ($def =~ m/^([^=]+)=(.+)$/) {
michael@428 494 $defs .= "--define '$1 $2' ";
michael@428 495 }
michael@428 496 else {
michael@428 497 $defs .= "--define '$def yes' ";
michael@428 498 }
michael@428 499 }
michael@428 500 }
michael@428 501 if ($lopts->{"w"}) {
michael@428 502 foreach my $def (split(/\s+/, $lopts->{"w"})) {
michael@428 503 $defs .= "--with $def ";
michael@428 504 }
michael@428 505 }
michael@428 506
michael@428 507 # run build command
michael@428 508 my $specfile = ($argv[0] || specfile());
michael@428 509 if ($lopts->{"s"} eq 'track') {
michael@428 510 run("$openpkg_prefix/bin/openpkg rpm -bt $defs$specfile");
michael@428 511 }
michael@428 512 elsif ($lopts->{"s"} eq 'fetch') {
michael@428 513 run("$openpkg_prefix/bin/openpkg rpm -bf $defs$specfile");
michael@428 514 }
michael@428 515 elsif ($lopts->{"s"} eq 'prep') {
michael@428 516 run("$openpkg_prefix/bin/openpkg rpm -bp $defs$specfile");
michael@428 517 }
michael@428 518 elsif ($lopts->{"s"} eq 'compile') {
michael@428 519 run("$openpkg_prefix/bin/openpkg rpm -bc --short-circuit $defs$specfile");
michael@428 520 }
michael@428 521 elsif ($lopts->{"s"} eq 'install') {
michael@428 522 run("$openpkg_prefix/bin/openpkg rpm -bi --short-circuit $defs$specfile");
michael@428 523 }
michael@428 524 elsif ($lopts->{"s"} eq 'binary') {
michael@428 525 run("$openpkg_prefix/bin/openpkg rpm -bb --short-circuit $defs$specfile");
michael@428 526 }
michael@428 527 elsif ($lopts->{"s"} eq 'source') {
michael@428 528 run("$openpkg_prefix/bin/openpkg rpm -bs $defs$specfile");
michael@428 529 }
michael@428 530 elsif ($lopts->{"s"} eq 'all') {
michael@428 531 run("$openpkg_prefix/bin/openpkg rpm -ba $defs$specfile");
michael@428 532 }
michael@428 533
michael@428 534 return $rc;
michael@428 535 }
michael@428 536
michael@428 537 # command: peek into package
michael@428 538 sub cmd_peek ($@) {
michael@428 539 my ($gopts, @argv) = @_;
michael@428 540 my $rc = 0;
michael@428 541
michael@428 542 # run query command
michael@428 543 my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`;
michael@428 544 $template =~ s/\n$//s;
michael@428 545 my $specfile = specfile();
michael@428 546 my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`;
michael@428 547 $rpm =~ s/^XXX//s;
michael@428 548 $rpm =~ s/\n$//s;
michael@428 549
michael@428 550 # determine files
michael@428 551 print STDOUT "\033[34m++ determining configuration files\033[0m\n";
michael@428 552 my @cfgfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qplc $rpm`);
michael@428 553 print STDOUT "\033[34m++ determining documentation files\033[0m\n";
michael@428 554 my @docfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qpld $rpm`);
michael@428 555 print STDOUT "\033[34m++ determining all file information\033[0m\n";
michael@428 556 my @allfiles = split(/\n/, `$openpkg_prefix/bin/openpkg rpm -qplv $rpm`);
michael@428 557
michael@428 558 # create package file listing
michael@428 559 foreach my $line (@allfiles) {
michael@428 560 $prefix = "";
michael@428 561 foreach my $docfile (@docfiles) {
michael@428 562 if ($line =~ m/\s+$docfile\b/s) {
michael@428 563 $prefix .= "D";
michael@428 564 last;
michael@428 565 }
michael@428 566 }
michael@428 567 foreach my $cfgfile (@cfgfiles) {
michael@428 568 if ($line =~ m/\s+$cfgfile\b/s) {
michael@428 569 $prefix .= "C";
michael@428 570 last;
michael@428 571 }
michael@428 572 }
michael@428 573 $prefix .= "--";
michael@428 574 $prefix = substr($prefix, 0, 2);
michael@428 575 if ($line =~ m/^d/) {
michael@428 576 $line =~ s/(\s+\/\S+)/\033[34m$1\033[0m/s;
michael@428 577 }
michael@428 578 print "$prefix $line\n";
michael@428 579 }
michael@428 580
michael@428 581 return $rc;
michael@428 582 }
michael@428 583
michael@428 584 # command: show modifications via VCS
michael@428 585 sub cmd_diff ($@) {
michael@428 586 my ($gopts, @argv) = @_;
michael@428 587 my $rc = 0;
michael@428 588
michael@428 589 my $vcs = "";
michael@428 590 my $cmd = "";
michael@428 591 if (-d "CVS") {
michael@428 592 $vcs = "CVS";
michael@428 593 $cmd = "cvs diff -u3";
michael@428 594 }
michael@428 595 elsif (-d ".svn") {
michael@428 596 $vcs = "Subversion";
michael@428 597 $cmd = "svn diff";
michael@428 598 }
michael@428 599 elsif (-d "_MTN" or -d ".mtn" or
michael@428 600 -d "../_MTN" or -d "../.mtn" or
michael@428 601 -d "../../_MTN" or -d "../../.mtn" or
michael@428 602 -d "../../../_MTN" or -d "../../../.mtn") {
michael@428 603 $vcs = "Monotone";
michael@428 604 $cmd = "mtn diff .";
michael@428 605 }
michael@428 606 elsif (-d ".git" or
michael@428 607 -d "../.git" or
michael@428 608 -d "../../.git" or
michael@428 609 -d "../../../.git") {
michael@428 610 $vcs = "Git";
michael@428 611 $cmd = "git diff . ";
michael@428 612 }
michael@428 613 elsif (-d ".hg" or
michael@428 614 -d "../.hg" or
michael@428 615 -d "../../.hg" or
michael@428 616 -d "../../../.hg") {
michael@428 617 $vcs = "Mercurial";
michael@428 618 $cmd = "hg diff ."
michael@428 619 }
michael@428 620 else {
michael@428 621 $vcs = "OSSP svs";
michael@428 622 $cmd = "svs diff";
michael@428 623 }
michael@428 624 print STDOUT "\033[34m++ modifications as known to underlying $vcs VCS\033[0m\n";
michael@428 625 run($cmd);
michael@428 626 }
michael@428 627
michael@428 628 # command: install package
michael@428 629 sub cmd_install ($@) {
michael@428 630 my ($gopts, @argv) = @_;
michael@428 631 my $rc = 0;
michael@428 632
michael@428 633 # command line argument processing
michael@428 634 my $lopts = {};
michael@428 635 @argv = getopts("fnos", $lopts, @argv);
michael@428 636
michael@428 637 # run install command
michael@428 638 my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`;
michael@428 639 $template =~ s/\n$//s;
michael@428 640 my $specfile = specfile();
michael@428 641 my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`;
michael@428 642 $rpm =~ s/^XXX//s;
michael@428 643 $rpm =~ s/\n$//s;
michael@428 644 chdir("/");
michael@428 645 run(($lopts->{"s"} ? "sudo " : "") .
michael@428 646 "$openpkg_prefix/bin/openpkg rpm -Uvh"
michael@428 647 . ($lopts->{"f"} ? " --force" : "")
michael@428 648 . ($lopts->{"n"} ? " --nodeps" : "")
michael@428 649 . ($lopts->{"o"} ? " --oldpackage" : "")
michael@428 650 . " $rpm");
michael@428 651
michael@428 652 return $rc;
michael@428 653 }
michael@428 654
michael@428 655 # command: erase package
michael@428 656 sub cmd_erase ($@) {
michael@428 657 my ($gopts, @argv) = @_;
michael@428 658 my $rc = 0;
michael@428 659
michael@428 660 # command line argument processing
michael@428 661 my $lopts = {};
michael@428 662 @argv = getopts("fnas", $lopts, @argv);
michael@428 663
michael@428 664 # run erase command
michael@428 665 my $specfile = specfile();
michael@428 666 my $name = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '%{NAME}'`;
michael@428 667 $name =~ s/\n$//s;
michael@428 668 chdir("/");
michael@428 669 run(($lopts->{"s"} ? "sudo " : "") .
michael@428 670 "$openpkg_prefix/bin/openpkg rpm -e"
michael@428 671 . ($lopts->{"f"} ? " --force" : "")
michael@428 672 . ($lopts->{"n"} ? " --nodeps" : "")
michael@428 673 . ($lopts->{"a"} ? " --allmatches" : "")
michael@428 674 . " $name");
michael@428 675
michael@428 676 return $rc;
michael@428 677 }
michael@428 678
michael@428 679 # command: lint package
michael@428 680 sub cmd_lint ($@) {
michael@428 681 my ($gopts, @argv) = @_;
michael@428 682 my $rc = 0;
michael@428 683
michael@428 684 # command line argument processing
michael@428 685 my $lopts = {};
michael@428 686 @argv = getopts("vb", $lopts, @argv);
michael@428 687
michael@428 688 # run source linting commands
michael@428 689 my $specfile = specfile();
michael@428 690 my $fslfile = $specfile;
michael@428 691 $fslfile =~ s/([^\/]+)\.spec$/fsl.$1/s;
michael@428 692 my $rcfile = $specfile;
michael@428 693 $rcfile =~ s/([^\/]+)\.spec$/rc.$1/s;
michael@428 694 my $name = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '%{NAME}'`;
michael@428 695 $name =~ s/\n$//s;
michael@428 696 my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{_rpmfilename}'`;
michael@428 697 $template =~ s/\n$//s;
michael@428 698 my $rpm = `$openpkg_prefix/bin/openpkg rpm -q --specfile '$specfile' --qf 'XXX$template'`;
michael@428 699 $rpm =~ s/^XXX//s;
michael@428 700 $rpm =~ s/\n$//s;
michael@428 701 my $rc = 0;
michael@428 702 $rc += run("$openpkg_prefix/bin/openpkg lint-spec" . ($lopts->{"v"} ? " --verbose" : "") . " $specfile");
michael@428 703 $rc += run("$openpkg_prefix/bin/openpkg lint-fsl" . ($lopts->{"v"} ? " --verbose" : "") . " $fslfile") if (-f $fslfile);
michael@428 704 $rc += run("$openpkg_prefix/bin/openpkg lint-rc" . ($lopts->{"v"} ? " --verbose" : "") . " $rcfile") if (-f $rcfile);
michael@428 705
michael@428 706 # optionally run binary linting command
michael@428 707 run("$openpkg_prefix/bin/openpkg lint-rpm" . ($lopts->{"v"} ? " --verbose" : "") . " $rpm") if (-f $rpm and not $lopts->{"b"});
michael@428 708
michael@428 709 return $rc;
michael@428 710 }
michael@428 711
michael@428 712 # command: release package
michael@428 713 sub cmd_release ($@) {
michael@428 714 my ($gopts, @argv) = @_;
michael@428 715 my $rc = 0;
michael@428 716
michael@428 717 # command line argument processing
michael@428 718 my $lopts = {};
michael@428 719 @argv = getopts("nm:f", $lopts, @argv);
michael@428 720
michael@428 721 # implicit linting
michael@428 722 if (not $lopts->{"f"}) {
michael@428 723 my $rc = cmd_lint($gopts);
michael@428 724 if ($rc != 0 and !$lopts->{"f"}) {
michael@428 725 return $rc;
michael@428 726 }
michael@428 727 }
michael@428 728
michael@428 729 # sanity check environment
michael@428 730 my $cmd = $ENV{"OPENPKG_DEV_RELEASE"}
michael@428 731 || `$openpkg_prefix/bin/openpkg rpm --eval '%{openpkg_dev_release}' 2>/dev/null || true` || "";
michael@428 732 $cmd =~ s/\n$//s;
michael@428 733 if ($cmd eq "") {
michael@428 734 print STDERR "openpkg:$prog_name:ERROR: no \$OPENPKG_DEV_RELEASE command defined\n";
michael@428 735 exit(1);
michael@428 736 }
michael@428 737
michael@428 738 #
michael@428 739 # determine package information
michael@428 740 #
michael@428 741
michael@428 742 print STDOUT "\033[34m++ determining package information\033[0m\n";
michael@428 743 my $info = {};
michael@428 744 $info->{"openpkg-prefix"} = $openpkg_prefix;
michael@428 745 $info->{"option-force"} = $lopts->{"f"} ? "yes" : "no";
michael@428 746
michael@428 747 print STDOUT "-- determining package name/version/release\n";
michael@428 748 my $specfile = specfile();
michael@428 749 my $result = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '::%{NAME}::%{VERSION}::%{RELEASE}'`;
michael@428 750 $result =~ s/\n$//s;
michael@428 751 $result =~ s/^:://s;
michael@428 752 my @result = split(/::/, $result);
michael@428 753 $info->{"package-name"} = $result[0];
michael@428 754 $info->{"package-version"} = $result[1];
michael@428 755 $info->{"package-release"} = $result[2];
michael@428 756
michael@428 757 print STDOUT "-- determining package source and distribution location\n";
michael@428 758 my $defines = "--define '\%name " . $info->{"package-name"} . "'";
michael@428 759 $defines .= " --define '\%version " . $info->{"package-version"} . "'";
michael@428 760 $defines .= " --define '\%release " . $info->{"package-release"} . "'";
michael@428 761 my $result = `$openpkg_prefix/bin/openpkg rpm $defines --eval '%{_specdir}::%{_sourcedir}'`;
michael@428 762 $result =~ s/\n$//s;
michael@428 763 @result = split(/::/, $result);
michael@428 764 $info->{"spec-dir"} = $result[0];
michael@428 765 $info->{"source-dir"} = $result[1];
michael@428 766
michael@428 767 print STDOUT "-- determining package source and binary RPM files\n";
michael@428 768 my $template = `$openpkg_prefix/bin/openpkg rpm --eval '%{_rpmdir}/%{l_binrpmfilename}::%{_srcrpmdir}/%{l_srcrpmfilename}'`;
michael@428 769 $template =~ s/\n$//s;
michael@428 770 $result = `$openpkg_prefix/bin/openpkg rpm -q --specfile $specfile --qf '::$template'`;
michael@428 771 $result =~ s/\n$//s;
michael@428 772 $result =~ s/^:://s;
michael@428 773 @result = split(/::/, $result);
michael@428 774 $info->{"binary-rpm-file"} = $result[0];
michael@428 775 $info->{"source-rpm-file"} = $result[1];
michael@428 776 $info->{"package-version-old"} = "";
michael@428 777 $info->{"package-release-old"} = "";
michael@428 778 $info->{"vcs"} = "none";
michael@428 779
michael@428 780 print STDOUT "-- determining previous package version/release\n";
michael@428 781 my $vcs = "";
michael@428 782 my $diff = "";
michael@428 783 my $content_old = "";
michael@428 784 my $specdir = $info->{"spec-dir"};
michael@428 785 my $specfile = $info->{"package-name"} . ".spec";
michael@428 786 if (-f "$specdir/$specfile") {
michael@428 787 open(FP, "<$specdir/$specfile");
michael@428 788 $content_new .= $_ while (<FP>);
michael@428 789 close(FP);
michael@428 790 if ($content_new =~ m/\n\%No(?:Source|Patch)\s+/s) {
michael@428 791 $info->{"source-rpm-file"} =~ s/\.src\.rpm$/.nosrc.rpm/s;
michael@428 792 }
michael@428 793 if (-d "$specdir/CVS") {
michael@428 794 # package is version controlled via CVS
michael@428 795 $vcs = "cvs";
michael@428 796 $diff = `(cd $specdir && cvs diff -u3 $specfile) 2>/dev/null || true`;
michael@428 797 }
michael@428 798 elsif (-d "$specdir/.svn") {
michael@428 799 # package is version controlled via Subverson (SVN)
michael@428 800 $vcs = "svn";
michael@428 801 $diff = `(cd $specdir && svn diff $specfile) 2>/dev/null || true`;
michael@428 802 }
michael@428 803 elsif (-d "$specdir/_MTN" or -d "$specdir/.mtn" or
michael@428 804 -d "$specdir/../_MTN" or -d "$specdir/../.mtn" or
michael@428 805 -d "$specdir/../../_MTN" or -d "$specdir/../../.mtn" or
michael@428 806 -d "$specdir/../../../_MTN" or -d "$specdir/../../../.mtn") {
michael@428 807 # package is version controlled via Monotone (MTN)
michael@428 808 $vcs = "mtn";
michael@428 809 $diff = `(cd $specdir && mtn diff $specfile) 2>/dev/null || true`;
michael@428 810 $content_old = `(cd $specdir && mtn automate get_file_of -r h: $specfile) 2>/dev/null || true`;
michael@428 811 }
michael@428 812 elsif (-d "$specdir/.git" or
michael@428 813 -d "$specdir/../.git" or
michael@428 814 -d "$specdir/../../.git" or
michael@428 815 -d "$specdir/../../../.git") {
michael@428 816 # package is version controlled via Git
michael@428 817 $vcs = "git";
michael@428 818 $diff = `(cd $specdir && git diff $specfile) 2>/dev/null || true`;
michael@428 819 }
michael@428 820 elsif (-d "$specdir/.hg" or
michael@428 821 -d "$specdir/../.hg" or
michael@428 822 -d "$specdir/../../.hg" or
michael@428 823 -d "$specdir/../../../.hg") {
michael@428 824 # package is version controlled via Mercurial (Hg)
michael@428 825 $vcs = "hg";
michael@428 826 $diff = `(cd $specdir && hg diff $specfile) 2>/dev/null || true`;
michael@428 827 }
michael@428 828 elsif (-f "$specdir/$specfile.orig") {
michael@428 829 # package is patched via OSSP svs
michael@428 830 $vcs = "svs";
michael@428 831 $diff = `(cd $specdir && svs diff $specfile) 2>/dev/null || true`;
michael@428 832 }
michael@428 833 if ($vcs ne '') {
michael@428 834 $info->{"vcs"} = $vcs;
michael@428 835 }
michael@428 836 if ($content_old ne '') {
michael@428 837 my $define = {};
michael@428 838 $content_old =~ s/\n\%define[ \t]+([^ \t\n]+)[ \t]+([^ \t\n]+)/$define->{$1} = $2, ''/sge;
michael@428 839 $content_old =~ s/\n([^ \t\n]+):[ \t]+([^ \t\n]+)/$define->{lc($1)} = $2, ''/sge;
michael@428 840 sub resolve {
michael@428 841 my ($define, $name) = @_;
michael@428 842 my $value = $define->{$name};
michael@428 843 $value = "" if (not defined $value);
michael@428 844 $value =~ s/\%\{(.+?)\}/resolve($define, $1)/sge;
michael@428 845 return $value;
michael@428 846 }
michael@428 847 $info->{"package-version-old"} = resolve($define, "version");
michael@428 848 $info->{"package-release-old"} = resolve($define, "release");
michael@428 849 }
michael@428 850 if (( $info->{"package-version-old"} eq ''
michael@428 851 or $info->{"package-release-old"} eq '')
michael@428 852 and $diff ne '' ) {
michael@428 853 if ($info->{"package-version-old"} eq '' and $diff =~ m/\n-Version:\s+(\S+)/s) {
michael@428 854 $info->{"package-version-old"} = $1;
michael@428 855 }
michael@428 856 if ($info->{"package-release-old"} eq '' and $diff =~ m/\n-Release:\s+(\S+)/s) {
michael@428 857 $info->{"package-release-old"} = $1;
michael@428 858 }
michael@428 859 }
michael@428 860 }
michael@428 861
michael@428 862 print STDOUT "-- determining commit message\n";
michael@428 863 $info->{"commit-message"} = ($lopts->{"m"} || "");
michael@428 864 if ($info->{"commit-message"} eq "") {
michael@428 865 if ($info->{"package-version-old"} ne $info->{"package-version"}) {
michael@428 866 # new version
michael@428 867 $info->{"commit-message"} = "upgrading package: " .
michael@428 868 $info->{"package-name"} . " " .
michael@428 869 $info->{"package-version-old"} . " -> " .
michael@428 870 $info->{"package-version"};
michael@428 871 }
michael@428 872 elsif (!$lopts->{"f"}) {
michael@428 873 print STDERR "openpkg:$prog_name:ERROR: package version not changed -- you have to manually provide a commit message\n";
michael@428 874 exit(1);
michael@428 875 }
michael@428 876 }
michael@428 877
michael@428 878 # run external command
michael@428 879 print STDOUT "\033[34m++ executing openpkg development release program\033[0m\n";
michael@428 880 $cmd .= " %{openpkg-prefix}";
michael@428 881 $cmd .= " %{spec-dir} %{source-dir} %{binary-rpm-file} %{source-rpm-file}";
michael@428 882 $cmd .= " %{package-name} %{package-version} %{package-release} %{package-version-old} %{package-release-old}";
michael@428 883 $cmd .= " %{commit-message} %{vcs}";
michael@428 884 $cmd .= " %{option-force}";
michael@428 885 $cmd =~ s/(\%\{([a-z][a-z-]+)\})/&subst($info, $1, $2)/sge;
michael@428 886 sub subst {
michael@428 887 my ($info, $text, $name) = @_;
michael@428 888 if (exists($info->{$name})) {
michael@428 889 $text = $info->{$name};
michael@428 890 $text =~ s/'/\\'/sg;
michael@428 891 $text = "'$text'";
michael@428 892 }
michael@428 893 }
michael@428 894 if ($lopts->{"n"}) {
michael@428 895 print STDOUT "-- DRY RUN:\n";
michael@428 896 print STDOUT "-- $cmd\n";
michael@428 897 $rc = 0;
michael@428 898 }
michael@428 899 else {
michael@428 900 $rc = system($cmd);
michael@428 901 }
michael@428 902
michael@428 903 return $rc;
michael@428 904 }
michael@428 905

mercurial