Thursday, 24 November 2011

PGMidi moved and updated

My popular PGMidi library for MIDI input/output on iOS has moved from Gitorious to a new location on GitHub. (This was requested many times, and who am I to disappoint?)

Please update your repos accordingly.

Over the next few days, I'll also be adding a few new tweaks and features to the project, so stay tuned.

Thanks for all the kind comments and feedback about the code - I'm really glad it's useful. Please do let me know if you've incorporated it in your own project.

Wednesday, 23 November 2011

Writing: How To Pick Your Programming Language

The November issue of ACCU's C Vu magazine is out now. It contains the latest instalment in my Becoming a Better Programmer column. This one's called How To Pick Your Programming Language.

It's a masterwork that uses ancient dark arts (and frivolous flow chart technology) to help you select the programming language that best suits you.

Best read with a pinch of salt!

I quite like the artwork I produced for this month's cover, and have finally remembered to align the {cvu} drop shadow correctly, something that's been bugging me for months. (I doubt anyone else would even have noticed it)

Wednesday, 16 November 2011

Xcode 4 keyboard/mouse shortcuts

(I'm posting this here mostly so I don't lose it, although I'm sure it'll be useful to other Xcode 4 users out there.)

There are a couple of really handy Xcode mouse click modifier key combinations that I can never remember when I want them (kind of like a Super Street Fighter key combo).

In particular, you can click on symbols in the code editor and have them open in this editor, in the alt editor, in a new window, or... even... with a (ugly looking) popup asking you where to open (e.g. in a new tab).

Here's the lowdown:


Xcode 4 editor symbol clicks

Modifiers Click What happens
⌘⎇^ + single Open in alt editor
⌘⎇⇧ + single Select where to open (with popup)

+ single Open in this editor
+ double Open in this new editor window
+ single Show help popup
+ double Show help in organiser

⌘⎇⇧ Make alt editor counterpart again (super useful)

Key (what the silly symbols mean) 
Command (cmd)
Option (alt)
^ Control (ctrl)
Shift

Friday, 11 November 2011

It's the thought that accounts




Thinking well is wise; planning well, wiser; doing well, wisest and best of all.
– Persian Proverb


I run. Every week. It's my waistline, you see. Perhaps it's a guilt thing, but I do feel I need to do something to keep it under control.  

Now, let's be clear: I'm no masochist. Exercise is not my favourite thing in the world. Far from it. It definitely ranks above hot pokers being stuck in my eyes. Marginally. But there are plenty of things I'd rather do with my evenings. Many of them involve sitting down, preferably with a glass of wine.


But I know that I should run. It's good for me.


Is that fact alone enough to ensure I go regularly, every week, for the full distance? With no slacking or slowing of the pace?


It is not.


I dislike exercise and would gladly employ the weakest of excuses to get out of a run. “Oh no, my running shorts have a loose thread.” “Oh no, I have a runny nose.” “Oh no, I'm a bit tired.” “Oh no, my leg has fallen off."


(Ok, some excuses are better than others.)


What unseen force coaxes me to continue running regularly when guilt alone can't drag me out the door? What magical power leads me on where willpower fails?


Accountability.


I run with a friend. That person knows when I'm slacking, and encourages me out of the house even when I don't fancy it. They turn up at the door, as we'd arranged before my lethargy set in. I perform the same kind of service back. I’ve lost count of the times that I wouldn't have run, or would have given up half-way round had I not had someone there, watching me and running alongside me.


And, as a by-product we enjoy the run more for the company and shared experience.


Sometimes we both don't feel like going on the run. Even if we admit it to each other, we won't let the other person off the hook. We encourage each other to push through the pain. And, once we've run, we're always glad we did it, even if it didn't feel like a great idea at the time.

Stretch the metaphor

Some metaphors are tenuous literary devices, written to entertain, or for use as contrived segues. Some are so oblique as to be distracting, or form such a bad parallel as to be downright misleading.
However, I believe this picture of accountability is directly relevant to the quality of our code.

For all the good it does technical writers, speakers, and code prophets like myself to talk about producing good, well-crafted code, and as much as the luminaries like Uncle Bob Martin extol the (genuine) virtues of “clean” code, and Fowler explains why we need well-factored code, it matters not one jot if, in the heat of the workplace, we can't put it into practice. If the harsh realities of the codeface cause us to shed our development morals and resort to hacking at code like uninformed idiots, what have we achieved?

