Compare local $VERSION with remote $VERSION and GET

What I like to do is:

a) determine where IDOC dir is under Perl locally
b) read all the files in that dir and parse the $VERSION
c) compare the local files $VERSION with remote files $VERSION
d) if the remote file $VERSION is greater then GET and save
in the IDOC dir replacing the local file with remote file using LWP.

Basically you can follow my logic below:

1) I would need some code to find where perl is installed
so that may lead me to finding where the Dir "IDOC" is located
that would work both on unix and win32 and than use readdir to
build a list of the file names along with $VERSION like this:

$directory = "$PerlDir";

$directory = $directory . "\/" unless ($directory =~ /\/$/);
opendir (DIR, $PerlDir);
@files = grep !/^\.\.?$/, readdir(DIR);
closedir (DIR);
foreach $file (@files) {

$VERSION = $1 if $line =~ m/^$VERSION.*?(\d+)$/;

# now somehow save the version with it's associated file name
# can I just append like this and split on the "\" later?:
$_ .= $VERSION . '|' . $file;


2) Ok, now if gotton this far and parsed local the file names
and version's under the Perl dir and saved I can now compare with
the files on a remote directory. I would then want to call LWP
Simple read the remote dir and parse for the $VERSION and $file

3) Somehow I would have to compare the local dir and remote dir parsed
$VERSIONS and determine if there is a remote $file to GET and save
with LWP.

Ok, this should give a clear vision of what I need to accomplish.

I know I could use CPAN and I have, but CPAN is really a dog for
continous updating of only a few ever changing modules and more
work then I care to expand and I need something really user novice
friendly and multi plat form. CPAN is fine for main distro's installs.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I think I can help but my only confusion is the IDOC thing...  I don't know that dir... I work in both Win32 and Unix and don't ever recall seeing it.  And right now on my Win32 machine I don'd find it...  But if your're talking about updating modules then why not run through the @INC array which will contain all default locations which the instalation of perl has been set up tp handle.  Then the only other issue is how to determine where to do the relative get for each file as the file names do repeat in different modules. (ex: carp and CGI::carp)...  If you can give some feed back I think I can help...
BiffoAuthor Commented:

IDOC is is something I create, it wouldn't be under your Perl, so just use LWP dir for this example since you would have that.

Oh yes @INC is the proper way for finding the defaults, yes you are correct there!
BiffoAuthor Commented:
<<Then the only other issue is how to determine where to do the relative get for each file as the file names do repeat in different modules. (ex: carp and CGI::carp)...  If you can give some feed back I think I can help...>>

Oooops I forgot to cover this ? of your's.....

Well I don't think repeating file names like your example there would be relevant. We would only look in a defined directory where defined files reside, we won't be looking outside the define directory for file names so I don't see how we can get into a file name confusion.

Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Ok give me a little time as this one seem a little tricky... the end of today or tomorrow.  Hope thats fast enough!
Ok were moving forward, but I got to a small sticking point.  To parse out the version number I need to know the format of the file names.  Generally module names do not carry there version number.  Are these custom modules...?  Can we be certain they will carry the version number in the name.  The version number is in the name of the tar of the module, but not the4 actual file .pm ... let me know...?
BiffoAuthor Commented:
Yes all have a $VERSION line in the format of $VERSION = '1.0';
Thats inside the file...?
Ok her we go...

First make sure to set the variables at the top of the file.  They are for you FTP host/login and to set the temp local and remote source dirs.  The if you are on windows!!!!! be careful I had one wierd things where it wouldn't let me delete a file.  If your on windows let me know and we'll se if it happens again.  Now the recusive dir search is not efficent but I didn't have that much time...  Maybe later we can improve it to be more efficent. Any way here you go:


use File::Find;
use Net::FTP;
use File::Copy;

$| = 1;

$debug = 1;

#Set a temp download dir
      #Windows - yes with reversed slashes!!!!!
      $temp_dir = "C:/temp/mods";

      #$temp_dir = "/tmp/mods";

mkdir("$temp_dir", 0777);

#Define host, user, pass, dir
$host = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$user = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$pass = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$dir = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

#Connect to host
$ftp = Net::FTP->new($host);

print "Connected\n" if $debug;

$ftp->login($user , $pass );

print "Logged In\n" if $debug;

#Change to dir

print "Dir Changed\n" if $debug;

$dir = $ftp->ls();

print "List Gotten\n" if $debug;

#foreach $line (@$dir)
#      print "Line: $line\n";

# get command line arguments, i.e. list of directories to start going thru
#@ARGV = qw(.) unless @ARGV;

# This will call sub rename_it for each file found, and will recurse
find(\&get_list, @INC);

sub get_list

# $_ now has the name of the "next" file in the current dir
# $File::Find::dir       has the name of the current dir
      if ($File::Find::dir =~ /IDOC/)
            $file = $_;
            print "Checking $file...\n" if $debug;

            #Open file to get Version number
            open(DATA,"./$file") || die "Can't open $file : $!\n";
            while (<DATA>)
                  #print "$_\n";
                  #Match line with version number and backtoken version number
                  if (/^$VERSION.*?(\d+);$/)
                        $Local_VERSION = $1;

                        print "Local Version of $file: $Local_VERSION\n" if $debug;
            print "Checking for remote copy of $file\n" if $debug;
            foreach $line (@$dir)
                  if ($line =~ /$file/)
                        print "Remote copy exists\n" if $debug;            

                        #Get Remote Mod
                        $mod = $ftp->get("$line", "$temp_dir/$line");
                        print "Remote copy downloaded\n" if $debug;

                        open(MOD, "$temp_dir/$line") || die "Can't open downloaded mod: $!";

                        while (<MOD>)
                              #Match line with version number and backtoken version number
                              if (/^\$VERSION.*?(\d+);$/)
                                    $Remote_VERSION = $1;

                                    print "Remote version of $file: $Remote_VERSION\n" if $debug;

                        if ($Remote_VERSION > $Local_VERSION)
                              print "Remote version newer\n" if $debug;
                              $num = unlink("$File::Find::dir/$file");
                              if (!($num))
                                    print "Error deleting $file\nFile could not be updated\n$!\n";
                                    #Move newer
                                    move("$temp_dir/$line", "./$line");
                                    print "Remote version has replaced local version\n\n" if $debug;

                        elsif ($Remote_VERSION < $Local_VERSION)
                              print "Local version newer and will be maintained\n\n" if $debug;
                              print "Local version is current\n\n" if $debug;


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BiffoAuthor Commented:
Works dang good, guadalupe. I gave you a slightly incorrect parse statement with getting the $VERSION, it should been:  

if (m/^\$VERSION.*?(\d.+)('|")/) {

One thing I know I will want to eventually have it do and really lost to how, and that is if there is a remote file found that is not found locally to save that remote file anyway as it would be a new addition. If you have an idea on that, send it my way for future addition to this fine script.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.