Programming is a wonderful mix of art and science; source code is both a poem and a math problem. It should be as simple and elegant as it is functional and fast. This blog is about that (along with whatever else I feel like writing about).

Tuesday, January 08, 2008

Flex: Automatically Compile and Deploy to Server

One thing that's been irking me a little bit about my Flex development process is that I have to upload the SWF to the server in order to test it. Normally you don't have to, but I'm using HTTPService to load XML from the server to populate the components. I really like that feature, but for security reasons, it doesn't allow cross-domain access.

One option is to put a crossdomain.xml file on my web server, but since I'd be testing from a local machine, I'd have to define the allowed domains as "*" ... which probably isn't the best idea. Also, I'm not that excited about hard-coding the domain name of my server into the application. (I currently have them just using absolute URL's, without the domain, ie "/server/api.php".)

Up until now, I've been uploading the file manually with scp after the compile successfully finishes. For that, I have to enter the compile command, check if it was successful, enter the upload command, type my password, and then I'm done. Figuring there must be a way to automate that, I learned that Flex works with Ant, which can do all these things (and allegedly supports FTP and SCP).

After setting up my build.xml file, I learned that Ant doesn't support FTP and SCP without some esoteric libraries ... which I didn't really feel like hunting down. I thought to myself ... "Why do I have to use Ant, when there must be a way to do this with roughly the same effort as this build.xml file, but that actually does the work?"

Enter Python.

#!/usr/bin/python

import commands
import pexpect

sourceFile = name of source file
outputFile = name of output file

username = remote username
password = remote password
serverAddress = remote server
remoteDir = path to destination folder on remote server

print "BUILDING..."
(compileStatus, compileOutput) = commands.getstatusoutput('mxmlc -file-specs ' + sourceFile + ' -output="' + outputFile + '"')

if (compileStatus > 0):
#the build failed, display the output
print "BUILD FAILED!"
print compileOutput
else:
#the build was successful, upload it
print compileOutput
print "UPLOADING..."
scpCommand = 'scp ' + outputFile + ' ' + username + '@' + serverAddress + ':' + remoteDir + '/' + outputFile

scp = pexpect.spawn(scpCommand)
scp.expect('Password:')
scp.sendline(password)
try:
scp.interact()
except:
print "(exception)"
finally:
print "Done!"

This script uses pexpect, which is a cool little program that lets you programmatically interact with the command line. This is necessary to enter your password into scp (which doesn't allow you to pass it into the command as a parameter, for obvious security reasons).

It's pretty simple. Basically, you compile using mxmlc, and if it was unsuccessful you display all the errors. If it worked ... you upload it to the server and you're done. Much easier than doing everything manually every time.

You have to set the constants in the file before executing, which isn't really a problem. I could make it so it takes parameters, but that almost defeats the point. I'm looking at this as a build.xml replacement, not as a full-bore program. So there shouldn't be a problem with setting some constants inside.

Enjoy the 3-5 seconds you'll repeatedly save! I know I have.

No comments: