One thing I was missing when I started to develop PHP applications with eclipse was the ability to upload files to my webhoster via FTP(S). I started looking around and tried various eclipse-solutions (Remote System Explorer (RSE), Aptana, Ant) as well as other IDEs (NetBeans, Dev-PHP, PSPad, …), but none satisfied me.
There are two key features which are critical to me:
- The possibility to map different local folders to different remote folders. This is important because I want some files to reside outside the servers document root.
- The upload shall be triggered automatically whenever a change is saved, but only new or changed files shall be uploaded (and removed ones deleted).
Additionally, I prefer using FTPS (FTP-SSL) over using FTP. As I could not find what I was looking for (at least not for free), I started scripting my own solution. And finally, here it is:
Download: eclipse-winscp-upload-script.zip
In this archive you will find five files:
- build.xml is an Ant-buildfile that is used to easily create a new builder for a project. It also takes care of passing the lists of added/changed/removed files and directories to build.js.
- build.properties is a property file that needs to be added to the builders launch configuration to make eclipse variables (affected files/directories and the projects file system path) available to build.xml.
- build.js is a Microsoft JScript script that controls WinSCP to replicate the local changes on a FTP/FTPS/SFTP/SCP-Server according to the passed values and some additional settings configured within the script itself.
- build-notmin.js contains the same script as build.js, but is not minified. Use this file if you want to have a look at the code or change the script.
- gpl-3.0.txt is a copy of the GNU GENERAL PUBLIC LICENSE version 3, under which this script is released.
Quick setup
This is a quick setup guide to get you started with the script. For questions pleas use the comments on this website.
- Within your project, create a new folder (lets say winscp_sync) and copy build.xml, build.properties and build.js to it. It is important to have a separate folder for these files, as during execution some additional temporary files might be created.
- You need to either install WinSCP or get a copy of WinSCP.com and WinSCP.exe from the portable executables package. If you choose the latter, you can put them into your winscp_sync directory. (WinSCP download page)
- Open build.js and set at least winscp_com, winscp_open_arguments and dir_assignment variables.
- In the projects properties, add a new Ant Builder with the following configuration:
— On the „Main“-tab: —
Buildfile: ${workspace_loc:/project_name/winscp_sync/build.xml}
Base Directory: ${workspace_loc:/project_name/winscp_sync}
Uncheck „Set an Input handler“
— On the „Targets“-tab: —
Add „autobuild“-target to the Auto Build section (but uncheck synchronize for Auto Build!). Leave the rest as preconfigured.
— On the „Properties“-tab: —
Uncheck „Use global properties as specified in the Ant runtime preferences“
Add the build.properties file in winscp_sync to the Property files section
— On the „Build Options“-tab: —
Check „Allocate Console“
Check „Specify working set of relevant resources“ and add the folders you specified in the dir_assignment variable (in build.js) to the working set. - If not already selected, activate „Build Automatically“ in the „Project“-menu (in eclipses main menu).
- Finally, do a „Clean…“ on the project. This is also in the „Project“-menu.
Hi.
Can You explain exactly „dir_assignment“ in JS file?
If I have my project in folder:
H:\PHP Eclipse WinSCP\workspace\MY_PROJECT
and absolute path at FTP server is:
/public_html/MY_PROJECT
…what should I put into array:
var dir_assignment = [
[„\\“,“/files/project“],
[„\\htdocs“,“/htdocs/project“]
];
???
Thank You.
I see my explanation in the .js-file is a bit confusing…
If you followed the „Quick setup“ you should already have a winscp_sync folder in your local MY_PROJECT folder. First of all, you need one or more subfolders in your MY_PROJECT folder, which will be the actual folders to be synchronized to ftp (possibly to different remote locations). Let’s say you create one folder called H:\PHP Eclipse WinSCP\workspace\MY_PROJECT\homepage. Now if you want the content of this homepage-folder to be synchronized to /public_html/MY_PROJECT, you need the following dir_assignment:
var dir_assignment = [
["\\homepage","/public_html/MY_PROJECT"]
];
Remember to add H:\PHP Eclipse WinSCP\workspace\MY_PROJECT\homepage to the folder-list under „Specify working set of relevant resources“ in the Ant Builder’s configuration (see „Quick setup“).
It is important that the folder containing the build.js-script is not within a directory which is synchronized. Or, more specific, the folder containing build.js must not be within a folder configured as relevant recource in the Ant Builder’s configuration. This is because sometimes build.js creates temporary files, which could lead to an infinite loop by build.js triggering itself.
Thanks, it works! 🙂
BTW Don’t You think about install separetly WinSCP, run it and set option for synchronize folders and files „Keep Remote Directory up to Date“.
Explanation:
http://winscp.net/eng/docs/task_keep_up_to_date
Well, actually WinSCP’s own sync-feature was the reason I stumbled upon WinSCP in the first place. But it has several shortcomings:
– (Until now) it’s not possible to configure the „Keep remote directory up to date“-function via command-line options. So if you want to use it, you have to manually configure it each time you start developing. If my script is set up correctly once, it’s ready to go whenever you start eclipse.
– It’s not easily possible to configure different remote locations for different local folders. You’d have to start several instances of WinSCP and configure each one everytime you start developing if you wanted to do that. With my script, you can specify multiple local-remote-directory-assignments, even nested ones.
– When a file or directory is moved or renamed, WinSCP’s „Keep remote directory up to date“-function will remove and re-upload that file or directory. My script recognizes such changes and moves/renames the file/directory on the server without re-uploading it.
I have set everything up and although it looks like it is working it does not. In the console I get the following message when autobuild is executed:
Buildfile: C:\Users\myname\workspace\PROJ\winscp_sync\build.xml
check-commandline-usage:
autobuild-commandline:
[exec] Starting WinSCP…
[exec] C:\Users\myname\workspace\PROJ\winscp_sync\build.js(170, 5226) WshShell.Exec: The system cannot find the file specified.
autobuild-file:
autobuild:
BUILD SUCCESSFUL
Total time: 923 milliseconds
I added C:\Users\myname\workspace\PROJ\winscp_sync to my PATH variable as well and restarted everything. Still same error. I checked and cscript executes from that folder just fine:
C:\Users\myname\workspace\PROJ\winscp_sync>cscript
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Usage: CScript scriptname.extension [option…] [arguments…]
….
Here is the folder structure for reference as well:
C:\Users\myname\workspace\PROJ\winscp_sync>dir
Directory of C:\Users\myname\workspace\PROJ\winscp_sync
02/27/2013 10:31 AM .
02/27/2013 10:31 AM ..
02/27/2013 09:46 AM 13,089 build.js
05/05/2012 12:40 PM 202 build.properties
02/27/2013 09:37 AM 3,310 build.xml
02/18/2013 10:54 PM 293,272 WinSCP.com
02/18/2013 10:54 PM 9,200,984 WinSCP.exe
02/27/2013 10:05 AM 11,916 WinSCP.ini
6 File(s) 9,522,773 bytes
2 Dir(s) 42,475,954,176 bytes free
Any ideas?
Thanks,
Keith
Thanks for this great blog entry!
For some reason I can get the „full sync“ working but the autobuild option does not…
Any suggestions? I’m using the latest Eclipse Kepler and latest WinSCP.
I don’t have enough knowledge on javascript and cscript to debug this any deeper…
With autobuild it connects and console says:
…
[exec] transfer binary
and then just
[exec] WinSCP finished without errors.
So it does not give any info to console if it is trying to upload anything…
The script works fine, but with one exception. Whenever I copy a PDF to Eclipse a directory will be generated remotely. I simply added an if for sorting out PDF.