Skip to content

Instantly share code, notes, and snippets.

@pepasflo
Last active February 27, 2019 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pepasflo/c37da00cd2fac42486a035005bc6b509 to your computer and use it in GitHub Desktop.
Save pepasflo/c37da00cd2fac42486a035005bc6b509 to your computer and use it in GitHub Desktop.
A 'pod' script which called 'bundle exec pod' if a Gemfile exists, otherwise uses the system 'pod'

A pod wrapper script which calls bundle exec pod if a Gemfile is found

When working with a team of iOS developers, it can be useful to keep all team members on the same version of the pod command (different versions of pod can result in wildly different Xcode project files, resulting in a lot of noise in pull-requests).

One way to do this is to include a Gemfile in your github repo, which specifies a specific version of Cocoapods:

$ cat Gemfile
source 'https://rubygems.org'
gem 'fastlane'
gem 'cocoapods', '1.4.0'

However, this means that team members must remember to run bundle exec pod rather than pod. This is both an annoyance and an easy mistake to make.

A solution to this is to use a pod wrapper script which will run bundle exec pod if it finds a Gemfile, and otherwise use whatever pod is in $PATH.

This wrapper script can be checked in to your repo and symlinked into each developer's ~/bin.

But how can a script named pod execute the pod command without instead calling itself in an endless loop?

There's a bit of trickery: the script removes its own $PATH component before calling pod!

#!/usr/bin/env python
# A wrapper for 'pod' which detects if it should run 'bundle exec pod' or
# use the system 'pod' command, based on the presence of a 'Gemfile'.
# If a Gemfile exists in any directory above pwd, 'bundle exec pod' should
# be used. Otherwise, the system 'pod' is used.
# Expected behavior:
# $ pwd
# /Users/foo/github/some_repo
# $ pod --version
# 1.4.0
# $ cd /tmp
# $ pod --version
# 1.5.3
import os
import sys
def gemfile_exists():
# Ascend up the directory tree looking for a Gemfile.
gempath = 'Gemfile'
while True:
if os.path.exists(gempath):
return True
else:
if os.path.abspath(gempath) == '/Gemfile':
return False
else:
gempath = '../' + gempath
continue
if __name__ == "__main__":
if gemfile_exists():
cmd = ['bundle', 'exec', 'pod'] + sys.argv[1:]
else:
scriptdir = os.path.dirname(__file__)
pathchunks = os.environ["PATH"].split(':')
if scriptdir in pathchunks:
os.environ["PATH"] = ':'.join(
filter(lambda x: x != scriptdir, pathchunks)
)
else:
# We can't find an exact match in $PATH, so fall back to the
# alternate strategy of chopping one leading component from $PATH
# and recursing.
# (To instead chop a trailing component, change '[1:]' to '[:1]')
os.environ["PATH"] = ':'.join(pathchunks[1:])
cmd = ['pod'] + sys.argv[1:]
os.execvp(cmd[0], cmd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment