Skip to content

Instantly share code, notes, and snippets.

@fabiopelosin
Created July 24, 2012 22:35
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 fabiopelosin/3173126 to your computer and use it in GitHub Desktop.
Save fabiopelosin/3173126 to your computer and use it in GitHub Desktop.
Experimental CocoaPodsBot
#!/usr/bin/env ruby
# Experimental CocoaPodsBot
#
# Synopsis:
#
# The CocoaPodsBot performs a full lint (including xcodebuild) and prints a
# markdown message with the result of the lint.
#
# Usage:
#
# $ ruby CocoaPodsBot.rb [LOGIN PASSWORD] PULL_REQUEST_NUMBER
#
# - LOGIN A GitHub account belonging to the CocoaPods
# organization. If not provided the value of the
# GITHUB_USER environment variable is used.
#
# - PASSWORD The password of the account. If not provided the
# value of the GITHUB_USER environment variable is
# used.
#
# - PULL_REQUEST_NUMBER The number of the pull request to lint.
#
# Requirements:
#
# - CocoaPods
# - Xcode command line tools
# - OS X
#
# Todo:
#
# - Use the GitHub API to comment on behalf of the user on the pull request.
# Alternatively a CocoaPodsBot account could be created for this purpose.
#
# - Support for pulls with multiple podspecs that depend from each other.
#
require 'rubygems'
require 'open-uri'
require 'CocoaPods'
require 'octokit'
Specification = Pod::Specification
TMP_DIR = Pathname.new('/tmp/CocoaPods/CocoaPodsBot')
class CocoaPodsBot
def initialize(arguments)
if arguments.count == 3
login, password, pull_number = *arguments
else
login, password = ENV['GITHUB_USER'], ENV['GITHUB_PASSWORD']
pull_number = arguments.first
end
@client = Octokit::Client.new(:login => login, :password => password)
@pull_number = pull_number
end
def pull_request
@pull_request ||= @client.pull_request('CocoaPods/Specs', @pull_number)
end
def team_members
# 108950 is the id of the Specs team
@team_members ||= @client.team_members('108950')
end
def pull_request_files
@client.get("https://api.github.com/repos/cocoapods/specs/pulls/#{@pull_number}/files")
end
def local_path(file)
TMP_DIR + File.basename(file.raw_url)
end
def download_podspec(file)
path = local_path(file)
path.dirname.mkpath
open(file.raw_url) do |io|
path.open('w') { |f| f << io.read }
end
end
def path_message(file)
spec = Specification.from_file(local_path(file))
expected_filename = "#{spec.name}/#{spec.version}/#{spec.name}.podspec"
file.filename == expected_filename ? nil : "\nIncorrect Path: `#{file.filename}` should be `#{expected_filename}`.\n"
end
def lint_message(file)
output = `pod spec lint --no-color #{local_path(file)}`
$?.to_i.zero? ? nil : output
end
# @TODO: The best solution would be to merge the master repo and
# and then lint the pods so new dependencies are available checked.
#
def run
puts
puts "Processing Pull Request ##{@pull_number} by #{pull_request.user.login}"
puts
path_messages = []
lint_messages = []
pull_request_files.each do |file|
filename = file.filename
url = file.raw_url
puts "- #{filename}"
download_podspec(file)
path_messages << path_message(file)
lint_messages << lint_message(file)
end
puts
if lint_messages.compact.empty? && path_messages.compact.empty?
comment = "The CocoaPodsBot approves this pull request."
unless team_members.any? { |user| user.id == pull_request.user.id }
comment << " @#{pull_request.user.login} Would you like push access?"
end
else
comment = ":exclamation: The CocoaPodsBot has some concerns regarding this pull request.\n"
comment << path_messages.join("\n - ")
comment << "\n\n```"
comment << lint_messages.join("\n")
comment << "\n```"
end
puts comment
puts
end
end
bot = CocoaPodsBot.new(ARGV)
bot.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment