I'm building yet another new toy in PHP (and no, I haven't finished the others...) and I ran into a familiar problem. I use ICDSoft for my hosting for appsCanadian, since when I bought the hosting I only intended to host this blog on it and I didn't need anything fancy or expensive. I just went with the cheapest option that had positive reviews. Now, I'm not knocking ICDSoft at all. In fact, they've been a perfectly good host, and they've been amazingly responsive to any and all inquiries I've had. However, being an economy host, I'm working on a shared server with no ssh access. This means that I have no ability to install Subversion, which is still my go-to version control system, largely since I've never bothered to use Git or Mercurial.

This presents a minor problem for me, since I really like developing on this server, for various reasons like the fact that my laptop is running Windows and I'm just paranoid enough to not want to develop on a different OS than I'll ultimately be deploying to. My reasons aren't that important, and if you're reading this it's likely that you have your own reasons for wanting to develop on some remote host you can't install things on or ssh into.

I've tried to find workarounds for this, and last time around I decided that I would just run Ubuntu in a virtual machine on my laptop. I found this to be a bit of a burden as I don't normally spend a lot of time using Linux, although I am relatively comfortable working with such a box, and I didn't like having to boot up a whole other machine just to make a quick change to my project. This time around, I decided to find a better way.

After a bit of brainstorming and a few searches on Google, I stumbled across WinSCP which is an open source (S)FTP/SCP client for Windows. The main feature that hooked me was the scripting features, which have commands for synchronization and directory monitoring. I've written a small script which will allow monitoring:

sync.txt
option batch on
option confirm off
open WINSCP_SESSION
option exclude .svn/
synchronize remote -delete "LOCAL_DIRECTORY" "REMOTE_DIRECTORY"
keepuptodate -delete "LOCAL_DIRECTORY" "REMOTE_DIRECTORY"

And I run pass this script to WinSCP from a Windows batch file:

sync.bat
"C:\Program Files\WinSCP\WinSCP.com" /command /script=sync.txt

The execution of this script is pretty straightforward. First we open a particular WinSCP session, defined in advance via the GUI, which contains credential information for your (S)FTP/SCP connection. Next, we do an initial synchronization of the remote directory with the contents of the local directory, opting also to delete any remote files which no longer exist locally. You can also replace the "remote" option with "local" to synchronize the other way around, or use "both" to do a two way sync moving the most recent files from each side to the other (note that the delete option obviously has no effect when synching both ways). Finally we use the keepuptodate command to tell WinSCP to monitor your local directory and push any changes up to your remote directory. Since the whole point of this exercise is to be able to develop remotely while still being able to checkout a working copy from svn locally, I've also used an exclusion option to tell WinSCP not to propogate any changes having to do with a .svn directory, since this is Subversions work area and it's never needed on the server.

With this script running, I can make any and all changes necessary to my project on the local files, and as I save these changes WinSCP will quietly send them to my server where I can see them immediately. I just have to be careful not to make any changes directly to the server, or I'll run the risk of having them overwritten by any local changes that get made.

One final caveat. There seems to be a known issue where a directory deletion made locally will NOT get propagated to the remote directory, though it seems its contents will be deleted without issue. It seems that because WinSCP has the directory open to monitor changes within it, Windows isn't able to complete the deletion until the monitoring process ends. Because the deletion isn't completed until the monitoring process ends, the completed deletion won't be noticed by WinSCP and will therefore not be applied to the server. It's a bit of a catch-22. I did make a bug report on the WinSCP forums, but the developer responded saying he's seen the issue before but is unsure how he can fix it. I'm therefore not going to hold my breath for a bug fix, but luckily there's an easy workaround. If you either need to recreate the directory locally (Windows won't allow its recreation until the deletion process of the original can be deleted, for obvious reason) or if the existence of the directory on the server is a problem, you can simply restart the batch script and the initial synchronization process will clean up for you.

Since WinSCP is open source, I would love to be able to contribute a fix to this, but the code is in C++ and a little lot above my ability. If anyone out there knows how to fix this issue, I'm sure a patch would be appreciated by the developer.

I hope that this information can help someone else who finds themselves in a similar situation to mine. If so, I'd love to hear from you if for no other reason than to convince myself that I'm not crazy for using such a setup.

Leave a Reply