We can complain about the poor state of our codebases, but who can we look at to blame?

We need to bake into our development regimen ways to avoid the temptation for shortcuts, bodges and quick-fixes. We need something to lure us out of the trap of thoughtless design, sloppy, easy solutions and half-baked practices. The kind of thing that costs us effort to do, but that in retrospect we're always glad we have done.

The spirit is willing, but when the deadline looms, all too often the flesh is weak.

How do you think we'll achieve this?

Accountability counts

I know that in my career to date, the single most import thing that has encouraged me to work to the best of my abilities has been accountability, to a team of great programmers.


It's the other coders that make me look good. It's those other coders that have made me a better programmer.

Being accountable to other programmers for the quality of your work will dramatically improve the quality of your coding.

That is a single simple, but powerful idea.

Code++

To ensure you're crafting excellent code, you need people who are checking it every step of the way. People who will make sure you're working to the best of your ability, and are keeping up to the quality standard of the project/team you're working on.

This needn't be some bureaucratic big-brother process, or a regimented personal development plan that feeds back directly into your salary. In fact, it had better not be. A lightweight, low-ceremony system of accountability, involving no forms, lengthy reviewing sessions or formal reviews is far superior, and will yield much better results.

Most important is to simply recognise the need for such a thing; to realise that you must be accountable to other people for the quality of your code to encourage you to work at your best. To realise that actively putting yourself into that vulnerable position of accountability is not a sign of weakness, but a valuable way to gain feedback and improve your skills.

How accountable do you feel that you currently are for the quality of the code you produce? Is anyone challenging you to produce high quality work, to prevent you from slipping into bad, lazy practices?
Accountability is worth pursuing not only in the quality of our code output, but also in the way we learn, and how we plan our personal development. It's even beneficial in matters of character and personal life (but that's a whole other magazine's column).

Making it work

There are some simple ways to build accountability for the quality of code into your development process. In one development team we found it particularly useful when the all coders agreed on a simple rule: all code passed two eyes before entering source control. With this as a peer-agreed rule, it was our choice to be accountable to one another, rather then some managerial diktat passed down from faceless suits on high. Grass-roots buy-in was key to this success of the scheme.


To satisfy the rule, we employed pair programming and/or a low-ceremony one-on-one code review, keeping each checked-in change small to make the scheme manageable. Knowing another person was going to scrutinise your work was enough to foster a resistance to sloppy practise and to improve the general quality of our code.

If you know that someone else will read and comment on your code, you're more likely to write good code.

This practice genuinely improved the quality of the team, too. We all learnt from one another, and shared our knowledge of the system around. It encouraged a greater responsibility for and understanding of the system.

We also ended up with closer collaboration as a result, enjoyed working with each other, and had more fun writing the code as a consequence of this scheme. The accountability lead to a pleasant, more productive workflow.

Setting the standard

When building developer accountability into your daily routine it is worth spending a while considering the benchmark that you're aiming for. Ask yourself the following questions:

How is the quality of your work judged? How do people currently rate your performance? What is the yardstick they use to gauge it's quality? How do you think they should rate it?
  • The software works, that's good enough.
  • It was written fast, and released on schedule (internal quality is not paramount).
  • It was well-written, and can be maintained easily in the future.
  • Some combination of the above.
Which is seen as most important?

Who currently judges your work? Who is the audience for your work? Is it only seen by yourself? Your peers? Your superiors? Your manager? Your customer? How are they qualified to judge the quality of your handiwork?

Who should be the arbiter of your work quality? Who really knows how well you’ve performed? How can you get them involved? Is it as simple as asking them? Does their opinion have any bearing on the company's current view of your work's quality?


Which aspects of your work should be placed under accountability?
  • The lines of code you produce?
  • The design?
  • The conduct and process you used to develop it?
  • The way you worked with others?
  • The clothes you wore when you did it?
Which aspect matters the most to you at the moment? Where do you need the most accountability and encouragement to keep improving?

The next steps

If you think that this is important, and something you should start adding to your work:
  • Agree that accountability is a good thing. Commit to it.
  • Find someone to become accountable to. Consider making it a reciprocal arrangement; perhaps involve the entire development team.
  • Consider implementing a simple scheme like the one described above in your team, where every line of code changed, added or removed must go past two sets of eyes.
  • Agree on how you will work out the accountability – small meetings, end of week reviews, design meetings, pair programming, code reviews, etc.
  • Commit to a certain quality of work, be prepared to be challenged on it. Don't be defensive.
  • If this happens team-wide, or project-wide then ensure you have everyone's buy-in. Draft a set of team standards or group code of conduct for quality of development.
Also, consider approaching this from the other side: can you help someone else out with feedback, encouragement, and accountability? Could you become another programmer's moral software compass?

Often this kind of accountability works better in pairs of peers, rather than in a subordinate relationship.

Conclusion

Accountability between programmers requires a degree of bravery; you have to be willing to accept criticism. And tactful enough to give it well. But the benefits can be marked and profound in the quality of code you create.

Questions

  • How are you accountable to others for the quality of your work?
  • What should you be held accountable for?
  • How do you ensure the work you do today is as good as previous work?
  • How is your current work teaching you and helping you to improve?
  • When have you been glad you kept quality up, even when you didn't feel like it?
  • Does accountability only work when you chose to enter into an accountability relationship, or can it effectively be something you are required to do? 

Sunday, 9 October 2011

My latest iOS app: The Mahjong Score Book

My latest iOS app is out now (thanks to the iOS 5 SDK having finally gone GM). It's called the Mahjong Score Book and, as the name suggests, is designed to help Mahjong players keep tabs on their scoring in Mahjong games.

Of course, once you have your scores captured inside a wee computer, there's more exciting things we can do with them. So the app allows you to:

  • keep records of all the games you've ever played, with a very clear visual presentation, associated with the date played
  • draw pretty graphs of game progress
  • adopt different rule sets (limit hand value, maximum wins as east wind, etc)
  • export games to databases, as images, or text files
  • automatically roll dice to determine starting positions
  • associate notes with each game
  • and much more.


If you're interested, then check it out in iTunes here.

I appreciate that it's a niche app. It simply something I wrote to fulfil a personal need. Of course, someone else out there is going to find it useful, too. And so I've polished it, honed it, and produced a really very slick app.

I wrote Mahjong Score Book app back in the summer whilst on holiday, playing Mahjong with friends. It serviced its purpose well then and many times since, and I've learnt a few new iOS techniques whilst polishing off the application.

I'm sure that it won't make me millions, but I'm very proud of what I've produced in a relatively short time. If you know someone who plays Mahjong then please point them at it!

Wednesday, 21 September 2011

iOS: Using older SDKs with newer Xcode versions

When you update Xcode versions, the installer automatically removes any old SDKs you have lying around, and replaces them with the latest version.

This is fine behaviour, as the most recent SDKs remain backwards compatible. You can set your project to target older iOS versions. If you do this, the newer SDK features are disabled for you.

However, there are times when you need to use an older SDK.

For example, I am running the latest Xcode with a beta iOS 5 SDK installed. Since this was originally installed on a clean machine, I didn't set the beta install to use a parallel directory and leave the "release version" of the developer tools intact - they simply weren't installed. (Making a parallel install is, in general, the best practice when installing a beta Xcode/SDK set).

