Moving Code

Here’s how I develop: I have an installation of a package or application in a subdirectory, ~/public_html/<package-name>, where I’m actually coding and testing. The app is in this place because PHP has an internal web server whose pages must reside here. I can code and test here using the PHP server, and easily see errors and server responses without involving the main Apache server. Plus, I can test here without affecting the main live instance of the package, which resides at /var/www/html/<package-name>. This is where I actually run the application for real world use.

But it’s always a pain to move revised code from the development instance to the live instance. There are some reasons for this. First, I may write a lot of one-off scripts to test various things. This takes place on the devel side, but I don’t want these to pollute the live site. Plus, my devel site will be cluttered with vim temporary swap files and other garbage that comes from coding. Second, most apps “ship” with no or a skeleton database, adequate for startup, but needing to be populated by the user. Because I use SQLite, this is a single file, so it could be copied from the devel site to the live site. But if I’ve been using the live code and populating the database, I don’t want the “stub” database to overwrite the live data on the live site. Third, there is the config file, which has default values, normally. If the live site config file has been modified, then I can’t copy the devel one over the top of the live one.

This has led to me trying to come up with a viable solution to moving code from devel to live. Obviously, I can’t simply copy files en masse. I could do a file compare for changed files, but this will pick up devel files which shouldn’t be copied, as noted above. So I need some sort of solution to copy only certain files. A file list. Theoretically, I could copy all these files over from devel to live, without worrying about whether they have changed in development or not. If they haven’t changed in devel, then I’m just copying the same content to the same content. Or better, avoiding the copy.

I can accomplish the above with a relatively simple shell script. Put a list of files in a “manifest” file, and use that file as a guide to what files to copy over. Simple, right?

Well, yes, it is. First step, build a MANIFEST file:

$ find . | sort | sed -e 's/.///g' > MANIFEST

This will capture every file in your devel directory. Now you must edit it. For example, you don’t want to copy your devel database over the top of your live one. Delete it. Any file which might interfere with the setup you have on the live side should be removed. Remove directories, which this command will insert. Carefully modify your MANIFEST file. When done, do the following:

$ cd my-devel-directory
$ rsync -urv --files-from=MANIFEST . $1

The $1 in this case is the target directory. This command will copy the files which are different between devel and live, and leave the rest alone.

That’s it. I’ve put these commands into script files run from my ~/bin directory. And I use them all the time.