Perl Lib for WordPress Deployment

I’m super-pleased to have developed a master Perl script for deploying the new WordPress builds that get released every few weeks. It’s an enormous time-saver. It relieves me of the one time-trap chore I absolutely hated, which was FTP’ing the builds to each of my WordPress departments. Since some of this article is of general interest, and some is probably only interesting to Perl geeks, I’ll divide the article into General and Technical parts.

General Description

I have 10 WordPress departments (including a TEST directory), so a WP upgrade session was guaranteed good for an evening of work. Tonight, I just upgraded all 10 departments in 10 minutes, and 90% of the time was testing and checking the build and rebuilding the databases.

A full WordPress build is over 1000 files, dripping wet. Of these, only 80-200 files are generally “new” since the last build. My strategy has always been to upload only the changed files (except on major new releases). I still use the superb SuperFlexible file synch utility to determine what the changed files are. I save them off to a different DEPLOY directory.

I FTP these ONCE to a matching DEPLOY directory on my host server. I built a new test web page to handle 10 custom links to my Perl script, one link for each of the 10 WordPress directories on the server. Executing the script causes the server itself to do the file copies to the TO directories. This is how I save an enormous amount of FTP time and manual directory navigation.

Technical Description

Caution: use this information only if you are comfortable with scripting the web server with Perl scripts of moderate complexity, and know how to thoroughly test your work before going “live”. You can really trash your site files if you do this wrong.

I tried the standard File::Copy utilities. I tried embedded system commands. I never developed a reliable copy routine that could handle nested directories 10 deep. If a new folder didn’t exist on the TO side,  Perl would faithfully abort despite my best efforts to intercept the error and build the directory. The CPAN file copy module Recursive.pm solved all these problems. It effortlessly copies all the files and directories, even if new. If the file already exists on the OUT side, it is overwritten. If it does not exist, it is written. If a new directory is required here, it is built no matter how many levels deep it may be.

I am not going to upload the entire Perl script because some file paths are proprietary, and because if you aren’t comfortable throwing together and testing your own script based on my description, this is NOT the project to start copying hundreds of files into your HTML directories.

My approach is to first build read-only arrays of IN and OUT filepaths, and then execute the actual COPY routine, which I found on CPAN, and then to compare the pre-counts to the actual counts to make sure they are equal. I use an old subroutine ‘recursive’ (not to be confused with the CPAN module) to build the read-only arrays (bottom of article).

I call the CPAN dircopy routine with the statement

my($num_of_files_and_dirs,$num_of_dirs,$depth_traversed)
= dircopy($dirname,$dirname2);

If your server carries the CPAN module Recursive.pm (I use PerlDiver for this determination),  Include it in your script thusly:

use File::Copy::Recursive
qw(fcopy rcopy dircopy fmove rmove dirmove);

My server does NOT carry this module. You cannot invoke the dircopy command with just the FIle::Copy module most servers carry. I copied the File::Copy::Recursive module into a local lib of my own, but you then have to rename the package within the pm module – I could not get the package double-colon notation to work in my own lib.

declarations:

#package File::Copy::Recursive; #NO
package Recursive; #YES

And then, include it in your script thusly:

use lib '/home/yourdomain/www/cgi-bin/lib/';
use Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);
use strict; #yes, I recommend this for sure!

Documentation and Source

You can get the specs on the CPAN module here:

http://kobesearch.cpan.org/htdocs/File-Copy-Recursive/File/Copy/Recursive.html#dircopy

You can get the module and further CPAN description here:

http://search.cpan.org/~dmuey/File-Copy-Recursive-0.36/Recursive.pm

Setting Directories

My DEPLOY (IN) directory file path is the server path to wherever you choose a safe place to FTP your deployment files. Obviously, this can be a full deployment, or an incremental deployment as I usually do. The script and the Recursive package do NOT remove any files, either unchanged files, obsolete files or custom files you have added yourself.

I set my OUT directory arrays manually in the script so I can control program scope with hard-wiring. It is also easy to add elements. Obviously, the $server_www var is predefined to equal your own server path to your html directory:

$server_www = "/var/www/html";
$proddir[0] = $server_www."/wp_1astronomy/";
$proddir[1] = $server_www."/wp_1commentary/";
$proddir[2] = $server_www."/wp_1computers/";
$proddir[3] = $server_www."/wp_1laparola/";
$proddir[4] = $server_www."/wp_1miscellany/";
$proddir[5] = $server_www."/wp_1photo/";
$proddir[6] = $server_www."/TEST/WP/";
$proddir[7] = $server_www."/Whats_New/WP/";
$proddir[8] = $server_www."/WP/";
$proddir[9] = $server_www."/wp_1writing/";
$proddir[10] = $server_www."/TEST/WP-DEPLOY2/";

Program Output

I execute the file in a test mode first, remove the test parm, and then do the real thing. My code gives me the confirmation message such as the sample below. I have had no problems in a month of testing and usage.

outcount = 79

Number of files and dirs: 102
Number of files only: 79
Number of dirs only: 23
Depth level traversed: 23
SUCCESSFUL: Number of files IS EQUAL to inventory pre-count

sub recursive { #build dir list
 my $inpath = ""; my $outpath = "";
    system($command);
    foreach $file (<*>) { #glob notation p,393 CGI Programming
  chop  ($long_dir=`pwd`);
   unless (-d $file) {
    $inpath = $long_dir."/".$file;
   $outpath = $inpath;
   $outpath =~ s($dirname)($dirname2);
   {push @infile_array, $inpath };
   {push @outfile_array, $outpath };
    $incount++;
   } # end unless
  if (-d $file) {

   chdir $file;  
   &recursive(); 
   chdir "..";
  } # end if
   } # end foreach
  
} # end sub recursive

675 total views, 1 views today