Some trouble with Build Automation

Hi – posting here because I’m running Xojo on a Mac, but it affects all platforms, I think.

I’m a (sometimes) lazy guy and there are too many small apps I have to update from time to time. Some automation might help and I decided to give it a try… But it’s a bag of hurts…

Is it just me, or is this whole “Build Automation” thing missing useful documentation?

The Framework-User-Guide says: “All the commands are listed in the Language Reference, but some useful ones include: DoCommand and DoShellCommand and Speak.” – have you ever searched the Language Reference for “DoShellCommand”? Try it. Nothing.

Here is my question…

What is the directory the DoShellCommand is fired in? The example from the docs “DoShellCommand(“codesign MyApplication.app”)” makes me think that it’s the folder where the built app is saved to – but I don’t think that is true.

According to this example, a DoShellCommand(“zip -r MyApplication.zip MyApplication.app”) should create a zip file containing the app package (works in terminal). But Xojo just throws an error 31 telling me that something went wrong during the build step.

And this is just the mac part. The windows and linux builds are saved in separate folders by Xojo – what’s the directory here? The folder where the exe is located or the parent folder?

I try to automate the ZIP-creation for all platforms to save some time. An external script might do the trick – but how to tell this external script which folder to use?

I agree that build automation is a huge time sink because it’s so fiddly. Regarding the documentation there should be something called “IDEScripting.pdf” in the documentation somewhere.

The shell is not Terminal! You need to use the full path for MyApplication.zip and likely for zip, too. You get the full path of the app with currentBuildLocation.

The full IDE Scripting docs are in User Guide Book 3: Framework, Chapter 9: Building Your Application, Sections 3 and 4.

You can also just grab that section as its own PDF:

http://documentation.xojo.com/index.php/Ide_scripting

OK… So… This should work, but i doesn’t.

Dim command as string command = "zip -r "+chr(34)+CurrentBuildLocation+"/MyApp.zip"+chr(34)+" "+chr(34)+currentBuildLocation+"/MyApp.app"+chr(34) DoShellCommand(command)

Because the build-path contains spaces, it’s necessary to some kind of escape the quotes.

DoShellCommand returns a string (which you must graciously accept, or you get an error) Also, according to the PDF currentBuildLocation is the shell path to the app that was built, so the spaces should already be escaped.
I also don’t think quotes are a normal thing in bash scripts.

dim result as string result = DoShellCommand("zip -r ~/Desktop/MyApp.zip " + currentBuildLocation)

You’re not going to like the zip structure once you open it (unacceptable for deployment) but hey, it works.

Hi Tim,

OK, that example works. But it’s useless because of the zip structure.

I think I’ll have to stay with the manual zipping of the files until the build automation becomes useable someday.

Escaping quotes and spaces…

There are two possible ways…

  1. DoShellCommand(“program ““filename with spaces”””)

  2. DoShellCommand(“program filename\ with\ spaces”)

The fun part: this automation works as long as I use a smart external app. Automating DMG Canvas works perfect which solves the Mac part.

Just for completeness:

I learned from this answer (http://stackoverflow.com/questions/13077241/execute-combine-multiple-linux-commands-in-one-line) that you can put multiple lines in one statement.
Since Zip paths are relative by default (http://stackoverflow.com/questions/7674143/shell-script-zip-archive-keep-folder-structure-mac-os-x) you need to do it all in one statement.

dim result as string result = DoShellCommand("cd " + currentBuildLocation + " && zip -r MyApp.zip test.app")

Hope this will help someone else. Now I’m able to make a build script that can zip my files (and use my naming convention).

You know, this is a fantastic idea.

Until now, I did not know how to do a CD in shell, since each shell being a different session, that would not not work.

The only way I knew how was to build a bash script and execute it. But that was a bit cumbersome.

Now with && as separator between commands I can do that directly.

Thank you :slight_smile:

http://askubuntu.com/questions/334994/which-one-is-better-using-or-to-execute-multiple-commands-in-one-line

you can also use others BUT && has a nice effect of testing the prior command so something like

foo && bar

behaves more like

if foo() then bar

[quote=255530:@Norman Palardy]http://askubuntu.com/questions/334994/which-one-is-better-using-or-to-execute-multiple-commands-in-one-line

you can also use others BUT && has a nice effect of testing the prior command so something like

foo && bar

behaves more like

if foo() then bar

That is real nice. I did not realise semicolon worked as well.

dim result as string result = DoShellCommand("cd " + currentBuildLocation + " && zip -r MyApp.zip test.app")

Ask Griffenberg: This is an excellent tip. Thanks.

One further optimization is to use the -y option to preserve the symlinks in the zip file so it doesn’t include multiple copies of the same data. Otherwise the decompressed app will be significantly larger than the original copy, and the zip archive will be larger than necessary.

zip -r -y MyApp.zip test.app

Without “zip -y” my 89MB app became 105MB after going in and out of the zip archive. With -y it’s the same size before and after.