mise en place Xcode

I’ve recently started using mise “a polyglot tool version manager” and have been really impressed with how much simpler it makes configuring projects.

For example if I want to use a tool like swiftlint I have to make sure that all other developers on my team and the CI machine agree on which version to use. If we have different versions we might end up with contrasting linting rules causing various errors/disagreement. In the past I’ve dealt with this by bundling the binary into the repository but this consumes repository space that will never be reclaimed.

A better way

Enter mise a tool which I only investigated because tuist started using it for managing its versions. With mise I can create a file in my repository called .mise.toml and configure the version of swiftlint I want to use like this

.mise.toml

[tools]
swiftlint = "0.55.1"

With this file in place I can call mise install and mise will download the version I specified and make sure it is installed on my $PATH. Now when I call swiftlint from within my projects directory it will ensure that the correct version of swiftlint is used.

What about in Xcode?

mise works by modifying $PATH when you cd into a directory, so that won’t work in Xcode run scripts. Fortunately mise provides a solution; instead of calling swiftlint directly in my run script I can instead tell mise to execute swiftlint like this

$HOME/.local/bin/mise x -- swiftlint

mise will do the same thing of looking inside the .mise.toml file and then making sure it invokes the correct version of swiftlint for me.

What about on CI?

You can use the same trick above on CI or if you are using github actions there is a specific mise action that will take care of calling install and setting up the path for any following actions.


Can it help with fastlane?

Yes. fastlane is a ruby gem and Ruby is not always easy to get configured right especially if you’ve not got much terminal experience. Now I love Ruby but I hate to think how many hours/days I lost over the years helping colleagues get their environment set up. I’ve also personally changed my Ruby version management tooling from rvm to chruby to rbenv over the years in search of a solution that is stable.

Thankfully mise is polyglot and so I can now just use this for making sure that I have a version of Ruby suitable for use with fastlane.

e.g. updating my .mise.toml to

.mise.toml

[tools]
ruby = "3.3.0"
swiftlint = "0.55.0"

Then again running mise install - this time it will take longer as it builds me the version of Ruby I specify.

For best results with building Rubies I’ve found it wise to get your build environment set up as recommended here.


Any more?

I work in different languages on various Kotlin/Java code bases. Nothing is ever simple so of course those different code bases require different JVMs for which I had to use a version manager - I was using jenv. Now that I have mise I don’t need jenv anymore and my entire set up is simplified further.

In fact there is an eye watering list of tooling that mise supports which you can see here and it doesn’t look difficult to add your own plugin if you want to support different tools.


Wrap up

I’m really liking mise. There were a couple of things to figure out like the mise x command but after that and realising I can bin off my various other tools for managing versions I feel I have a much cleaner and more maintainable way to get build environments set up across the team.