Portable Version Control

I've mentioned previously that I'm version controlling my work using distributed version control software - specifically Bazaar. I explained that part of the reason I'm doing this is because I work at a number of different locations, and I need to be able to manage various different versions of my work and keep them all in sync.
One of the locations I work at is a Laptop provided by my sponsor. Unfortunately their corporate system does not allow the installation of unauthorised software and Bazaar is not on their approved list. I did briefly look into using subversion (as it was used elsewhere in the company and linking between this and Bazaar is possible) however it looked like it was going to be too much hassle to justify getting it installed. I've therefore decided to attempt to run my version control purely from my flash memory. This will not only allow me to version control my work on my sponsors laptop, but also on any other machine I decide to use.

Incidentally it's worth mentioning that I'm storing all my work on the flash memory (micro-sd) card of my phone. I upgraded to an 8 Gb card which should be plenty (at least initially). I always carry my phone anyway  so all I need to retrieve my work at any time or location is a USB cable (or bluetooth if I'm desperate!). I don't treat this as a working copy, but I backup to it regularly and use it to transfer versions between machines. In version control terminology this means I have a 'branch' on each machine I work at and another 'branch' on my phone. I 'push' or 'pull' changes between the phone branch and the local copy branch to backup/transfer the work.

Bazaar is coded using the Python programming language. This is a pretty modern and, by most accounts, a pretty handy programming language; however it's not something that I'm particularly familiar with. The main benefit to me is that there is a variant of it available called Portable Python which is designed to run from a USB storage device (like my phone). This means that it is possible for me to install Portable Python on my phone, and then run Bazaar from that.

I was quite surprised not to be able to find any instructions for this setup on the net anywhere, as it seems like quite a handy proposition (certainly for someone in my situation). The only references that I could find to it were suggestions of using it here, and here. I'm far from an expert on this type of thing but I've sort of got it working - so I thought I'd publish the steps I took incase anyone has any feedback, or it is of use to someone else.

Unfortunately portable python is only windows based; however this is where I'm most likely to need it. (there's also a chance that it will work under linux through wine, but I haven't really experimented with that yet.)

Python Installation
The current version of Python is 3.2, however I don't think any of the Bazaar source is built on that version, so I went with 2.6 (I'm not sure if I could have gotten away with a newer version or not?). I downloaded Portable Python from here and copied it to a "python" folder on my phone. I then ran the installer and told it to install to the same folder on the phone.

