mobile development == development for different API versions
As you know, the last years I was using Mercurial (hg) as DVCS for my projects.
2012 will become the year of Git ;-)
While I like the easy-to-use-and-understand Mercurial, which is a good way to start with DVCS, the last weeks I experimented using Git for some special workflows not so easy possible using Mercurial.
If you’re developing for mobile devices (doesn’t matter if this is Android or BlackBerry etc) sooner or later you run into the situation that you have to support some platform OS versions.
per ex. for BlackBerry:
- BlackBerry OS 5
- BlackBerry OS 6
- BlackBerry OS 7
there are different strategies how to solve this:
- manage different projects for each OS Version
- use a pre-processor
- encapsulate different API’s in libraries and build different products
both doesn’t make me happy: I don’t want to manage different projects parallel and I also don’t want to use a preprocessor because the code becomes more unreadable with all those if OS5 then….. if OS 6 then….. instructions. Also the library-per-API.-differences solution isn’t really flexible.
So I was looking for new ways HowTo solve this and sketched up what I’ll need.
I don’t need it exactly this way, but if you should read the article to get the idea how all will work.
so back to the mobile development.
let’s take an actual example:
logging4bb using a special Git Branching model
I developed a logging framework for BlackBerry OS 6+. As you probably know, under BlackBerry OS Java you couldn’t use any of the modern logging frameworks like Log4J, SLF4J, LogBack, java.util-logging etc.
Logging is always an important part for my development, so I implemented a logging framework (logging4bb) where I can
- log to SQlite on BlackBerry
- or through Socket Connection to Lilith as LogMonitor.
If you followed my blogs you know that I’m using Lilith since years to monitor the logging of OSGi – Equinox applications together with SLF4F / LogBack.
I’m sending LogEvents to Lilith using the same format as LogBack does this using a Lilith Appender, so Lilith doesn’t know that there’s not LogBack but a BlackBerry device sending events.
This works from Simulator and also real Devices through WLAN or CellTower. The best thing: now you can watch log statements from server and mobile clients side-by-side :)
read more here about the logging4bb project itself.
Between BlackBerry OS 6 and OS 7 APIs supporting SQLite and also Remote Command Framework are different, so I wanted to support both OS versions.
Next problem because the project should be Open-Sourced:
The Socket Connection uses BIS (BlackBerry Internet Service), which makes it very easy to switch between WLAN and CellTower and still using the same SocketConnection.
As a BlackBerry partner you’re allowed to use BIS as a free BlackBerry Service in your products (per ex. my Apps in the Appworld), but it’s not allowed to publish the special connection String.
To launch and run the application I have to use the String. How to make development possible with these goals:
- support different OS versions (API)
- support public (OSS) and private development
- support OSS project and Appworld Product
all without the standard ways like pre-processor etc.
public and private repositories
of course I want to use source repositories for the public parts (OSS) and also the private parts (secret connection and also appworld product and/or customer products).
that’s the reason why the projects are hosted at Bitbucket: I can have unlimited private repositories for free.
Great that Bitbuckit also supports both: hg and Git projects.
Git Branching Model
Here’s an example how the branching model could look like from different tools:
I’m working with Tower because then it’s easy to have one single place where I can manage all my repositories from Eclipse Workspaces on OSX (my main development) and also Eclipse Workspaces from the unfortunately-Windows-only-BlackBerry development.
Hint: I’m using Parallels and mapped a directory on OSX as Drive W:\ to Parallels-Windows7 running on top of OSX. so I can manage all from Tower on OSX :)
Here’s an overview how my branching model works:
let’s take a look into the details:
Who’s the Master ?
There’s no Master branch as usual, because there are dev-* branches working like a Master branch for the different OS Versions.
The Master only has a readme.txt file with a short description of the branching model.
Then development started with the dev-public Branch – in this case development started with OS 6 API. Some times later after finishing the OS 6 version, the development continues using the newest OS 7, so a branch os6/dev-public was created.
Each branch works like a Master for the specific OS Version.
Hint: I’m using the “/” in the names to get a folder-like structure in tooles like Tower.
What about Bugs ?
Bugfixes only for OS 6 API will be done on the os6/dev-public branch – bugs for all versions will be fixed on the newest branch.
If some parts of the new development or generic branches should be back-ported to the older os6 version, then GIT Cherry-Pick is an easy way to do this.
How to use the “secret” private Repository ?
This repository is only needed in workflows where the project ist Open Source and public, but some parts are not allowed to be publicly visible.
In this special case I need dev-secret* branches, where I add the secret parts. Now it becomes difficult: without the secret connection code I cannot run and test the application or launch the simulator. So normaly I’ll work in the *secret* branches, test-run-change code etc.
But these changes must be part of the public branches. So after some steps I want to commit and I also want to be sure, that all works from the OSS public branch.
Now GIT Stashing comes into play:
- all changes from secret branch will be staged
- then stashed
- now switching to public branch
- applying stash to public branch and see if all compiles
- committing to public branch
- pushing to remote public OSS repository
- switching back to secret branch
- merging public branch into secret branch
- pushing changes to private secret repository
sounds complicated, but it works very well and after some weeks working with this branching model I like the flexibility
How to work with Customer Repositories ?
workflows are easier, I only merge regulary from the public development branches, because normaly special customer-cases won’t be given back to the public area.
but if – from time to time – something should go back: as usual cherry-picking is your friend.
HowTo organize local development Repositories
this is totally up to you how you organize your local repositories. It depends from your team-size, project structures etc. some examples what could be done:
- One local repo for all Braches of a specific project: You can have one workspace for all branches and always switch between public – secret – customers – OS Versions. Again Stashing can help to make the workspace clean before switching.
- One local repo for each platform OS: Then your local Repository has some branches for different projects from different remote repositories, but all for the same OS Version
- One local repo for each Customer: Then all Customer Branches will be inside one workspace.
To cherry-pick and move changes back to other branches one member of your development team should have a local Repository like 1.
The Branching Model above was all about public remote branches tracked by your local branches.
Of course al the usual workflows work as with ‘normal’ projects referring to a Master Branch only:
create local branches for bugfixes, new features etc.
Hint: if not already done please read the article above: A successful Git branching model
What Users should Clone / Check-Out ?
Users simply clone the public Repository and then have to decide which public branch they should check out and always pull against to get the newest things.
Everyone who only needs the OS 6 version simply checks out the os6/dev-public branch, who needs the newest one checks out dev-public branch. Who needs all, can switch between the branches or have different workspaces for different OS Versions or ….
GIT really makes it easy for everyone to follow their specific workflows and project structures.
Tooling is important if you want to manage complex workflows with GIT.
If you’re a friend of the commandline, then you can do it all from there very fast and all options are open to you.
But I don’t like the commandline and prefer UI Tools.
If you’re working with Eclipse only then EGit is the best way to do it. Newest versions of EGit / JGit now are supporting most what GIT provides. If you like Gerrit for code-reviews then again EGit is a good solution.
I’m now using Tower, which is a great UI Tooling for OSX. (Thx @PeterFriese mentioning Tower some time ago at twitter)
With Tower I can manage all my repositories at a single place – doesn’t matter if they’re from OSX – Eclipse workspaces, Windows (on-Parallels) Eclipse workspaces or from non-Eclipse sources.
All the workflows are easy to manage from Tower. The UI is a really good looking OSX UI. I’ll provide some Videos later.
…to Al Blue’s Git Tips of the week – series – this is a must-read for everyone starting with Git to understand the power of Git.
I’ll blog some more about my GIT experiences soon as part of my DVCS blogging series.