Keith Smiley | About | RSS | Mastodon

Raking Podspecs

I spend a decent amount of time these days helping maintain the CocoaPods specs repo by managing pull requests and issues. CococaPods is an awesome dependency manager similar to Rubygems for Objective-C projects. Unfortunately a lot of submitted podspecs haven't been correctly formatted or they're missing required information. CocoaPods has an awesome build in command pod spec lint that allows you to make sure the spec is valid and complete. Understandably people who are new to CocoaPods trying to submit their libraries are unaware of this awesome tool. Therefore when I look through the pull requests, I like to lint them myself (CocoaPods does utilize Travis but unfortunately it can't do everything).

Since CocoaPods supports multiple versions of Ruby (1.8.7 and 1.9.3) to be complete ideally you'd lint them on both versions. Tools like RVM and rbenv(my tool of choice) make it easy to quickly switch between different versions of Ruby using .rvmrc and .rbenv-version respectively. As you can probably assume I wanted to automate this. So I wrote a quick Rakefile to do this for me.

#!/usr/bin/env rake

# NOTE: Must be using rbenv 4.0 to use `system` and `.ruby-version`
## Set your preferred ruby versions
$V18 = 'system'
$V19 = '1.9.3-p385'
$RBENV = '.ruby-version'

# The gem to use
$GEM = 'cocoapods'

task :default => :lint
task :c       => :clean

desc "Lint podspecs on multiple versions of ruby with rbenv"
task :lint do
  if Dir.glob('*.podspec').count < 1
    puts "No podspecs in #{ Dir.pwd }"
    exit
  end

  existed = versionFileExists?
  if existed
    old_version = currentVersion
  end

  # Loop through all podspecs
  Dir.glob('*.podspec').each do |file|
    # Loop through ruby versions
    2.times do |x|
      version = x == 0 ? $V18 : $V19
      writeVersion(version)

      puts "Linting #{ file } on Ruby version #{ currentVersion }"
      puts lint(file)
    end
  end

  # If the dotfile already existed rewrite the original code
  if existed
    writeVersion(old_version)
  else
    File.delete($RBENV) if versionFileExists?
  end
end

desc "Delete all podspec files"
task :clean do
  Dir.glob('*.podspec').each { |file| File.delete(file) }
  Dir.glob($RBENV).each { |file| File.delete(file) }
end

# Check to see if the current dotfile exists
def versionFileExists?
  File.exists?($RBENV)
end

# Retrieve the current version from the rbenv dotfile
def currentVersion
  File.open($RBENV, "r") { |io| io.read }
end

# Write out a version to .rbenv-version
def writeVersion(version)
  File.open($RBENV, 'w') { |file| file.write("#{ version }") }
end

# Run the lint
def lint(podspec)
  %x[pod spec lint "#{ podspec }"]
end