Way back in January of 2013, we released Liftoff to help developers quickly configure Xcode projects. We used it heavily internally, but felt like it was only solving part of the problem. So we’ve improved it, and are proud to announce Liftoff 1.0.

Earlier versions of Liftoff were distributed as a Ruby gem, but that added some weird overhead to the tool, since it isn’t used for Ruby development. For this reason, Liftoff 1.0 is now distributed through Homebrew. We’re adding it to our thoughtbot/formulae tap, and all future updates will be done there.

The RubyGems version will stay up, but is deprecated. If you install the Homebrew version, you should make sure to uninstall the RubyGems version to avoid confusion/potential conflicts.

The next thing that we were able to improve was the way you configure Liftoff itself. Originally, we used command line flags to enable specific configurations (there was no way to selectively disable configurations). This worked fine for us because we never touched these flags. But it made Liftoff extremely rigid and clumsy for people who wanted to configure their projects differently.

I had opened an issue after an internal conversation about possibly using a config file instead of command line options, and after an awesome contribution from @mokagio, we had a viable solution for configuring projects quickly and easily, without increasing overhead for users out of the box.

The liftoffrc file is written in YAML, and works with a 3 stage fallback system on a per-key basis. The lookup order is:

Local ( ./.liftoffrc ) User ( ~/.liftoffrc ) Default ( <liftoff installation location>/defaults/liftoffrc )

If a key isn’t defined at one level, it will fall back to the next level. So you can safely override individual keys without changing the default behavior, or build your own set of defaults at the User level and override those options at the Local level.

Take a look at the default liftoffrc to see what keys are available for customization.

The largest change in Liftoff 1.0 is that you can now use it to create new projects from scratch, as opposed to only being able to use it for configuring existing projects. Now, when you run liftoff in a directory that doesn’t contain a project, you’ll get a prompt asking you for the project name, the company name, your name, and the prefix. These values will be used to create a directory structure, populate template files, and configure the new project. You can see what the default directory/group structure will look like in the default liftoffrc .

This becomes especially powerful when you consider that since the keys used to generate the new project are defined in liftoffrc , they are easily overridden for your specific needs. You can even pre-define some defaults for the options collected at the command line to speed up the data entry. For example, I’m setting author inside ~/.liftoffrc so that I don’t have to enter my name any time I want to create a new project. I’m also setting company: thoughtbot inside ~/Code/thoughtbot/.liftoffrc and company: Gordon Fontenot inside ~/Code/personal/.liftoffrc . Now, projects I create have sensible defaults based on where I’m creating them.

Additionally, you can completely redefine the project structure based on your personal preference, or your employer’s requirements. Again, referring to the default liftoffrc , you can see that the directory structure is a simple dictionary. And since the directory structure is mimicked in the group structure (including linking groups to their directory counterparts, which Xcode doesn’t do by default), the group structure will match.

We’re also creating .gitkeep files in each directory on disk, which is critical, because Xcode is all-too-happy to delete a directory off disk once it sees that there aren’t any files left in it. That’s a sure-fire way to end up with merge-conflicts in your pbxproj file.

So that’s Liftoff 1.0. We’ve put a lot of work into this release, and it’s been a really great addition to our toolbelt so far. If you have ideas on how to make it even better, open an issue, or even better: submit a pull request. If you’re ready to check it out for yourself, install it via Homebrew: