Maintaining multiple Haxe versions

If you are working on multiple projects you may find that you need to be able to compile different projects with different versions of the haxe compiler.

After a little trial and error, here’s how I got it set up on OS X…

The Haxe binaries are here: http://haxe.org/file/

mkdir ~/bin
cd ~/bin
wget http://haxe.org/file/haxe-2.08-osx.tar.gz
wget http://haxe.org/file/haxe-2.09-osx.tar.gz
tar -xfvz haxe-2.08-osx.tar.gz
tar -xfvz haxe-2.09-osx.tar.gz

Next I edited my ~.profile and created the necessary environment vars.

export HAXEPATH=~/bin/haxe-2.09-osx
#export HAXEPATH=~/bin/haxe-2.08-osx
export PATH=$HAXEPATH:$PATH

export HAXE_LIBRARY_PATH=$HAXEPATH/std:.
export PATH=$HAXE_LIBRARY_PATH:$PATH

I also found that in my case it was necessary to change the default location of the haxelib repository after getting some odd behaviour from haxelib.
I think this was because I had manually deleted the default installation in /usr/lib/haxe , but then re-copied just the haxe libs back to /usr/lib/haxe/lib.
Anyway after changing the haxelib directory to somewhere in my user space the errors went away.

This is how to reconfigure the haxelib repository folder.

haxelib setup ~/dev/lib/haxe

So now if I need to compile with 2.08 I can edit my ~/.profile and uncomment

#export HAXEPATH=~/bin/haxe-2.09-osx
export HAXEPATH=~/bin/haxe-2.08-osx

(After editing ~/.profile you need to reload it with).

source ~/.profile

It would be nice if haxelib had a feature for managing multiple compiler versions just like libs.

Haxe unit testing with munit

We all love TDD – right ?

So you’re starting a Haxe project and you need to write some tests while you develop. Well, thanks to massiveinteractive there exists a very good unit testing library that works pretty much like flexunit.
It’s called munit and can be found here

Here’s my quick start guide:

For starters we want a top level project structure that looks something like this:
project structure
inside src we would place our package folder structure, inside test we would place the test package structure mirroring our src package structure.
expanded project structure

Now at a terminal we want to cd to our project folder and install munit if we don’t already have it.

$ haxelib install munit

Once installed we are ready to configure munit for our project.

$ haxelib run munit config

At which point we will enter an interactive configuration session that allows us to configure various folder locations…

Massive Unit - Copyright 2012 Massive Interactive. Version 0.9.2.3
Configure munit project settings
--------------------
test src dir (defaults to 'test') :
output build dir (defaults to 'build') :
report dir (defaults to 'report') :
target class paths (comma delimitered, defaults to 'src') : src
hxml file (defaults to 'test.hxml') :
resources dir (optional, defaults to 'null') : resources
templates dir (optional, defaults to 'null') :

I have used defaults for all but two of the settings: I have explictly defined the src folder, and also specified a resources folder. If your test folder or output locations are different then this is where you would configure them.

Once that is done you will find a .munit file has been created inside the top level project folder (where you ran haxelib run munit config).
The contents of the .munit file are pretty straight forward:

version=0.9.2.3
src=test
bin=build
report=report
hxml=test.hxml
classPaths=src
resources=resources

At this point you are ready to generate all the test files and the test.hxml that can be used to build and run the tests.

$ haxelib run munit gen

When we run this command our test folder will be scanned for all our test cases and the files required to run them are generated.

If we take a look at our project structure now we’ll see something like this
post test creation project structure

Note that 4 files have been generated for us: ExampleTest.hx, TestMain.hx, TestSuite.hx and test.hxml.
ExampleTest.hx can be deleted – but it serves as a useful quick reference for the correct metadata to use to when declaring test methods.

Here’s the source of ExampleTest.hx

/**
* Auto generated ExampleTest for MassiveUnit.
* This is an example test class can be used as a template for writing normal and async tests
* Refer to munit command line tool for more information (haxelib run munit)
*/
class ExampleTest
{
	private var timer:Timer;

	public function new()
	{

	}

	@BeforeClass
	public function beforeClass():Void
	{
	}

	@AfterClass
	public function afterClass():Void
	{
	}

	@Before
	public function setup():Void
	{
	}

	@After
	public function tearDown():Void
	{
	}

	@Test
	public function testExample():Void
	{
		Assert.isTrue(true);
	}

	@AsyncTest
	public function testAsyncExample(factory:AsyncFactory):Void
	{
		var handler:Dynamic = factory.createHandler(this, onTestAsyncExampleComplete, 300);
		timer = Timer.delay(handler, 200);
	}

	private function onTestAsyncExampleComplete():Void
	{
		Assert.isFalse(false);
	}

	/**
	* test that only runs when compiled with the -D testDebug flag
	*/
	@TestDebug
	public function testExampleThatOnlyRunsWithDebugFlag():Void
	{
		Assert.isTrue(true);
	}

}

We are now ready to run our tests with this command

haxelib run munit test test.hxml

And that’s all for now. (I did say this was quick start guide.)

