#!/usr/bin/perl #!/usr/bin/perl -w # -*- Perl -*- # # rpmcvs.pl - convert SPEC file and sources between # RPM directory and CVS Repository. # # [Usage] # pkgcvs.pl <-c|--cvs> # Sources and patches copy into CVS repository from RPM Source directory. # pkgcvs.pl <-s|--source> # Sources and patches copy into RPM Source directory from CVS repository. # # # $Modified: Wed Jun 14 18:37:31 2000 $ use File::Basename; $SRCPOOL = 'pkgcvs:/work/srcpool'; $ENV{'SHELL'} = '/bin/sh'; my $dummyspec = sprintf("/tmp/dummy%s.spec", $$); ## Get SOURCES directory #### Phase. 1 Make temporary spec file. open (SPEC, "> $dummyspec"); print SPEC << "__END__"; %define name dummy %define ver 1.0 %define rel 1 %define prefix /usr Summary: This is dummy package to test RPM variables Name: %{name} Version: %{ver} Release: %{rel} Group: System Copyright: GPL Distribution: TurboLinux BuildRoot: /var/tmp/%{name}-%{ver}-root %description This is dummy package to test RPM variables #-------------------------------------------------- %prep echo "SOURCEDIR=\${RPM_SOURCE_DIR}" __END__ close(SPEC); open(SPEC, "rpm -bp $dummyspec 2>&1 |"); while() { if(/^SOURCEDIR=(\S+)\n$/) { $Config{'SourceDir'} = $1; } } close(SPEC); unlink $dummyspec; #use strict; ## Site configuration if(-r "$ENV{'HOME'}/.rpmcvsrc.pl") { unless (eval('require "$ENV{\'HOME\'}/.rpmcvsrc.pl"')) { print STDERR "Error: can't read ~/.rpmcvsrc.pl\n"; } } #$DEBUG = 1; $| = 1; #$VERSION = '0.01'; $USAGE = "Usage: $0 <-c|--cvs|-s|-source> \n". "Options:\n". " -c|--cvs\t (RPM SOURCE directory -> CVS Directory)\n". " Sources and patches copy into current directory\n". " from RPM Source directory.\n". " -s|--source\t (CVS Directory -> RPM SOURCE directory)\n". " Sources and patches copy into RPM Source directory\n". " from current directory.\n" . " -cp\n" . " Copy \"NoSource:\" and \"NoPatch:\" files using with ssh\n\n"; #print $USAGE; my @DistFiles; &ReadConfig; &ReadArgv; &ReadSpec; my(@TargerFile); if (defined $Mode) { if($Mode eq 'cvs') { &RPMtoCVS; } elsif ($Mode eq 'source') { &CVStoRPM; } } else { print "Option is not specified\n". $USAGE; } sub ReadConfig { # Read Configuration file. print "&ReadConfig\n" if $DEBUG; print 'Home dir: '. (getpwuid($>))[7]. "\n" if $DEBUG; my($configfile) = (getpwuid($>))[7]. '/.rpmcvs.pl'; if(-r $configfile) { eval "require $configfile" or die "Error: Syntax error your configuration file.\n"; } # Check each configuration item if(!$Config{'SourceDir'}) { die "\"SourceDir\" in configuration is not defined.\n"; } elsif (!-d $Config{'SourceDir'}) { die "\"$Config{'SourceDir'}\" (SourceDir) is not directory.\n"; } elsif (!-r $Config{'SourceDir'}) { die "\"$Config{'SourceDir'}\" (SourceDir) can't read.\n"; # } elsif (!-d $Config{'SpecDir'}) { # die "\"$Config{'SpecDir'}\" (SpecDir) is not directory.\n"; # } elsif (!-r $Config{'SpecDir'}) { # die "\"$Config{'SpecDir'}\" (SpecDir) can't read.\n"; } } sub ReadArgv { if ($DEBUG) { print "&ReadArgv:"; for(@ARGV) { print " ". $_; } print "\n"; } if(defined @ARGV) { for(@ARGV) { if($_ eq '-c' || $_ eq '-cvs') { die "Options are duplicated" if($Mode); $Mode = 'cvs'; } elsif ($_ eq '-s' || $_ eq '--source') { die "Options are duplicated" if($Mode); $Mode = 'source'; } elsif (-r $_) { die "SPEC file is duplicated" if($SpecFile); $SpecFile = $_; } elsif ($_ eq '-cp') { $CpNoSrc = 1; } else { die "Unknown option \"$_\".\n". $USAGE; } } return 1; } else { print(STDERR "Option is not specified.\n". $USAGE); exit; } if (!defined $Mode) { die "Option is not specified.\n". $USAGE; } elsif (!defined $SpecFile) { die "SPEC File is not specified.\n". $USAGE; } print "File=$SpecFile Mode=$Mode\n" if $DEBUG; } sub ReadSpec { print "&ReadSpec\n" if $DEBUG; # Read SPEC File print "Processing $SpecFile \n"; open(IN, $SpecFile) or die "Can't open $SpecFile (SPEC File).\n"; while() { if(/^\%define\s+(\S+)\s+(.+)\n$/) { $Defines{$1} = $2; printf("\%define %s %s\n", $1, $2) if $DEBUG; } elsif (/^\S+:/) { print "In preamble tag\n" if $DEBUG; s/^(\S+):/\L$1\E:/; s/\n$//; print " \"$_\"\n" if $DEBUG; # Name: tag if (/^name:\s+(\S+)/) { $Spec{'name'} = &convertdef($1); print "Name: $Spec{'name'}\n" if $DEBUG; $Defines{'name'} = $Spec{'name'}; $Defines{'Name'} = $Spec{'name'}; $Defines{'NAME'} = $Spec{'name'}; } # Version: tag elsif (/^version:\s+(\S+)/) { $Spec{'version'} = &convertdef($1); print "Version: $Spec{'version'}\n" if $DEBUG; $Defines{'version'} = $Spec{'version'}; $Defines{'Version'} = $Spec{'version'}; $Defines{'VERSION'} = $Spec{'version'}; $Defines{'PACKAGE_VERSION'} = $Spec{'version'}; } # Release: tag elsif (/^release:\s+(\S+)/) { $Spec{'release'} = &convertdef($1); print "Release: $Spec{'release'}\n" if $DEBUG; } # Serial: tag elsif (/^serial:\s+(\S+)/) { $Spec{'serial'} = &convertdef($1); print "Serial: $Spec{'serial'}\n" if $DEBUG; } # Distribution: tag elsif (/^distribution:\s+(.+)/) { $Spec{'distribution'} = &convertdef($1); print "Distrubution: $Spec{'distribution'}\n" if $DEBUG; } # Source0: tag elsif (/^source:\s+(\S+)/) { $Source[0] = &convertdef($1); print "Source: $Source[0]\n" if $DEBUG; } # Patch0: tag elsif (/^patch:\s+(\S+)/) { $Patch[0] = &convertdef($1); print "Patch0: $Patch[0]\n" if $DEBUG; } # Source(\d): tag elsif (/^source(\d+):\s*(\S+)/) { my($num, $content) = ($1, $2); $Source[$num] = &convertdef($content); } # Patch(\d): tag elsif (/^patch(\d+):\s*(\S+)/) { my($num, $content) = ($1, $2); $Patch[$num] = &convertdef($content); } # NoSource: tag elsif(/^nosource:\s*(\d+)/) { push(@NoSource, $1); } # NoPatch: tag elsif(/^nopatch:\s*(\d+)/) { push(@NoPatch, $1); } # If this line is defined section name. elsif(/^%description/ || /^%prep/ || /^%setup/ || /^%patch/ || /^%build/ || /^%install/ || /^%pre/ || /^%post/ || /^%preun/ || /^%postun/ || /^%fils/) { printf("%s section is appeared, go out &ReadSpec\n", $_) if $DEBUG; last; } elsif ($DEBUG) { print " - Procedure is no need in this line.\n"; } print "\n" if $DEBUG; } } close(IN); # divide NoSource and Source my($i); for($i = 0; $i <= $#Source; $i ++) { #push(@DistFiles, $Source[&RemoveDist($i, $Source[$i], @NoSource)]); #&RemoveNoSource($i, $Source[$i]); &DivideDist($i, $Source[$i], @NoSource); } # divide NoPatch for($i = 0; $i <= $#Patch; $i ++) { #push(@DistFiles, $Source[&RemoveDist($i, $Patch[$i], @NoPatch)]); &DivideDist($i, $Patch[$i], @NoPatch); } sub DivideDist { my($num, $content, @nodist) = @_; $content =~ s/.+\/(.+)/$1/g; for(@nodist) { if ($num == $_) { push(@DistFiles, $content); return; } } push(@TargetFile, $content); } sub convertdef { # replace %define my($target) = shift; my($name, $val); while(($name, $val) = each(%Defines)) { $target =~ s/\%$name/$val/g; $target =~ s/\%\{$name\}/$val/g; } return($target); } } sub RPMtoCVS { my($file); # Copy source and patch files foreach $file (@TargetFile) { next if((!$file) || ($file eq './')); print "Target file: $file\n" if $DEBUG; if (-r "$Config{'SourceDir'}/$file") { if (-f _) { print "Copying $Config{'SourceDir'}/$file to ./\n"; system("cp $Config{'SourceDir'}/$file ./"); } else { print "$Config{'SourceDir'}/$file is not a regular file.\n"; } } else { print "$Config{'SourceDir'}/$file is not found.\n"; } } # Copy nosource and nopatch files if($CpNoSrc) { my $scpfiles = ''; foreach $file (@DistFiles) { if($file ne '') { print "Copy $file to $SRCPOOL\n"; $scpfiles = sprintf ("%s %s/%s", $scpfiles, $Config{'SourceDir'}, $file); } } if($scpfiles ne '') { print "Execute: scp $scpfiles $SRCPOOL\n"; system("scp $scpfiles $SRCPOOL"); } } } sub CVStoRPM { my($file); # Copy source and patch files foreach $file (@TargetFile) { if (-r $file) { print ("Copy $file to $Config{'SourceDir'}\n"); system("cp ./$file $Config{'SourceDir'}/$file"); } else { print "$file is not found.\n"; } } # Copy nosource and nopatch files if($CpNoSrc) { my $scpfiles = ''; foreach $file (@DistFiles) { if ($file ne '') { print "Copy $file: to $Config{'SourceDir'}\n"; $scpfiles = sprintf("%s %s/%s", $scpfiles, $SRCPOOL, $file); } } if ($scpfiles ne '') { print "Executing: scp $scpfiles $Config{'SourceDir'}\n"; system("scp $scpfiles $Config{'SourceDir'}"); } } }