openpkg/dev.pl

Mon, 28 Jan 2013 17:37:18 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 28 Jan 2013 17:37:18 +0100
changeset 758
a2c6460cfb16
permissions
-rw-r--r--

Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.

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