Fear not. You can still get your newer Xcode to build with an older SDK, without downgrading your Xcode or making a parallel install:


  • Close any running Xcode instance you have open.
  • Locate the install DMG for an old version of Xcode (e.g. Xcode_3.2.5_and_ios_sdk_4.2_final.dmg, they name them so well) and open it.
  • Do not run the installer!
  • Open the Packages directory in that disk image. It is a hidden directory. Try this terminal incantation: "open /Volumes/Xcode\ and\ iOS\ SDK/Packages"
  • Locate the iPhoneOS and iPhoneSimulator SDKs for the version you want. Run just those pkg files. (e.g. I ran the iPhoneSDK4_2.pkg and it's matching iPhoneSimulatorSDK4_2.pkg)
  • Make sure you specify the /Developer directory as your install location. If you don't, the SDKs will be installed in your root directory, under the /Platforms directory; you'll have to manually copy them into /Developer/Platforms yourself.
  • Now, re-open Xcode. If the SDKs installed in the right locations, they will be selectable in your project now.


Tuesday, 20 September 2011

How to set up Jenkins CI on a Mac

In this post I will describe how to get a running Jenkins server set up on your Mac. Like most free software ("free" as in price and "free" as in freedom), Jenkins is very capable, very functional, and mostly documented. But it didn't quite work out of the box.

As with many such projects, you get far more than you pay for. But you can end up spending more than you expect.

There aren't enough step-by-step how-to guides. And there aren't many documents that help you out when things go wrong. There is a great community behind Jenkins, though, which does help. And plenty of people moaning and blogging. Now I'm adding to that noise.

It took me a few days to get the setup working properly. Hopefully this story-cum-howto will save you some of that effort.

The Prologue

All good developers know that a continuous integration (CI) server is a linchpin of the development effort. I joined a large software project without one, and made loud noises that we needed one. And so, it naturally fell to me to set up.

It's been some time since I set up a CI server. Previously, I've used ViewTier's Parabuild. It was more than adequate. But times have moved on. Although I still have a licence for it, the cools kids are hanging around at other parties these days.

Jenkins (the recent fork of Husdon) seems well-regarded, popular, and to have a good development and support community. It's also open source, so seemed the right way to go. Plenty of people have sung it's praises to me in the past, and that kind of thing counts for a lost.

Our requirements for the builds were:
  • to build two products from the same codebase on Mac OSX
  • to build two products from the same codebase on Windows

Both of these need 32-bit and 64-bit versions.

That's already a reasonable configuration matrix, and highlighted why we needed CI in place. A developer would check in a tweak that they'd built on one configuration. All the other config could easily get broken without anyone noticing for a while.

So: Jenkins to the rescue.

Almost.

I purchased a small Mac Mini to use as a build server. I downloaded a copy of Jenkins (free, whoop!), installed the Mac dev tools (free, whoop!) bought (and installed) Parallels, Windows 7, and the Visual Studio toolchain (not quite as free), and sat down for a small configuration session.


Getting your project ready for a CI build

Before setting up your build on an CI server, you should first create a simple script that builds everything from a clean checkout. Then check that script into the repository, to be versioned alongside the software itself.

For our project, I already had that in place. The script cleaned, built, versioned and packaged the software in one step.

Such scripts are clearly useful for deployment on a CI server, and also for making official software releases by hand, whether or not you release from the CI server builds. It's a record of the recipe needed to build a release.

With a fixed recipe like this in place, every software release can be guaranteed to be good and reproducible.

That's development 101.




Installing Jenkins on the Mac

The Jenkins website has a handy Mac installer that you can download. (In retrospect, I'm not sure if this was more hassle than it was worth, but this is the route I obviously sought to go down.)

STEP 1: Install Jenkins

Download the Mac installer and run it.

This installer creates a system launch daemon that fires up Jenkins when your machine boots. This runs in the background even if you haven't logged in, making a true stand-alone build server installation.

However, if you have a fresh Lion install you don't yet have Java.

STEP 2: Install Java

Try to run a Java app. Any app. The OS may fumble around for a while looking for Java. If you're lucky, it'll download and install it automatically. Otherwise, install it by hand.

And of course, now, Jenkins "just works".

Not.


Configuring Jenkins on the Mac

The Jenkins war (web application archive) is unpacked into /Users/shared/Jenkins. The application runs from there. All configuration is stored there. The source code checkouts and builds go in there. It's the center of your Jenkins universe.

A launch daemon plist is installed in /Library/LaunchDaemons. It runs a script /Library/Application Support/jenkins-runner.sh as the user "daemon" (a system specific user that runs background processes - it is not shown on the login screen, nor does it have a home directory).

This installation has all the hallmarks of a runnable system. You can now point your browser to http://localhost:8080 and start configuring the Jenkins server. The lights are most definitely on. But no one's home yet. As we're about to see...

STEP 3: Set up Jenkins to build a Mac project

I was a good soldier with a simple shell script that built and packaged my application. If you don't have this, write one now. To build Mac projects, you'll need some cunning invocation of xcodebuild and probably packagemaker.

This single script is a critical step in configuring your build job. Whilst it is possible to place multiple build commands into the Jenkins task itself, it's far better to keep them under source control in a script checked in to your codebase (if you need to ask why then you probably need to go to a more basic tutorial!).

Configure Jenkins to check out your repository, to react to appropriate build triggers (e.g. manual build requests through the UI, automatic detection of the repository changing, or other triggers) and to run the appropriate scripts to kick off the build.

Then press "Build Now" to start your first build.

In all probability Jenkins will crash and burn. But don't tear your hair out just yet. You'll be needing it for later on.


Fix Jenkins so it works

Welcome to the nether-world of almost working builds.

STEP 4: Configure the Java heap size

My project is large. It includes lots of third party libraries, including the vastness that is Boost and many other comparable-size libraries. There are also several SDKs that are shipped as large binaries (with versions for each platform and 32/64 bit). That's a lot of data to shovel around.

Jenkins choked trying to check out this monster. It would collapse with Java heap exhaustion errors before it even got to triggering a build. Goodness only knows why a large heap is required to check files out of a subversion repository, but the solution can only be to increase the heap size to remove the bottleneck.

By default, Java allocates a very conservative default heap size to running applications; I believe its 256M or  so on 32-bit Mac OS.

On the Mac, this can be changed using the "Java Preferences" application (found in the /Applications/Utilities folder). The trick is to adjust the Java launch command line (hit Options...) to include the comand-line sneeze: "-Xmx1024M" (or whatever heap size you want). However, this didn't seem to affect the Jenkins Java process launched through launchd.

To set the heap size in that context, you have to adjust the launch script itself. You can place the command line switch into the jenkins-runner.sh file directly. However, the file does have provision to load the heap size parameter from a configuration plist. This plist does not exist by default, but you can create/edit it with the following incantation:

sudo defaults write /Library/Preferences/org.jenkins-ci heapSize 1024M

This will write a file /Library/Preferences/org.jenkins-ci.plist (note that you must not specify the plist file extension to the defaults command).

To make the system use this new heap size, you can't just restart Jenkins (either gracefully within the web interface, or by "kill -9"-ing the process. You can't even use "sudo launchctl {stop,start} org.jenkins-ci".

You could reboot. Or, more cleanly, you have to force launchd to reload of the configuration for the launch daemon using launchctl by unloading, and then reloading the daemon. It's the reloading that'll force the new configuration to take hold. (It took me a while to figure that one out!)

With an increased heap, Jenkins will fall over less. In my case, I got through a whole checkout.

But once Jenkins manages to check out the project and run the build script, you're still not quite done...

My script called xcodebuild to invoke Xcode from the command line to build the various configurations of the project. This script worked fine when run directly from the command line. However, when running within Jenkins it would bomb out with quite unfathomable errors - e.g. NSAssertions triggered from deep within the Xcode IDE codebase. Or it would just enter a hibernation state; lock-up completely, performing no work, but generating no error.

The reason for the strangeness is that xcodebuild doesn't work when run as a user that has no home directory, like daemon. It throws its toys out of the pram in as baroque a manner as it can muster.

STEP 5: Create a "jenkins" user

So, to solve this we can either have Jenkins run as one of the existing users, or - more cleanly - create a new user specifically for jenkins.

To do this:

  • Create a user called "jenkins" from Control Panel. If you care particularly, you might want to create a "hidden" user; follow the instructions here: http://hints.macworld.com/article.php?story=20080127172157404
  • Stop jenkins again: sudo launchctl unload -w /Library/LaunchAgents/org.jenkins-ci.plist
  • Edit  /Library/LaunchAgents/org.jenkins-ci.plist, change the username entry from daemon to jenkins
  • Change all permissions on the existing jenkins files: "sudo chown -R jenkins /User/Shared/jenkins" "sudo chgrp -R staff /User/Shared/Jenkins"
  • Restart Jenkins: sudo launchctl load -w /Library/LaunchAgents/org.jenkins-ci.plist
Re-start the build. Sit and wait.


Job done

From memory, that was the set-up steps required to get builds to work on a Mac from a fresh Jenkins install. These things aren't really covered by the install guides. They're obvious once you know them. Hindsight is great like that.

Plenty of people followed my whining on Twitter with disbelief, saying that Jenkins "just works" for them. Others suggested moving over to Hudson instead, but I imagine I'd've had the same issues there.

Perhaps I'm unusual, and this stuff does just work for everyone else. If that's not the case, then I hope this rant proves useful.

As a postscript, I now have my Jenkins server working well. I have configured a Windows client, running under a Parallels virtual machine on the same computer. It's not the fastest build server when both run together, but it's passable.

There are definitely some rough edges and features lacking from Jekins, but I can't complain at the price. And there are plenty of excellent plugins that really do make it a very capable build server.