Bazaar Installation
I tried installing Bazaar from some executables, unfortunately these complained that it needed python 2.6 in the registry, and gave me no option for manually specifying a python path. So instead I downloaded a tarball of the Bazaar source from here which I extracted to the Python "App" directory. I then opened a command prompt, navigated to the python "App" directory, and ran:
python bzr-2.4b3\setup.py install
(actually I was still using Linux at this point and instead ran SPE-Portable.exe under wine and then ran setup.py through that - I'm pretty sure it had the same effect though)
This ran for a while and terminated without any errors. Within the bazaar directory a "build" folder had now appeared.

From the command prompt I was then able to run :
python bzr-2.4b3\bzr status C:\test
where C:\test was a directory under version control. This gave the correct response, but it also gave me this warning that some extensions couldn't be loaded. I don't think this is a problem, so I ignored it (the link gives a method for turning off the warning if you're bothered about it).

Bazaar Explorer Installation
I wasn't keen on typing everything through the command line, so I looked into getting bazaar explorer running. The official instructions for this are here.
So I changed to the plugins directory of bazaar:
cd F:\python\PortablePython_1.1_py2.6.1\App\bzr-2.4b3\bzrlib\plugins

and ran bzr with the command to download from launchpad:
F:\python\PortablePython_1.1_py2.6.1\App\python F:\python\PortablePython_1.1_py2.6.1\App\bzr-2.4b3\bzr branch lp:bzr-explorer explorer
This warned me that I hadn't given a launchpad ID, but I don't think that matters as I'm not intending on writing anything back to launchpad. Then it went about downloading and building explorer. This process took a little while.

I then tried to run it, but there were a few dependencies that needed fulfilling. Firstly it told me I needed QBzr. So, still in the plugins directory, I ran:
F:\python\PortablePython_1.1_py2.6.1\App\python F:\python\PortablePython_1.1_py2.6.1\App\bzr-2.4b3\bzr branch lp:qbzr
this then went through the same process as with explorer.

On the next try it requested qt libraries (ERROR: No modeule names PyQt4). Some googling reveals this, which suggests installing it in a "non-portable" install and then copying selected files across. (I did try a proper install before this but got nowhere*). I downloaded "PyQt-Py2.6-gpl-4.5.4-1.exe" from here, and installed to C:\Python26. This created a folder in C:\Python26\Lib called "site-packages", I copied the contents of this to the Lib\site-packages folder of my portable python install.

I then tried running:
python bzr-2.4b3\bzr explorer
and up it popped!

Unfortunately a lot of the buttons bring up a deprecation warning for commands in plugins\explorer\lib\app_suite.py. This is something I haven't been able to fix yet. My guess is that it's due to a new version of explorer being used with an older version of Bazaar, but that's just a guess. If anyone can help with it then I'd love to hear from you!
It's still useful as a GUI for inspecting the changes and looking at differences; however any major commands need to be made from the command prompt.

Also this all took a while working from the phone flash card, next time I might consider doing it locally on the hard drive and then copying it across.

Please let me know if you know of any better methods for getting this working, or where I've gone wrong with getting explorer working. Hope this is of interest to someone.
I've also just come across another (easier looking) solution here.

* The copying method sounded like it might be a bit flaky, and I saw some sites indicating that it could be done in a more "conventional" manner, so I got the files for it from here. I also needed "SIP" (I tried it without but it said no). SIP can be obtained from the same place here, and extracted to the python/App directory. I then changed to the python directory and ran:
python sip-4.12.3\configure.py
after this had created a sip module Makefile it errored with unable to open siplib\siplib.sbf - not sure what this means, so I then tried:
python PyQt-win-gpl-4.8.4\configure.py
this said: "make sure you have a working qt v4 qmake on your path". I was a bit lost then so I gave up and tried the technique of copying across!


Simulink to eps

I've mentioned previously that I've developed a process to export plots from Matlab and include them as (eps format) figures in a Latex document. Well today I spent a load of time trying to get a similar method working for exporting Simulink model diagrams from Matlab. This hasn't proved quite as easy, but I think I'm there now.

My main issue was that Simulink doesn't allow you to print in the same way as a normal Matlab figure does. The "print" command can be used, but it works in a very specific way. It is fairly easy to use this command to print in eps format (see my previous posting for why this is a good thing); however it doesn't allow you the same freedom to setup the page. More specifically it will only allow you to use a pre-defined page size (A4, US legal, etc). It rescales and centres the figure to fill the page, but, unless the model is the exact same aspect ratio as a pre-set paper type, you end up with white borders at either the top/bottom or left/right.

EDIT: This seems to have been corrected in newer versions of Matlab now!

I've tried all sorts to get round this, including calling Ghostscript from within matlab to post-process the eps file. This should work as it ought to be able to find the right "bounding-box" for the figure and resize the page accordingly. However I had no luck with this - it would either not trim it down at all, or over-trim it removing some of the image.

I also tried exporting in a few other formats (namely normal postscript and pdf) and then converting with Ghostscript. This worked a little better and I was able to get the right bounding box through a process of:
  1. Simulink export to pdf, 
  2. Ghostscript convert pdf-to-eps, 
  3. Ghostscript convert eps-to-eps. 
I have no idea why that last step was necessary! Unfortunately although the output from this was pretty good, the text becomes part of the image (I think during the second step), meaning it doesn't render properly at high zoom levels. I don't know why that happened, I'm pretty sure it shouldn't have, but I thought I could do better.

So an alternative process I finally came up with is:
  1. Find out the ratio of the figure (I did this by exporting as a raster image and then reading back in - I'm not very happy with this technique as it's pretty dirty, but at least it works)
  2. Simulink export to eps, with the model at the very bottom of the page
  3. Automatically edit the resulting eps file to adjust its bounding box information
It's a bit hacky, and if I was being picky the margins aren't perfectly even in the resulting file, but it seems to work. I'm sure there must also be a better way of achieving step 1, but it's sufficient for now. (If anyone has any suggestions then I'd love to hear them!?)

There's nothing very clever in the code, but if anyone wants a copy of my function I'll happily forward it to them. Hope this helps somebody!

EDIT: Code for my function is available here.