in reply to Re: Looking to confirm a file against CVS as part of a loop
in thread Looking to confirm a file against CVS as part of a loop

The list that it's reading from is indeed trusted, so data security isn't an issue - But I'll try to use the more secure method as best practice.

I think I may have been a bit unclear - I already have a directory list that I'm reading in from a file, and for each entry in that list, I'm running a 'cvs co filename.xx' on it.

The list is generated by the end user, and will as such have files that aren't project specific in it. (Scratch files, ideas, temp files, etc).

What I'm looking to do is before I run the 'cvs co filename.xx', is to somehow check the 'cvs log filename.xx' command and capture the result of that, then have something along the lines of:

If: (CVS Log returns that the file is valid, version info, etc) - cvs co (the file).

Else: Print "That file's not in the tree, and Seventh asks too many silly questions on Perlmonks.org'.

Here's the whole script, what I'm looking to do is edit the read loop:
#!/usr/bin/perl -w # # Author: Chris Q # Date: 12/2004 # Desc: Common CR master util # # Key: [ ] - Not yet started # [%] - Partially complete, (known to be broken) # [!] - Complete, but undebugged # [X] - Complete # [?] - Thinking on it (don't know how yet) # [-] - Hell with it. # ToDo: # [ ] - Single character switches # [X] - Help Link # [X] - Empty Variable # # Bugs: # [ ] - # # Questions: # [ ] - use Getopt::Long; use strict; use Data::Dumper; use IO::File; my ($read,$generate,$help); # option switches GetOptions ( "help" => \$help, "read" => \$read, "generate" => \$generate, ); if (!$read && !$help && !$generate) { print "\nMissing Switch. Run with -help for options.\n"; } #################################### ## READ LOOP ## #################################### if ($read) { my $fh2 = new IO::File("; my $state2 = join("", @state2); foreach my $f (@state2) { print "File is $f\n"; # swap this with cvs co command `cvs co $f`; } } ################################### ## GEN LOOP ## ################################### if ($generate) { system ("clear"); print "Building project config.\n\n"; sub find { my ( $dir ) = @_; my $dh; my @theseFiles; + opendir $dh, $dir or return; while(my $file = readdir $dh ) { next if $file =~ /^\.{1,2}$/; my $full_file = "$dir/$file"; if ( -d $full_file ) { push(@theseFiles,find($full_file)); } else { push(@theseFiles,$full_file); } } closedir $dh; return @theseFiles; } my @files = find('.'); my @noCvsDirs; foreach my $file (@files) { push(@noCvsDirs,$file) unless(($file =~ /\/CVS\//) || ($file = +~ /\~/)); } my $state = join("\n",map { s{^\./}{}; $_} @noCvsDirs); my $fh = new IO::File(">ccrConfig.cfg"); die("Checkpoint failed for ccrConfig.cfg - $!\n") unless($fh); my $bytes = $fh->syswrite($state, length($state)); $fh->close(); unless($bytes == length($state)) { die("Checkpoint failed, incomplete write for ccrConfig.cfg\n") +; } else { print "Saved $bytes bytes into file: ccrConfig.cfg\n"; } exit; } ############################### ## Help Loop ## ############################### if ($help) { system ("clear"); print "Common Code Repository Utility v1.1\n\n"; print "|| ccrutil -generate ||\n\n"; print "Generates a project configuration file named\n"; print "ccrConfig.cfg to be included in your project.\n"; print "This file contains a list of all project files\n"; print "and related CCR includes, omitting temporary\n"; print "files and CVS control files.\n\n"; print "|| ccrutil -read ||\n\n"; print "Reads in a ccrConfig.cfg file from a project,\n"; print "and checks out any associated files.\n\n"; }
Does that make sense?

Thank you very much once again - I really appreciate the help and apologize in advance if I'm missing something blatantly obvious as a result of my inexperience. :)

Replies are listed 'Best First'.
Re^3: Looking to confirm a file against CVS as part of a loop
by revdiablo (Prior) on Dec 20, 2004 at 20:30 UTC
    Does that make sense?

    It makes perfect sense, and I understood the original question. I didn't want to give you the answer directly, though. I wanted to give you the tools to help get the answer on your own. If you're unsure how to use the tools I gave you, please ask, but I'm not going to do your work for you. :-)

    PS: As a hint, you are probably going to want to use one of the mothods I showed you to capture the output, then check if the output looks like a success or a failure. How exactly you do that is up to you.

      I appreciate it. :D

      Here's what I came up with:
      #################################### ## READ LOOP ## #################################### if ($read) { my $fh2 = new IO::File("<ccrConfig.cfg"); return unless($fh2); my @state2 = <$fh2>; my $state2 = join("", @state2); foreach my $f (@state2) { print "File is $f\n"; my $logoutput = qx(cvs log $f); if ($logoutput eq "RCS") { `cvs co $f`; else { print "File $f is not in CVS, skipping\n"; } } }

      Running a cvs log on any of the files in the list always starts with "RCS file: ...", so what I'm trying to do is:

      "If a cvs log of the file returns a string that starts with RCS, then check it out, otherwise print out that it's missing".

      And I'm getting this error currently:
      $ Global symbol "$logoutput" requires explicit package name at ccrutil +.pl line 5 6. Global symbol "$logoutput" requires explicit package name at ccrutil.p +l line 57. syntax error at ccrutil.pl line 59, near "else" syntax error at ccrutil.pl line 63, near "}" Execution of ccrutil.pl aborted due to compilation errors.
      I must be screwing up the syntax, but from what I can tell, isn't "$string = "text" the proper syntax for "contains"?

      Thank you very much once again.

        I am not sure what's causing the "Global symbol" error, but it's not in the code you've shown. The syntax error is because you forgot a curly bracket to end the if block.

        There is also a logic error, though. You are using eq to check for string equality, but this checks if one string matches another string exactly. So "hi" and "hi " would not match with eq.

        You probably want a pattern match, instead. This is covered nicely in perlretut, but here's a very quick example:

        foreach my $str ("one", "two", "three") { if ($str =~ /^t/) { print "'$str' starts with 't'\n"; } else { print "'$str' does not start with 't'\n"; } }
      Got it working - Thank you all very, very much for taking the time to help me out! =)