mokacoding

unit and acceptance testing, automation, productivity

An even lighter way to use Carthage

Carthage is an iOS and OS X dependency manager that aims to be simple to use and "out of your way". In this post we will look into a different way to integrate dependencies using Carthage than the standard one, an why you might want to use it.

As usual there is a sample project, which is the same used when we looked at How to add testing dependencies using Carthage, but on a different branch.

The standard way to use Carthage is by having a Cartfile listing the dependencies, and then running carthage update to download them in the Cathage/Checkouts folder, and build each of those into frameworks located in the Carthage/Build folder, and finally the developer has to manually integrate in the project.

Looking at gitignores around the web, for example Carthage's own gitignore, it seems recommended to ignore the Carthage/Build folder. This has the result that each new checkout of a project using Carthage has to run carthage update before being able to build, or the frameworks referenced in the project won't be found.

There are a lot of opinions among developers on whether to track dependencies into a project's SCM, and the truth is that each team should make a choice based on their specific requirements. When choosing not to track dependencies though two things have to be kept in mind:

  • If the referenced dependency version disappears from the internet the project won't build ever again.
  • CI boxes will have to install the dependencies at every run which takes more time, or have caching systems which increases complexity.

I tweeted in this regard, and Tony Arnold replied to me suggesting a different approach than usual:

--no-build

The description of the --no-build option for the update command says, very straightforwardly: skip the building of dependencies after updating. This means that after running carthage update --no-build we won't have any Carthage/Build folder.

How to integrate the dependencies then?

The answer is in Tony's tweet: just integrate the projects directly ๐Ÿ˜Ž. To recap:

  1. Define dependencies in the Cartfile.
  2. Run carthage update --no-build.
  3. Create a workspace for the project if you don't have one already.
  4. Add all the dependencies' projects from the Carthage/Checkouts folder to the workspace.
  5. ๐ŸŽ‰Stuff works๐ŸŽ‰

Tradeoffs

Some advantages of this method are:

  • No need to run any dependency update command on checkout, the project will build out of the box. This is great if you need to speed up your CI builds.
  • No need to add the copy-frameworks Build Phase workaround for iOS projects.
  • The dependencies source is available to the developers. This is great if you need to look into the source or modify it.

There are some disadvantages too:

  • This is not the standard usage of Carthage, so you will need to document the carthage update --no-build invocation, or better script it.
  • Each dependency is added to the workspace as a project, if you have more than a handful of dependencies the workspace navigator might become cluttered.
  • Having the dependencies source available might tempt daredevil developers to modify it without realising that the change will be lost when the dependency is updated to a newer version.

As expected there are a number of pros and cons, and no solution comes out as the silver bullet. It is up to you and your team to take an informed decision, measure the outcome, and review it to decide if it is actually the best approach for you or not. The good news is that switching between one or the other is not hard at all, only a mundane add/remove of references in Xcode.

If you are using Carthage to manage your dependencies, with or without the --no-build option, I'd love to hear about it, leave a comment below or hit me up on Twitter @mokagio.

A big thanks again to Tony Arnold for suggesting the workflow, and reviewing this post ๐Ÿ‘.

Happy coding, and leave the codebase better than you found it.

Ps. On the 17th and 18th of September I will be speaking at YOW! Connected in Melbourne, Australia, if you are there come around and say hi ๐Ÿ˜Š.

Want more of these posts?

Subscribe to receive new posts in your inbox.