Howto add user on archlinux

A very quick cheat sheet for getting a user setup quickly on archlinux-arm

Create a user called ‘myuser’ (obviously replace this with your desired username)

# useradd -m -g users -G \
audio,lp,optical,storage,video,wheel,games,power,scanner \
-s /bin/bash myuser

Set the password

# passwd myuser
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

Add to sudo users (Optional)

# visudo

If visudo does not exist then install with

# pacman -S sudo

Once vi launches use arrow key to scroll to the line:

# %wheel	ALL=(ALL) ALL

press ‘x’ twice to uncomment the line. Then exit vi (press ESC then “:” then “wq” then press ENTER).
Now change to your newly created user account

# su myuser

Now edit the .bashrc to get TAB completion working for the new user when using sudo.

$ nano ~/.bashrc

And add the following line at the bottom.

complete -cf sudo

Then do

$ source ~/.bashrc

to reload .bashrc

Neko on Archlinux-arm (ARMv5)

Today I decided to try getting Neko VM running on my Pogoplug (Pink)
Pogoplug (ARMv5)
Here’s how it worked…

Firstly I had to install development packages.

# pacman -S kernel-headers file base-devel abs

But that failed with some 404 errors:
failed retrieving file ‘xxx-arm.pkg.tar.xz’ from mirror.archlinuxarm.org : The requested URL returned error: 404

So I ran

# pacman -Syu

which synced everything after which I could proceed with installation of development packages

# pacman -S kernel-headers file base-devel abs

Once installed I had to grab the PKGBUILD files for Neko from here (The wget command below takes care of this)

You may also need to install subversion if it is not already install on your system

# pacman -S subversion

We’re now ready to build the Neko package.
From the Pogoplug terminal as non root user:

$ wget http://aur.archlinux.org/packages/ne/neko/neko.tar.gz
$ tar -xzvf neko.tar.gz
$ cd neko
$ sudo makepkg --asroot -Acs

The build takes quite some time and grabs any dependencies that it requires.
Once completed it generates a package called neko-1.8.2-7-arm.pkg.tar.xz package which can be installed doing

$ sudo pacman -U neko-1.8.2-7-arm.pkg.tar.xz

Once installed you can run Haxe code on a Pogoplug if you target Neko :-)
This bodes well for running Neko on RaspberryPi too, since there already exists an ArchlinuxArm distro for the RaspberryPi.

As a side experiment I wanted to see if Neko would build using the yaourt package management system.

$ sudo pacman -S yaourt
$ yaourt -AS neko

However this failed with a not very helpful error.

/bin/sh: line 1: 21293 Killed                  LD_LIBRARY_PATH=../bin: NEKOPATH=../boot:../bin ../bin/neko nekoml -nostd neko/Main.nml nekoml/Main.nml
make: *** [compiler] Error 137
==> ERROR: A failure occurred in build().
    Aborting...
==> ERROR: Makepkg was unable to build neko.

Anyway the first method did work, and maybe someone with more knowledge than myself might be able to get it working with yaourt.

Useful Links:
http://archlinuxarm.org/
http://archlinuxarm.org/platforms/armv5/pogoplug-v2-pinkgray
http://archlinuxarm.org/developers/building-packages
http://nekovm.org/
http://haxe.org/doc/targets/neko

Mount drives using serial number to name mapping with udev

I recently installed Arch Linux Arm v5 on my Pogoplug v2 and I wanted to configure the box to always mount the usb drives at the same mount points.

The solution was to create a udev rule and place it in /etc/udev/rules.d

here is the rule: /etc/udev/rules.d/15-usb-ext.rules

# This section defines the mapping of serial numbers to names
# To find serial numbers as seen by udev use udevadm
# e.g. udevadm info -a -n /dev/sdb

## WD 1
DRIVERS=="usb", ATTRS{serial}=="57442D57434153xxxxxxxxxx", NAME="WD-2TB-1"

## WD 2
DRIVERS=="usb", ATTRS{serial}=="574D415A413132xxxxxx", NAME="WD-2TB-2"

## WD 3
DRIVERS=="usb", ATTRS{serial}=="57442D57434155xxxxxxxxxxxxxx", NAME="WD-1TB"

# Start at sdb to avoid system harddrive.
KERNEL!="sd[b-z][0-9]", GOTO="media_by_label_auto_mount_end"

# Import FS infos
IMPORT{program}="/sbin/blkid -o udev -p %N"

#If we have picked up a name (defined above) then use it
NAME!= "", ENV{dir_name}="$name"
# otherwise use the kernel name (e.g. "sdb1" , "sdc1" , etc )
NAME=="", ENV{dir_name}="mnt-%k"
# Global mount options
ACTION=="add", ENV{mount_options}="relatime"
# Filesystem-specific mount options
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="$env{mount_options},utf8,gid=100,umask=002"

# Mount the device
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"

# Clean up after removal
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"

# Exit
LABEL="media_by_label_auto_mount_end"

I don’t really want to get into the details of writing udev rules, (this resource helped decipher how udev rules work.)
but here is a very brief outline of what’s going on here.

DRIVERS=="usb", ATTRS{serial}=="57442D57434153xxxxxxxxxx", NAME="WD-2TB-1"

The rule checks that the newly detected device is usb and has serial numer “57442D57434153xxxxxxxxxx”, if the rule matches then the name “WD-2TB-1″ is assigned to the device.
If no matching serial is found the rule defaults to using the kernel name of the device

NAME=="", ENV{dir_name}="mnt-%k"

man udev to find out all about %k , %n and $name (http://linux.die.net/man/8/udev)

It’s important to note that after saving a rule, the rule is applied the next time a device is picked up by the system. Unplugging and then replugging the drives will cause them to be detected and the udev rule to be applied.

At this point I could edit my /etc/samba/smb.conf and add shares for my drives that will now always be found at the same mount points

[extra]
  path = /media/WD-2TB-1/
  read only = no
  public = yes
  writable = yes
  force user = root

[media]
  path = /media/WD-2TB-2/
  read only = no
  public = yes
  writable = yes
  force user = root

[bkup]
  path = /media/WD-1TB/
  read only = no
  public = yes
  writable = yes
  force user = root

Then restart samba with

rc.d restart samba

Bon appetit.

SHA1 Lookup In Nexus Repository

If you have a maven artifact on disk somewhere and for some reason you want to check that it exists in a particular repository and find out what version of the artifact it is, then this script might be useful.

#!/bin/bash
target=$1
NEXUS_BASE_URL='http://localhost:8081/nexus/'
NRA_SEG='service/local/data_index?sha1='

chksum=`openssl dgst -r -sha1 ${target}`

url=$NEXUS_BASE_URL$NRA_SEG"${chksum:0:40}"
result=`curl -s ${url}`
count=`echo ${result} | sed 's/.*[^<]<totalCount>(.*[^<])</totalCount>.*/1/'`
if [ $count -gt 0 ];then
	version=`echo ${result} | sed 's/.*[^<]<version>(.*[^<])</version>.*/1/'`
	echo "${target} -> ${version}"
fi

Another script that will run the above script for each file in a directory

#!/bin/bash

dir=$1
files=$dir/*

shopt -s nullglob
for f in $files
do
        if [ ! -d $f ]; then
                ./getver.sh $f
        fi
done

These could be adapted quite easily to return full GAV coordinates.

Introducing Topshot

I have recently released a small Flex library for doing screen grabs in Flex apps called topshot-lib.

The purpose was to provide a small tool in a large app I have been working on where I just wanted a quick way to grab snippets of screens for sending over to the designers or other devs for showing ui bugs etc. Sometimes you’re on a machine where there is no easy way to do a screen grab (like windows) with no decent screen grab software installed, this tool can sit in the dev version of the app…

…anyway it’s pretty straight forward – you just press the mouse and start selecting the area you want to snap – when you release the mouse you will have 2 options – one to cancel, one to save.

That’s it.
topshot-select
topshot-save

The image – for those who are interested – is the smoldering Jane Russell from “The Outlaw”

Thinner Component Framework – Reflex.

After my last post about the “Flexless” MXML Preloader, I took a look at Reflex.

… and one of the first things I noticed was that this branch of Reflex has an MXML Preloader like the one I described here – except the Reflex one has bells and whistles and it loads RSLs . . . it’s looking very promising.

Until now all my “Flexless” MXML experiments had been based on top of Skinnable Minimal Components and my own FXG vector skinning library.
I must say that my first impressions of looking over the Reflex code are really good – it seems exactly where I was trying to take my experiments but I’m now thinking it’s probably going to be better to work on top of the Reflex base.

On the subject of Reflex and routes to thinner component frameworks – this is an excellent post

Embedded Monospace and Fixed-width Fonts with TLF and FTE

Just a quick post about this ‘gotcha’ I encountered last night. (Which nearly drove me crazy).

When embedding a monospace font in Flex 4, be careful with character filtering.

Initially I was doing this..

@font-face {
	src: url("assets/fonts/VeraMono.ttf");
	fontFamily: VeraMono;
	fontStyle: normal;
	fontWeight: normal;
	advancedAntiAliasing: true;
	cff:true;
	unicodeRange:
		U+0041-005A, /* Upper-Case [A..Z] */
		U+0061-007A, /* Lower-Case a-z */
		U+0030-0034, /* Numbers [0..4] */
		U+002E-002E; /* Period [.] */
}

But this was bad. When typing into a RichEditableText component the characters were not spacing themselves correctly.
Basically the un-embedded characters were displaying but their widths were not fixed “!” , “)” would be very narrow and “@” would be too wide. I’m guessing that FTE or TLF finds fallback characters – possibly using the system font and lays them out differently to the characters in the embedded font, anyway. Simple fix, just don’t filter the character range.

@font-face {
	src: url("assets/fonts/VeraMono.ttf");
	fontFamily: VeraMono;
	fontStyle: normal;
	fontWeight: normal;
	advancedAntiAliasing: true;
	cff:true;
}

Removing the unicodeRange fixed my widths and restored my sanity.