Commit edff6c05 authored by Will Pragnell's avatar Will Pragnell

Merge branch master into acknowledgements

parents 5c62253a 42cc83a1
......@@ -38,7 +38,6 @@ GEM
faraday_middleware (~> 0.8)
hashie (~> 1.2)
multi_json (~> 1.0)
open4 (1.3.0)
pry (0.9.8.4)
coderay (~> 1.0.5)
method_source (~> 0.7.1)
......@@ -64,7 +63,6 @@ DEPENDENCIES
kicker
mocha-on-bacon
octokit
open4
pry
rake
rb-fsevent
......
......@@ -29,7 +29,6 @@ Gem::Specification.new do |s|
"you are upgrading, first run: $ pod setup"
s.add_runtime_dependency 'xcodeproj', '~> 0.1.0'
s.add_runtime_dependency 'popen4', '~> 0.1.2'
s.add_runtime_dependency 'colored', '~> 1.2'
s.add_runtime_dependency 'escape', '~> 0.0.4'
s.add_development_dependency 'bacon', '~> 1.1'
......
......@@ -33,6 +33,7 @@ module Pod
autoload :Acknowledgements, 'cocoapods/generator/acknowledgements'
autoload :Plist, 'cocoapods/generator/acknowledgements/plist'
autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown'
autoload :DummySource, 'cocoapods/generator/dummy_source'
end
end
......@@ -42,3 +43,7 @@ class Pathname
end
end
if ENV['COCOA_PODS_ENV'] == 'development'
require 'pry'
require 'awesome_print'
end
......@@ -6,6 +6,7 @@ module Pod
autoload :Install, 'cocoapods/command/install'
autoload :List, 'cocoapods/command/list'
autoload :Presenter, 'cocoapods/command/presenter'
autoload :Push, 'cocoapods/command/push'
autoload :Repo, 'cocoapods/command/repo'
autoload :Search, 'cocoapods/command/search'
autoload :Setup, 'cocoapods/command/setup'
......@@ -18,12 +19,13 @@ module Pod
def message
[
@command_class.banner,
'',
'Options',
'-------',
@command_class.banner.gsub(/\$ pod (.*)/, '$ pod \1'.green),
'',
options
'Options:',
'',
options,
"\n",
].join("\n")
end
......@@ -45,22 +47,19 @@ module Pod
end
def self.banner
"To see help for the available commands run:\n" \
"\n" \
" * $ pod setup --help\n" \
" * $ pod search --help\n" \
" * $ pod list --help\n" \
" * $ pod install --help\n" \
" * $ pod repo --help\n" \
" * $ pod spec --help"
commands = ['install', 'list', 'push', 'repo', 'search', 'setup', 'spec'].sort
banner = "\nTo see help for the available commands run:\n\n"
commands.each {|cmd| banner << " * $ pod #{cmd.green} --help\n"}
banner
end
def self.options
[
['--help', 'Show help information'],
['--silent', 'Print nothing'],
['--verbose', 'Print more information while working'],
['--version', 'Prints the version of CocoaPods'],
['--help', 'Show help information'],
['--silent', 'Print nothing'],
['--no-color', 'Print output without color'],
['--verbose', 'Print more information while working'],
['--version', 'Prints the version of CocoaPods'],
]
end
......@@ -90,6 +89,8 @@ module Pod
Config.instance.silent = argv.option('--silent')
Config.instance.verbose = argv.option('--verbose')
String.send(:define_method, :colorize) { |string , _| string } if argv.option( '--no-color' )
command_class = case argv.shift_argument
when 'install' then Install
when 'repo' then Repo
......@@ -97,6 +98,7 @@ module Pod
when 'list' then List
when 'setup' then Setup
when 'spec' then Spec
when 'push' then Push
end
if show_help || command_class.nil?
......
......@@ -35,7 +35,7 @@ module Pod
def initialize(argv)
config.clean = !argv.option('--no-clean')
config.doc = !argv.option('--no-doc')
config.generate_docs = !argv.option('--no-doc')
config.force_doc = argv.option('--force-doc')
config.integrate_targets = !argv.option('--no-integrate')
@update_repo = !argv.option('--no-update')
......
......@@ -2,7 +2,7 @@ module Pod
class Command
class Presenter
def self.options
" --stats Show additional stats (like GitHub watchers and forks)\n"
[["--stats", "Show additional stats (like GitHub watchers and forks)"]]
end
autoload :CocoaPod, 'cocoapods/command/presenter/cocoa_pod'
......@@ -24,10 +24,11 @@ module Pod
result << detail('Homepage', pod.homepage)
result << detail('Source', pod.source_url)
if @stats
result << detail('Pushed', pod.github_last_activity)
result << detail('Authors', pod.authors) if pod.authors =~ /,/
result << detail('Author', pod.authors) if pod.authors !~ /,/
result << detail('Platform', pod.platform)
result << detail('License', pod.license)
result << detail('Platform', pod.platform)
result << detail('Watchers', pod.github_watchers)
result << detail('Forks', pod.github_forks)
end
......@@ -43,18 +44,15 @@ module Pod
txt.strip.gsub(/(.{1,#{col}})( +|$)\n?|(.{#{col}})/, indent + "\\1\\3\n")
end
def detail(title, value, preferred_indentation = 8)
# 8 is the length of Homepage
def detail(title, value)
return '' if !value
number_of_spaces = ((preferred_indentation - title.length) > 0) ? (preferred_indentation - title.length) : 0
spaces = ' ' * number_of_spaces
''.tap do |t|
t << " - #{title}:"
t << " - #{title}:".ljust(16)
if value.class == Array
separator = "\n - "
t << separator + value.join(separator)
t << separator << value.join(separator)
else
t << " #{spaces + value.to_s}\n"
t << value.to_s << "\n"
end
end
end
......
......@@ -72,6 +72,10 @@ module Pod
Pod::Specification::Statistics.instance.github_forks(@set)
end
def github_last_activity
distance_from_now_in_words(Pod::Specification::Statistics.instance.github_pushed_at(@set))
end
def ==(other)
self.class === other && @set == other.set
end
......@@ -92,6 +96,25 @@ module Pod
"#{words[0..-2].join(', ')}, and #{words.last}"
end
end
def distance_from_now_in_words(from_time)
from_time = Time.parse(from_time)
to_time = Time.now
distance_in_days = (((to_time - from_time).abs)/60/60/24).round
case distance_in_days
when 0..7
"less than a week ago"
when 8..29
"#{distance_in_days} days ago"
when 30..45
"1 month ago"
when 46..365
"#{(distance_in_days.to_f / 30).round} months ago"
else
"more than a year ago"
end
end
end
end
end
......
require 'fileutils'
module Pod
class Command
class Push < Command
def self.banner
%{Pushing new specifications to a spec-repo:
$ pod push [REPO]
Validates `*.podspec' in the current working dir, updates
the local copy of the repository named REPO, adds specifications
to REPO, and finally it pushes REPO to its remote.}
end
def self.options
[["--allow-warnings", "Allows to push if warnings are not evitable"]].concat(super)
end
extend Executable
executable :git
def initialize(argv)
@allow_warnings = argv.option('--allow-warnings')
@repo = argv.shift_argument
super unless argv.empty? && @repo
end
def run
validate_podspec_files
check_repo_status
update_repo
add_specs_to_repo
push_repo
puts
end
private
def update_repo
puts "Updating the `#{@repo}' repo\n".yellow unless config.silent
# show the output of git even if not verbose
Dir.chdir(repo_dir) { puts `git pull 2>&1` }
end
def push_repo
puts "\nPushing the `#{@repo}' repo\n".yellow unless config.silent
Dir.chdir(repo_dir) { puts `git push 2>&1` }
end
def repo_dir
dir = config.repos_dir + @repo
raise Informative, "[!] `#{@repo}' repo not found".red unless dir.exist?
dir
end
def check_repo_status
# TODO: add specs for staged and unstaged files (tested manually)
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "[!] `#{@repo}' repo not clean".red unless clean
end
def podspec_files
files = Pathname.glob("*.podspec")
raise Informative, "[!] Couldn't find .podspec file in current directory".red if files.empty?
files
end
def validate_podspec_files
puts "\nValidating specs".yellow unless config.silent
lint_argv = ["lint"]
lint_argv << "--only-errors" if @allow_warnings
lint_argv << "--silent" if config.silent
all_valid = Spec.new(ARGV.new(lint_argv)).run
end
def add_specs_to_repo
puts "\nAdding the specs to the #{@repo} repo\n".yellow unless config.silent
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
if Pathname.new(output_path).exist?
message = "[Fix] #{spec}"
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
message = "[Update] #{spec}"
else
message = "[Add] #{spec}"
end
puts " - #{message}" unless config.silent
FileUtils.mkdir_p(output_path)
FileUtils.cp(Pathname.new(spec.name+'.podspec'), output_path)
Dir.chdir(repo_dir) do
git("add #{spec.name}")
git("commit -m '#{message}'")
end
end
end
end
end
end
# encoding: utf-8
require 'net/https'
require 'uri'
require 'octokit'
require 'json'
module Pod
class Command
class Spec < Command
def self.banner
%{Managing PodSpec files:
$ pod spec create [NAME]
$ pod spec create [https://github.com/USER/REPO]
$ pod spec create [ NAME | https://github.com/USER/REPO ]
Creates a PodSpec, in the current working dir, called `NAME.podspec'.
If a GitHub url is passed the spec is prepopulated.
$ pod spec lint [NAME.podspec]
$ pod spec lint [ NAME.podspec | REPO ]
Validates `NAME.podspec'. In case `NAME.podspec' is omitted, it defaults
to `*.podspec' in the current working dir.}
to `*.podspec' in the current working dir. If the name of a repo is
provided it validates all its specs.}
end
def self.options
[ ["--quick", "Lint skips checks that would require to donwload and build the spec"],
["--only-errors", "Lint validates even if warnings are present"] ].concat(super)
end
def initialize(argv)
args = argv.arguments
unless (args[0] == 'create' && args.size == 2) ||
(args[0] == 'lint' && args.size <= 2)
@action = argv.shift_argument
if @action == 'create'
@name_or_url = argv.shift_argument
@url = argv.shift_argument
super if @name_or_url.nil?
elsif @action == 'lint'
@quick = argv.option('--quick')
@only_errors = argv.option('--only-errors')
@repo_or_podspec = argv.shift_argument unless argv.empty?
super unless argv.size <= 1
else
super
end
@action, @name_or_url = args.first(2)
super unless argv.empty?
end
def run
......@@ -37,64 +45,400 @@ module Pod
end
def create
if repo_id = @name_or_url[/github.com\/([^\/\.]*\/[^\/\.]*)\.*/, 1]
if repo_id_match = (@url || @name_or_url).match(/github.com\/([^\/\.]*\/[^\/\.]*)\.*/)
require 'octokit'
repo_id = repo_id_match[1]
data = github_data_for_template(repo_id)
data[:name] = @name_or_url if @url
puts semantic_versioning_notice(repo_id, data[:name]) if data[:version] == '0.0.1'
else
data = default_data_for_template(@name_or_url)
end
spec = spec_template(data)
(Pathname.pwd + "#{data[:name]}.podspec").open('w') { |f| f << spec }
puts "\nSpecification created at #{data[:name]}.podspec\n".green
puts "\nSpecification created at #{data[:name]}.podspec".green
end
def lint
name = @name_or_url
file = name ? Pathname.new(name) : Pathname.pwd.glob('*.podspec').first
spec = Specification.from_file(file)
puts "\nThe #{spec.name} specification contains all the required attributes.".green if spec.validate!
warnings = []
warnings << 'The name of the specification should match the name of the podspec file' unless path_matches_name?(file, spec)
warnings << 'Missing license[:type]' unless spec.license && spec.license[:type]
warnings << 'Missing license[:file] or [:text]' unless spec.license && (spec.license[:file] || spec.license[:text])
warnings << "Github repositories should end in `.git'" if spec.source[:git] =~ /github.com/ && spec.source[:git] !~ /.*\.git/
warnings << "Github repositories should end in `.git'" if spec.source[:git] =~ /github.com/ && spec.source[:git] !~ /.*\.git/
warnings << "The description should end with a dot" if spec.description && spec.description !~ /.*\./
warnings << "The summary should end with a dot" if spec.summary !~ /.*\./
unless warnings.empty?
puts "\n[!] The #{spec.name} specification raised the following warnings".yellow
warnings.each { |warn| puts ' - '+ warn }
end
puts
invalid_count = lint_podspecs
if invalid_count == 0
puts lint_passed_message unless config.silent?
else
raise Informative, lint_failed_message(invalid_count)
end
end
private
def path_matches_name?(path, spec)
(path.dirname + "#{spec.name}.podspec").to_s == @name_or_url
def lint_podspecs
specs_count, invalid_count = 0, 0
podspecs_to_lint.each do |podspec_file|
root_spec = Specification.from_file(podspec_file)
specs = root_spec.recursive_subspecs.any? ? root_spec.recursive_subspecs : [root_spec]
specs.each do |spec|
# Show immediatly which pod is being processed.
print " -> #{spec}\r" unless config.silent? || is_repo?
$stdout.flush
linter = Linter.new(spec, podspec_file)
linter.lenient = @only_errors
linter.quick = @quick || is_repo?
invalid_count += 1 unless linter.lint
# This overwrites the previously printed text
puts " -> ".send(lint_result_color(linter)) << spec.to_s unless config.silent? || should_skip?(linter)
print_messages(spec, 'ERROR', linter.errors)
print_messages(spec, 'WARN', linter.warnings)
print_messages(spec, 'NOTE', linter.notes)
puts unless config.silent? || should_skip?(linter)
end
specs_count += specs.count
end
puts "Analyzed #{specs_count} specs in #{podspecs_to_lint.count} podspecs files.\n\n" if is_repo? && !config.silent?
invalid_count
end
def suggested_ref_and_version(repo)
tags = Octokit.tags(:username => repo['owner']['login'], :repo => repo['name']).map {|tag| tag["name"]}
versions_tags = {}
tags.each do |tag|
clean_tag = tag.gsub(/^v(er)? ?/,'')
versions_tags[Gem::Version.new(clean_tag)] = tag if Gem::Version.correct?(clean_tag)
def lint_result_color(linter)
if linter.errors.empty? && linter.warnings.empty?
:green
elsif linter.errors.empty?
:yellow
else
:red
end
version = versions_tags.keys.sort.last || '0.0.1'
data = {:version => version}
if version == '0.0.1'
branches = Octokit.branches(:username => repo['owner']['login'], :repo => repo['name'])
master_name = repo['master_branch'] || 'master'
master = branches.select {|branch| branch['name'] == master_name }.first
data[:ref_type] = ':commit'
data[:ref] = master['commit']['sha']
end
def should_skip?(linter)
is_repo? && linter.errors.empty? && linter.warnings.empty? && linter.notes.empty?
end
def print_messages(spec, type, messages)
return if config.silent?
if spec.platform.name
messages = clean_platfrom_messages(messages)
else
data[:ref_type] = ':tag'
data[:ref] = versions_tags[version]
messages = clean_duplicate_platfrom_messages(messages)
end
messages.each {|msg| puts " - #{type.ljust(5)} | #{msg}"}
end
def clean_platfrom_messages(messages)
messages.map { |l| l.gsub(/ios: /,'').gsub(/osx: /,'') }
end
def clean_duplicate_platfrom_messages(messages)
duplicate_candiates = messages.select {|l| l.include?("ios: ")}
duplicated = duplicate_candiates.select {|l| messages.include?(l.gsub(/ios: /,'osx: ')) }
duplicated.uniq.each do |l|
clean = l.gsub(/ios: /,'')
messages.insert(messages.index(l), clean)
messages.delete(l)
messages.delete('osx: ' + clean)
end
messages
end
def podspecs_to_lint
@podspecs_to_lint ||= begin
if (is_repo?)
files = (config.repos_dir + @repo_or_podspec).glob('**/*.podspec')
elsif @repo_or_podspec
files = [Pathname.new(@repo_or_podspec)]
raise Informative, "[!] Unable to find a spec named #{@repo_or_podspec}".red << "\n\n" unless files[0].exist? && @repo_or_podspec.include?('.podspec')
else
files = Pathname.pwd.glob('*.podspec')
raise Informative, "[!] No specs found in the current directory".red << "\n\n" if files.empty?
end
files
end
end
def is_repo?
@is_repo ||= @repo_or_podspec && (config.repos_dir + @repo_or_podspec).exist? && !@repo_or_podspec.include?('/')
end
def lint_passed_message
( podspecs_to_lint.count == 1 ? "#{podspecs_to_lint.first.basename} passed validation" : "All the specs passed validation" ).green << "\n\n"
end
def lint_failed_message(count)
( podspecs_to_lint.count == 1 ? "[!] The spec did not pass validation" : "[!] #{count} specs failed validation" ).red << "\n\n"
end
# Linter class
#
class Linter
include Config::Mixin
attr_accessor :quick, :lenient
attr_reader :spec, :file
def initialize(spec, podspec_file)
@spec = spec
@file = podspec_file.realpath
end
# Takes an array of podspec files and lints them all
#
# It returns true if the spec passed validation
#
def lint
# If the spec doesn't validate it raises and informative
# TODO: consider raising the informative in the clients of Pod::Specification#validate!
# and just report the errors here
peform_multiplatform_analysis unless quick
# Skip validation if there are errors in the podspec as it would result in a crash
unless podspec_errors.empty?
@errors, @warnings, @notes = podspec_errors, [], ['[!] Fatal errors found skipping the rest of the validation']
return false
end
valid?
end
def valid?
lenient ? errors.empty? : errors.empty? && warnings.empty?
end
def errors
@errors ||= file_patterns_errors + build_errors
end
def warnings
@warnings ||= podspec_warnings + deprecation_warnings
end
def notes
@notes ||= build_warnings
end
# Performs platform specific analysis.
# It requires to download the source at each iteration
#
def peform_multiplatform_analysis
platform_names.each do |platform_name|
set_up_lint_environment
puts "\n\n#{spec} - Analyzing on #{Platform.new platform_name} platform.".green.reversed if config.verbose?
install_pod(platform_name)
puts "Building with xcodebuild.\n".yellow if config.verbose?
xcodebuild_output.concat(xcodebuild_output_for_platfrom(platform_name))
file_patterns_errors.concat(file_patterns_errors_for_platfrom(platform_name))
tear_down_lint_environment
end
end
def platform_names
spec.platform.name ? [spec.platform.name] : [:ios, :osx]
end
def install_pod(platform_name)
podfile = podfile_from_spec(platform_name)
config.verbose
Installer.new(podfile).install!
config.silent
end
def podfile_from_spec(platform_name)
name = spec.name
podspec = file.realpath.to_s
podfile = Pod::Podfile.new do
platform platform_name
dependency name, :podspec => podspec
end
end
def set_up_lint_environment
tmp_dir.rmtree if tmp_dir.exist?
tmp_dir.mkpath
@original_config = Config.instance.clone
config.project_root = tmp_dir
config.project_pods_root = tmp_dir + 'Pods'
config.silent = !config.verbose
config.integrate_targets = false
config.generate_docs = false
end
def tear_down_lint_environment
tmp_dir.rmtree
Config.instance = @original_config
end
def tmp_dir
Pathname.new('/tmp/CocoaPods/Lint')
end
def pod_dir
tmp_dir + 'Pods' + spec.name
end
# @return [Array<String>] List of the fatal defects detected in a podspec
def podspec_errors
messages = []
messages << "Missing name" unless spec.name
messages << "Missing version" unless spec.version
messages << "Missing summary" unless spec.summary
messages << "Missing homepage" unless spec.homepage
messages << "Missing author(s)" unless spec.authors
messages << "Missing source or part_of" unless spec.source || spec.part_of
messages << "Missing source_files" if spec.source_files.empty? && spec.subspecs.empty?
messages << "The name of the spec should match the name of the file" unless names_match?
messages << "Unrecognized platfrom (no value, :ios, :osx)" unless [nil, :ios, :osx].include?(spec.platform.name)
messages += paths_starting_with_a_slash_errors
messages
end
def names_match?
return true unless spec.name
root_name = spec.name.match(/[^\/]*/)[0]
file.basename.to_s == root_name + '.podspec'
end
def paths_starting_with_a_slash_errors
messages = []
%w[source_files resources clean_paths].each do |accessor|
patterns = spec.send(accessor.to_sym)
# Some values are multiplaform
patterns = patterns.is_a?(Hash) ? patterns.values.flatten(1) : patterns
patterns.each do |pattern|
# Skip Filelist that would otherwise be resolved from the working directory resulting
# in a potentially very expensi operation
next if pattern.is_a?(FileList)
invalid = pattern.is_a?(Array) ? pattern.any? { |path| path.start_with?('/') } : pattern.start_with?('/')
if invalid
messages << "Paths cannot start with a slash (#{accessor})"
break
end
end
end
messages
end
# @return [Array<String>] List of the **non** fatal defects detected in a podspec
def podspec_warnings
license = @spec.license || {}
source = @spec.source || {}
text = @file.read
messages = []
messages << "Missing license[:type]" unless license[:type]
messages << "Missing license[:file] or [:text]" unless license[:file] || license[:text]
messages << "The summary is not meaningful" if spec.summary =~ /A short description of/
messages << "The description is not meaningful" if spec.description && spec.description =~ /An optional longer description of/
messages << "The summary should end with a dot" if @spec.summary !~ /.*\./
messages << "The description should end with a dot" if @spec.description !~ /.*\./ && @spec.description != @spec.summary
messages << "Git sources should specify either a tag or a commit" if source[:git] && !source[:commit] && !source[:tag]
messages << "Github repositories should end in `.git'" if github_source? && source[:git] !~ /.*\.git/
messages << "Github repositories should use `https' link" if github_source? && source[:git] !~ /https:\/\/github.com/
messages << "Comments must be deleted" if text =~ /^\w*#\n\w*#/ # allow a single line comment as it is generally used in subspecs
messages
end
def github_source?
@spec.source && @spec.source[:git] =~ /github.com/
end
# It reads a podspec file and checks for strings corresponding
# to features that are or will be deprecated
#
# @return [Array<String>]
def deprecation_warnings
text = @file.read
deprecations = []
deprecations << "`config.ios?' and `config.osx?' are deprecated and will be removed in version 0.7" if text. =~ /config\..?os.?/
deprecations << "The `post_install' hook is reserved for edge cases" if text. =~ /post_install/
deprecations
end
def build_errors
@build_errors ||= xcodebuild_output.select {|msg| msg.include?('error')}
end
def build_warnings
@build_warnings ||= xcodebuild_output - build_errors
end
def xcodebuild_output
@xcodebuild_output ||= []
end
# It creates a podfile in memory and builds a library containing
# the pod for all available platfroms with xcodebuild.
#
# It returns a array of strings
#
def xcodebuild_output_for_platfrom(platform_name)
return [] if `which xcodebuild`.strip.empty?
messages = []
output = Dir.chdir(config.project_pods_root) { `xcodebuild 2>&1` }
clean_output = process_xcode_build_output(output).map {|l| "#{platform_name}: #{l}"}
messages += clean_output
puts(output) if config.verbose?
messages
end
def process_xcode_build_output(output)
output_by_line = output.split("\n")
selected_lines = output_by_line.select do |l|
l.include?('error') && (l !~ /errors? generated\./) \
|| l.include?('warning') && (l !~ /warnings? generated\./)\
|| l.include?('note')
end
selected_lines.map do |l|
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'') # Remove the unnecessary tmp path
new.gsub!(/^ */,' ') # Remove indentation
"XCODEBUILD > " << new # Mark
end
end
def file_patterns_errors
@file_patterns_errors ||= []
end
# It checks that every file pattern specified in a spec yields
# at least one file. It requires the pods to be alredy present
# in the current working directory under Pods/spec.name
#
# It returns a array of messages
#
def file_patterns_errors_for_platfrom(platform_name)
Dir.chdir(config.project_pods_root + spec.name ) do
messages = []
messages += check_spec_files_exists(:source_files, platform_name, '*.{h,m,mm,c,cpp}')
messages += check_spec_files_exists(:resources, platform_name)
messages << "#{platform_name}: license[:file] = '#{spec.license[:file]}' -> did not match any file" if spec.license[:file] && pod_dir.glob(spec.license[:file]).empty?
messages.compact
end
end
def check_spec_files_exists(accessor, platform_name, options = {})
result = []
patterns = spec.send(accessor)[platform_name]
patterns.each do |original_pattern|
pattern = pod_dir + original_pattern
if pattern.directory? && options[:glob]
pattern += options[:glob]
end
result << "#{platform_name}: [#{accessor} = '#{original_pattern}'] -> did not match any file" if pattern.glob.empty?
end
result
end
end
# Templates and github information retrival for spec create
def default_data_for_template(name)
data = {}
data[:name] = name
data[:version] = '0.0.1'
data[:summary] = "A short description of #{name}."
data[:homepage] = "http://EXAMPLE/#{name}"
data[:author_name] = `git config --get user.name`.strip
data[:author_email] = `git config --get user.email`.strip
data[:source_url] = "http://EXAMPLE/#{name}.git"
data[:ref_type] = ':tag'
data[:ref] = '0.0.1'
data
end
......@@ -113,17 +457,25 @@ module Pod
data.merge suggested_ref_and_version(repo)
end
def default_data_for_template(name)
data = {}
data[:name] = name
data[:version] = '0.0.1'
data[:summary] = "A short description of #{name}."
data[:homepage] = "http://EXAMPLE/#{name}"
data[:author_name] = `git config --get user.name`.strip
data[:author_email] = `git config --get user.email`.strip
data[:source_url] = "http://EXAMPLE/#{name}.git"
data[:ref_type] = ':tag'
data[:ref] = '0.0.1'
def suggested_ref_and_version(repo)
tags = Octokit.tags(:username => repo['owner']['login'], :repo => repo['name']).map {|tag| tag["name"]}
versions_tags = {}
tags.each do |tag|
clean_tag = tag.gsub(/^v(er)? ?/,'')
versions_tags[Gem::Version.new(clean_tag)] = tag if Gem::Version.correct?(clean_tag)
end
version = versions_tags.keys.sort.last || '0.0.1'
data = {:version => version}
if version == '0.0.1'
branches = Octokit.branches(:username => repo['owner']['login'], :repo => repo['name'])
master_name = repo['master_branch'] || 'master'
master = branches.select {|branch| branch['name'] == master_name }.first
data[:ref_type] = ':commit'
data[:ref] = master['commit']['sha']
else
data[:ref_type] = ':tag'
data[:ref] = versions_tags[version]
end
data
end
......@@ -183,16 +535,17 @@ Pod::Spec.new do |s|
s.description = 'An optional longer description of #{data[:name]}.'
# If this Pod runs only on iOS or OS X, then specify that with one of
# these, or none if it runs on both platforms.
# If the pod runs on both plafroms but presents different deployment
# targets, source files, etc. create two different pods: `#{data[:name]}-iOS'
# and `#{data[:name]}-OSX'.
# If this Pod runs only on iOS or OS X, then specify the platform and
# the deployment target.
#
# s.platform = :ios, '5.0'
# s.platform = :ios
# s.platform = :ios, { :deployment_target => "5.0" }
# s.platform = :osx
# s.platform = :osx, { :deployment_target => "10.7" }
# If this Pod runs on boths platforms, then specify the deployment
# targets.
#
# s.ios.deployment_target = '5.0'
# s.osx.deployment_target = '10.7'
# A list of resources included with the Pod. These are copied into the
# target bundle with a build phase script.
......@@ -240,9 +593,10 @@ Pod::Spec.new do |s|
#
# s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(SDKROOT)/usr/include/libxml2' }
end
SPEC
# ――― INFO ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
end
SPEC
end
def semantic_versioning_notice(repo_id, repo)
return <<-EOS
......@@ -271,7 +625,7 @@ $ git push --tags
After commiting the specification, consider opening a ticket with the template displayed above:
- link: https://github.com/#{repo_id}/issues/new
- title: Please add semantic version tags
EOS
EOS
end
end
end
......
......@@ -12,13 +12,13 @@ module Pod
attr_accessor :repos_dir, :project_root, :project_pods_root
attr_accessor :clean, :verbose, :silent
attr_accessor :doc, :doc_install, :force_doc
attr_accessor :generate_docs, :doc_install, :force_doc
attr_accessor :integrate_targets
alias_method :clean?, :clean
alias_method :verbose?, :verbose
alias_method :silent?, :silent
alias_method :doc?, :doc # TODO rename to generate_docs?
alias_method :generate_docs?, :generate_docs
alias_method :doc_install?, :doc_install
alias_method :force_doc?, :force_doc
alias_method :integrate_targets?, :integrate_targets
......@@ -26,7 +26,7 @@ module Pod
def initialize
@repos_dir = Pathname.new(File.expand_path("~/.cocoapods"))
@verbose = @silent = @force_doc = false
@clean = @doc = @doc_install = @integrate_targets = true
@clean = @generate_docs = @doc_install = @integrate_targets = true
end
def project_root
......@@ -51,18 +51,15 @@ module Pod
Podfile.from_file(project_podfile) if project_podfile.exist?
end
end
attr_writer :podfile
def ios?
require 'colored'
caller.find { |line| line =~ /^(.+.podspec):\d*/ }
puts "[!] The use of `config.ios?` is deprecated and will be removed in version 0.7.#{" Called from: #{$1}" if $1}".red
# TODO: deprecate in 0.7
podfile.target_definitions[:default].platform == :ios if podfile
end
def osx?
require 'colored'
caller.find { |line| line =~ /^(.+.podspec):\d*/ }
puts "[!] The use of `config.osx?` is deprecated and will be removed in version 0.7.#{" Called from: #{$1}" if $1}".red
# TODO: deprecate in 0.7
podfile.target_definitions[:default].platform == :osx if podfile
end
......
......@@ -60,13 +60,21 @@ module Pod
end
def clean
# no-op
if download_only?
FileUtils.rm_f(tmp_path)
else
super
end
end
def tarball_url_for(id)
original_url, username, reponame = *(url.match(/[:\/]([\w\-]+)\/([\w\-]+)\.git/).to_a)
"https://github.com/#{username}/#{reponame}/tarball/#{id}"
end
def tmp_path
target_path + "tarball.tar.gz"
end
private
......@@ -75,8 +83,6 @@ module Pod
end
def download_and_extract_tarball(id)
tmp_path = target_path + "tarball.tar.gz"
File.open(tmp_path, "w+") do |tmpfile|
open tarball_url_for(id) do |archive|
tmpfile.write Zlib::GzipReader.new(archive).read
......@@ -84,8 +90,6 @@ module Pod
system "tar xf #{tmpfile.path} -C #{target_path} --strip-components 1"
end
FileUtils.rm_f(tmp_path)
end
end
end
......
......@@ -7,7 +7,7 @@ module Pod
raise Informative, "Unable to locate the executable `#{name}'"
end
if Config.instance.verbose?
puts "#{bin} #{command}"
puts "-> #{bin} #{command}"
`#{bin} #{command} 1>&2`
else
`#{bin} #{command} 2> /dev/null`
......
......@@ -65,13 +65,19 @@ module Pod
'--ignore', '.m',
'--keep-undocumented-objects',
'--keep-undocumented-members',
'--keep-intermediate-files'
'--keep-intermediate-files',
'--exit-threshold', '2'
# appledoc exits with 1 if a warning was logged
]
index = index_file
options += ['--index-desc', index] if index
options += spec_appledoc_options
end
def already_installed?
Pathname.new(File.expand_path("~/Library/Developer/Shared/Documentation/DocSets/org.cocoapods.#{name.gsub(/ /,'-')}.docset")).exist?
end
def generate(install = false)
options = appledoc_options
options += ['--output', @target_path.to_s]
......@@ -82,9 +88,9 @@ module Pod
@pod.chdir do
appledoc Escape.shell_command(options)
end
# appledoc exits with 1 if a warning was logged
if $?.exitstatus >= 2
raise "Appledoc encountered an error (exitstatus: #{$?.exitstatus})."
if $?.exitstatus != 0
puts "[!] Appledoc encountered an error (exitstatus: #{$?.exitstatus}), an update might be available to solve the issue." unless config.silent?
end
rescue Informative
......
module Pod
module Generator
class DummySource
def save_as(pathname)
pathname.open('w') do |source|
source.puts "@interface PodsDummy : NSObject"
source.puts "@end"
source.puts "@implementation PodsDummy"
source.puts "@end"
end
end
end
end
end
......@@ -14,6 +14,8 @@ module Pod
# FIXME: pass this into the installer as a parameter
@sandbox = Sandbox.new(config.project_pods_root)
@resolver = Resolver.new(@podfile, @sandbox)
# TODO: remove in 0.7 (legacy support for config.ios? and config.osx?)
config.podfile = podfile
end
def lock_file
......@@ -59,9 +61,14 @@ module Pod
end
end
if (should_install && config.doc?) || config.force_doc?
puts "Installing Documentation for #{pod.specification}".green if config.verbose?
Generator::Documentation.new(pod).generate(config.doc_install?)
if (should_install && config.generate_docs?) || config.force_doc?
doc_generator = Generator::Documentation.new(pod)
if doc_generator.already_installed?
puts "Using Existing Documentation for #{pod.specification}".green if config.verbose?
else
puts "Installing Documentation for #{pod.specification}".green if config.verbose?
doc_generator.generate(config.doc_install?)
end
end
end
end
......@@ -87,6 +94,7 @@ module Pod
end
generate_lock_file!(pods)
generate_dummy_source
puts "* Running post install hooks" if config.verbose?
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
......@@ -156,6 +164,19 @@ module Pod
end
end
def generate_dummy_source
filename = "PodsDummy.m"
pathname = Pathname.new(sandbox.root + filename)
Generator::DummySource.new.save_as(pathname)
project_file = project.files.new('path' => filename)
project.group("Targets Support Files") << project_file
target_installers.each do |target_installer|
target_installer.target.source_build_phases.first << project_file
end
end
def specs_by_target
@specs_by_target ||= @resolver.resolve
end
......
......@@ -75,9 +75,8 @@ module Pod
support_files_group = @project.group("Targets Support Files").create_group(@target_definition.label)
support_files_group.create_files(target_support_files)
xcconfig_file = support_files_group.files.where(:path => @target_definition.xcconfig_name)
configure_build_configurations(xcconfig_file)
create_files(pods, sandbox)
end
......@@ -113,7 +112,7 @@ module Pod
end
def default_ld_flags
flags = %w{-ObjC -all_load}
flags = %w{-ObjC}
flags << '-fobjc-arc' if @podfile.set_arc_compatibility_flag? && self.requires_arc
flags.join(" ")
end
......
......@@ -3,19 +3,19 @@ module Pod
attr_reader :specification
attr_reader :sandbox
attr_reader :platform
def initialize(specification, sandbox, platform)
@specification, @sandbox, @platform = specification, sandbox, platform
end
def self.from_podspec(podspec, sandbox, platform)
new(Specification.from_file(podspec), sandbox, platform)
end
def root
@sandbox.root + specification.name
end
def to_s
if specification.local?
"#{specification} [LOCAL]"
......@@ -23,28 +23,28 @@ module Pod
specification.to_s
end
end
def name
specification.name
end
def create
root.mkpath unless exists?
end
def exists?
root.exist?
end
def chdir(&block)
create
Dir.chdir(root, &block)
end
def implode
root.rmtree if exists?
end
def clean
clean_paths.each { |path| FileUtils.rm_rf(path) }
end
......@@ -54,19 +54,19 @@ module Pod
@sandbox.root + specification.name + prefix_header
end
end
def source_files
expanded_paths(specification.source_files, :glob => '*.{h,m,mm,c,cpp}', :relative_to_sandbox => true)
end
def absolute_source_files
expanded_paths(specification.source_files, :glob => '*.{h,m,mm,c,cpp}')
end
def clean_paths
expanded_paths(specification.clean_paths)
end
def resources
expanded_paths(specification.resources, :relative_to_sandbox => true)
end
......@@ -90,13 +90,13 @@ module Pod
@sandbox.add_header_files(namespaced_path, files)
end
end
def add_to_target(target)
implementation_files.each do |file|
target.add_source_file(file, nil, specification.compiler_flags[@platform.name].strip)
end
end
def requires_arc?
specification.requires_arc
end
......@@ -104,13 +104,13 @@ module Pod
def dependencies
specification.dependencies[@platform.name]
end
private
def implementation_files
source_files.select { |f| f.extname != '.h' }
end
def relative_root
root.relative_path_from(@sandbox.root)
end
......@@ -125,7 +125,7 @@ module Pod
mappings
end
end
def expanded_paths(platforms_with_patterns, options = {})
patterns = platforms_with_patterns.is_a?(Hash) ? platforms_with_patterns[@platform.name] : platforms_with_patterns
patterns.map do |pattern|
......
......@@ -8,22 +8,29 @@ module Pod
new :osx
end
attr_reader :options
attr_reader :deployment_target
def initialize(symbolic_name, options = {})
def initialize(symbolic_name, deployment_target = nil)
@symbolic_name = symbolic_name
@options = options
if deployment_target
version = deployment_target.is_a?(Hash) ? deployment_target[:deployment_target] : deployment_target # backwards compatibility from 0.6
@deployment_target = Pod::Version.create(version)
end
end
def name
@symbolic_name
end
def deployment_target= (version)
@deployment_target = Pod::Version.create(version)
end
def ==(other_platform_or_symbolic_name)
if other_platform_or_symbolic_name.is_a?(Symbol)
@symbolic_name == other_platform_or_symbolic_name
else
self == (other_platform_or_symbolic_name.name)
self.name == (other_platform_or_symbolic_name.name) && self.deployment_target == other_platform_or_symbolic_name.deployment_target
end
end
......@@ -51,12 +58,6 @@ module Pod
name.nil?
end
def deployment_target
if (options && opt = options[:deployment_target])
Pod::Version.new(opt)
end
end
def requires_legacy_ios_archs?
return unless deployment_target
(name == :ios) && (deployment_target < Pod::Version.new("4.3"))
......
......@@ -4,7 +4,7 @@ module Pod
include Config::Mixin
attr_reader :name, :target_dependencies
attr_accessor :xcodeproj, :link_with, :platform, :parent, :exclusive
def initialize(name, options = {})
......@@ -64,7 +64,8 @@ module Pod
# Returns a path, which is relative to the project_root, relative to the
# `$(SRCROOT)` of the user's project.
def relative_to_srcroot(path)
(config.project_root + path).relative_path_from(xcodeproj.dirname)
raise Informative, "[!] Unable to find an Xcode project to integrate".red unless xcodeproj || !config.integrate_targets
xcodeproj ? (config.project_root + path).relative_path_from(xcodeproj.dirname) : path
end
def relative_pods_root
......@@ -368,7 +369,7 @@ module Pod
# This is used as a workaround for a compiler bug with non-ARC projects.
# (see https://github.com/CocoaPods/CocoaPods/issues/142)
#
# This was originally done automatically but libtool as of Xcode 4.3.2 no
# This was originally done automatically but libtool as of Xcode 4.3.2 no
# longer seems to support the -fobjc-arc flag. Therefore it now has to be
# enabled explicitly using this method.
#
......@@ -397,7 +398,7 @@ module Pod
def generate_bridge_support?
@generate_bridge_support
end
def set_arc_compatibility_flag?
@set_arc_compatibility_flag
end
......
......@@ -20,10 +20,10 @@ module Pod
targets_and_specs = {}
@podfile.target_definitions.values.each do |target_definition|
puts "\nResolving dependencies for target `#{target_definition.name}'".green if config.verbose?
puts "\nResolving dependencies for target `#{target_definition.name}' (#{target_definition.platform})".green if config.verbose?
@loaded_specs = []
# TODO @podfile.platform will change to target_definition.platform
find_dependency_sets(@podfile, target_definition.dependencies, target_definition.platform)
find_dependency_sets(@podfile, target_definition.dependencies, target_definition)
targets_and_specs[target_definition] = @specs.values_at(*@loaded_specs).sort_by(&:name)
end
......@@ -56,11 +56,11 @@ module Pod
end
end
def find_dependency_sets(dependent_specification, dependencies, platform)
def find_dependency_sets(dependent_specification, dependencies, target_definition)
@log_indent += 1
dependencies.each do |dependency|
puts ' ' * @log_indent + "- #{dependency}" if config.verbose?
set = find_cached_set(dependency, platform)
set = find_cached_set(dependency, target_definition.platform)
set.required_by(dependent_specification)
# Ensure we don't resolve the same spec twice for one target
unless @loaded_specs.include?(dependency.name)
......@@ -71,24 +71,21 @@ module Pod
if dependency.subspec_dependency?
spec = spec.subspec_by_name(dependency.name)
end
validate_platform!(spec)
@loaded_specs << spec.name
@specs[spec.name] = spec
# And recursively load the dependencies of the spec.
# TODO fix the need to return an empty arrayf if there are no deps for the given platform
find_dependency_sets(spec, (spec.dependencies[platform.to_sym] || []), platform)
find_dependency_sets(spec, (spec.dependencies[target_definition.platform.to_sym] || []), target_definition)
end
validate_platform!(spec || @specs[dependency.name], target_definition)
end
@log_indent -= 1
end
def validate_platform!(spec)
plaform = @podfile.target_definitions[:default].platform
unless plaform.support?(spec.platform)
raise Informative, "The platform required by the Podfile `#{plaform}' does not match that of #{spec} `#{spec.platform}'"
def validate_platform!(spec, target)
unless spec.platforms.any? { |platform| target.platform.support?(platform) }
raise Informative, "[!] The platform of the target `#{target.name}' (#{target.platform}) is not compatible with `#{spec}' which has a minimun requirement of #{spec.platforms.join(' - ')}.".red
end
end
end
......
......@@ -34,6 +34,7 @@ module Pod
@define_for_platforms = [:osx, :ios]
@clean_paths, @subspecs = [], []
@dependencies, @source_files, @resources = { :ios => [], :osx => [] }, { :ios => [], :osx => [] }, { :ios => [], :osx => [] }
@deployment_target = {}
@platform = Platform.new(nil)
@xcconfig = { :ios => Xcodeproj::Config.new, :osx => Xcodeproj::Config.new }
@compiler_flags = { :ios => '', :osx => '' }
......@@ -114,17 +115,14 @@ module Pod
end
def platform=(platform)
if platform.class == Array
name = platform[0]
options = platform[1]
else
name = platform
options = nil
end
@platform = Platform.new(name, options)
@platform = Platform.new(*platform)
end
attr_reader :platform
def platforms
@platform.nil? ? @define_for_platforms.map { |platfrom| Platform.new(platfrom, @deployment_target[platfrom]) } : [platform]
end
def requires_arc=(requires_arc)
self.compiler_flags = '-fobjc-arc' if requires_arc
@requires_arc = requires_arc
......@@ -157,7 +155,7 @@ module Pod
@specification, @platform = specification, platform
end
%w{ source_files= resource= resources= xcconfig= framework= frameworks= library= libraries= compiler_flags= dependency }.each do |method|
%w{ source_files= resource= resources= xcconfig= framework= frameworks= library= libraries= compiler_flags= deployment_target= dependency }.each do |method|
define_method(method) do |args|
@specification._on_platform(@platform) do
@specification.send(method, args)
......@@ -181,6 +179,11 @@ module Pod
end
attr_reader :source_files
def deployment_target=(version)
raise Informative, "The deployment target must be defined per platform like s.ios.deployment_target = '5.0'" unless @define_for_platforms.count == 1
@deployment_target[@define_for_platforms.first] = version
end
def resources=(patterns)
@define_for_platforms.each do |platform|
@resources[platform] = pattern_list(patterns)
......@@ -340,49 +343,6 @@ module Pod
"#<#{self.class.name} for #{to_s}>"
end
def validate!
missing = []
missing << "name" unless name
missing << "version" unless version
missing << "summary" unless summary
missing << "homepage" unless homepage
missing << "author(s)" unless authors
missing << "source or part_of" unless source || part_of
missing << "source_files" if source_files.empty? && subspecs.empty?
# TODO
# * validate subspecs
incorrect = []
allowed = [nil, :ios, :osx]
incorrect << "platform - accepted values are (no value, :ios, :osx)" unless allowed.include?(platform.name)
{
:source_files => source_files.values,
:resources => resources.values,
:clean_paths => clean_paths
}.each do |name, paths|
if paths.flatten.any? { |path| path.start_with?("/") }
incorrect << "#{name} - paths cannot start with a slash"
end
end
if source && source[:local] && source[:local].start_with?("/")
incorrect << "source[:local] - paths cannot start with a slash"
end
no_errors_found = missing.empty? && incorrect.empty?
unless no_errors_found
message = "\n[!] The #{name || 'nameless'} specification is incorrect\n".red
missing.each {|s| message << " - Missing #{s}\n"}
incorrect.each {|s| message << " - Incorrect #{s}\n"}
message << "\n"
raise Informative, message
end
no_errors_found
end
# This is a convenience method which gets called after all pods have been
# downloaded, installed, and the Xcode project and related files have been
# generated. (It receives the Pod::Installer::Target instance for the current
......@@ -436,7 +396,7 @@ module Pod
end
# Override the getters to always return the value of the top level parent spec.
[:version, :summary, :platform, :license, :authors, :requires_arc, :compiler_flags, :documentation].each do |attr|
[:version, :summary, :platform, :license, :authors, :requires_arc, :compiler_flags, :documentation, :homepage].each do |attr|
define_method(attr) { top_level_parent.send(attr) }
end
......
......@@ -41,6 +41,11 @@ module Pod
get_value(set, :gh_forks)
end
def github_pushed_at(set)
github_stats_if_needed(set)
get_value(set, :pushed_at)
end
private
def cache
......@@ -88,9 +93,10 @@ module Pod
end
cache[set.name] ||= {}
set_value(set, :gh_watchers, repo['watchers'])
set_value(set, :gh_forks, repo['forks'])
set_value(set, :gh_date, Time.now)
set_value(set, :gh_watchers, repo['watchers'])
set_value(set, :gh_forks, repo['forks'])
set_value(set, :pushed_at, repo['pushed_at'])
set_value(set, :gh_date, Time.now)
save_cache
end
end
......
......@@ -22,15 +22,16 @@ describe Pod::Command::Presenter do
end
it "presents the stats of a specification set" do
repo = {"forks"=>42, "watchers"=>318}
repo = { "forks"=>42, "watchers"=>318, "pushed_at"=>"2011-01-26T19:06:43Z" }
Octokit.expects(:repo).with("robbiehanson/CocoaLumberjack").returns(repo)
presenter = Presenter.new(argv('--stats'))
presenter = Presenter.new(argv('--stats', '--no-color'))
output = presenter.describe(@set)
output.should.include? 'Author: Robbie Hanson'
output.should.include? 'License: BSD'
output.should.include? 'Platform: iOS - OS X'
output.should.include? 'Watchers: 318'
output.should.include? 'Forks: 42'
output.should.include? 'Pushed: more than a year ago'
end
it "should print at least one subspec" do
......
require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Command::Push do
extend SpecHelper::Command
extend SpecHelper::Git
extend SpecHelper::TemporaryDirectory
it "complains for wrong parameters" do
lambda { run_command('push') }.should.raise Pod::Command::Help
lambda { run_command('push', '--allow-warnings') }.should.raise Pod::Command::Help
lambda { run_command('push', '--wrong-option') }.should.raise Pod::Command::Help
end
it "complains if it can't find the repo" do
repo1 = add_repo('repo1', fixture('spec-repos/master'))
Dir.chdir(fixture('banana-lib')) do
lambda { run_command('push', 'repo2') }.should.raise Pod::Informative
end
end
it "complains if it can't find a spec" do
repo1 = add_repo('repo1', fixture('spec-repos/master'))
lambda { run_command('push', 'repo1') }.should.raise Pod::Informative
end
it "it raises if the pod is not validated" do
repo1 = add_repo('repo1', fixture('spec-repos/master'))
git('repo1', 'checkout master') # checkout master, because the fixture is a submodule
repo2 = add_repo('repo2', repo1.dir)
git_config('repo2', 'remote.origin.url').should == (tmp_repos_path + 'repo1').to_s
Dir.chdir(fixture('banana-lib')) do
lambda { command('push', 'repo2', '--silent').run }.should.raise Pod::Informative
end
# (repo1.dir + 'BananaLib/1.0/BananaLib.podspec').read.should.include 'Added!'
end
before do
# prepare the repos
@upstream = add_repo('upstream', fixture('spec-repos/master'))
git('upstream', 'checkout -b master') # checkout master, because the fixture is a submodule
@local_repo = add_repo('local_repo', @upstream.dir)
git_config('local_repo', 'remote.origin.url').should == (tmp_repos_path + 'upstream').to_s
git('upstream', 'checkout -b no-master') # checkout no-master, to allow push in a non-bare repository
# prepare the spec
spec_fix = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
spec_add = spec_fix.gsub(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s)
spec_add.gsub!(/'JSONKit'/, "'PushTest'")
File.open(temporary_directory + 'JSONKit.podspec', 'w') {|f| f.write(spec_fix) }
File.open(temporary_directory + 'PushTest.podspec', 'w') {|f| f.write(spec_add) }
end
it "refuses to push if the repo is not clean" do
File.open(@local_repo.dir + 'README', 'w') {|f| f.write('Added!') }
(@local_repo.dir + 'README').read.should.include 'Added!'
cmd = command('push', 'local_repo')
cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { lambda { cmd.run }.should.raise Pod::Informative }
git('upstream', 'checkout master') # checkout master, because the fixture is a submodule
(@upstream.dir + 'PushTest/1.4/PushTest.podspec').should.not.exist?
end
it "sucessfully pushes a spec" do
cmd = command('push', 'local_repo')
cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { cmd.run }
cmd.output.should.include('[Add] PushTest (1.4)')
cmd.output.should.include('[Fix] JSONKit (1.4)')
git('upstream', 'checkout master') # checkout master, because the fixture is a submodule
(@upstream.dir + 'PushTest/1.4/PushTest.podspec').read.should.include('PushTest')
end
end
......@@ -3,6 +3,7 @@ require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Search" do
extend SpecHelper::Command
extend SpecHelper::Git
extend SpecHelper::TemporaryDirectory
before do
config.repos_dir = fixture('spec-repos')
......@@ -19,6 +20,7 @@ describe "Pod::Command::Search" do
end
it "complains for wrong parameters" do
lambda { run_command('search') }.should.raise Pod::Command::Help
lambda { run_command('search', 'too', 'many') }.should.raise Pod::Command::Help
lambda { run_command('search', 'too', '--wrong') }.should.raise Pod::Command::Help
lambda { run_command('search', '--wrong') }.should.raise Pod::Command::Help
......
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Spec" do
describe Pod::Command::Spec do
extend SpecHelper::Command
extend SpecHelper::Github
extend SpecHelper::TemporaryDirectory
it "runs with correct parameters" do
lambda{ run_command('spec', 'create', 'Bananas') }.should.not.raise
expect_github_repo_request
expect_github_user_request
expect_github_tags_request
lambda{ run_command('spec', 'create', 'https://github.com/lukeredpath/libPusher.git') }.should.not.raise
end
it "complains for wrong parameters" do
lambda { run_command('spec') }.should.raise Pod::Command::Help
lambda { run_command('spec', 'create') }.should.raise Pod::Command::Help
lambda { run_command('spec', '--create') }.should.raise Pod::Command::Help
lambda { run_command('spec', 'NAME') }.should.raise Pod::Command::Help
lambda { run_command('spec', 'createa') }.should.raise Pod::Command::Help
lambda { run_command('spec', 'create') }.should.raise Pod::Command::Help
lambda { run_command('lint', 'agument1', '2') }.should.raise Pod::Command::Help
end
end
describe "Pod::Command::Spec#create" do
extend SpecHelper::Command
extend SpecHelper::Github
extend SpecHelper::TemporaryDirectory
extend SpecHelper::Git
it "creates a new podspec stub file" do
run_command('spec', 'create', 'Bananas')
......@@ -50,6 +51,22 @@ describe "Pod::Command::Spec" do
spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' }
end
it "accepts a name when creating a podspec form github" do
expect_github_repo_request
expect_github_user_request
expect_github_tags_request
run_command('spec', 'create', 'other_name', 'https://github.com/lukeredpath/libPusher.git')
path = temporary_directory + 'other_name.podspec'
spec = Pod::Specification.from_file(path)
spec.name.should == 'other_name'
spec.license.should == { :type => "MIT", :file => "LICENSE" }
spec.version.should == Pod::Version.new('1.3')
spec.summary.should == 'An Objective-C interface to Pusher (pusherapp.com)'
spec.homepage.should == 'https://github.com/lukeredpath/libPusher'
spec.authors.should == {"Luke Redpath"=>"luke@lukeredpath.co.uk"}
spec.source.should == { :git => 'https://github.com/lukeredpath/libPusher.git', :tag => 'v1.3' }
end
it "correctly suggests the head commit if a suitable tag is not available on github" do
expect_github_repo_request
expect_github_user_request
......@@ -71,8 +88,53 @@ describe "Pod::Command::Spec" do
output.should.include 'MARKDOWN TEMPLATE'
output.should.include 'Please add semantic version tags'
end
end
describe "Pod::Command::Spec#lint" do
extend SpecHelper::Command
extend SpecHelper::TemporaryDirectory
extend SpecHelper::Git
before do
config.repos_dir = fixture('spec-repos')
end
after do
config.repos_dir = tmp_repos_path
end
it "lints a repo" do
# The fixture has an error due to a name mismatch
cmd = command('spec', 'lint', 'master')
lambda { cmd.run }.should.raise Pod::Informative
cmd.output.should.include "InAppSettingKit (0.0.1)\n - ERROR | The name of the spec should match the name of the file"
cmd.output.should.include "WARN"
end
it "complains if no repo name or url are provided and there a no specs in the current working directory" do
Dir.chdir(fixture('spec-repos') + 'master/JSONKit/') do
lambda { command('spec', 'lint').run }.should.raise Pod::Informative
end
end
it "lints the current working directory" do
Dir.chdir(fixture('spec-repos') + 'master/JSONKit/1.4/') do
output = command('spec', 'lint', '--quick', '--only-errors').run
output.should.include "passed validation"
end
end
it "lints a givent podspec" do
spec_file = fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec'
cmd = command('spec', 'lint', '--quick', spec_file.to_s)
lambda { cmd.run }.should.raise Pod::Informative
cmd.output.should.include "Missing license[:file] or [:text]"
end
it "respects the -only--errors option" do
spec_file = fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec'
cmd = command('spec', 'lint', '--quick', '--only-errors', spec_file.to_s)
lambda { cmd.run }.should.not.raise
cmd.output.should.include "Missing license[:file] or [:text]"
end
end
......@@ -84,9 +84,21 @@ describe "Pod::Downloader" do
downloader = Pod::Downloader.for_pod(@pod)
VCR.use_cassette('tarballs', :record => :new_episodes) { downloader.download }
downloader.clean
(@pod.root + 'tarball.tar.gz').should.not.exist
end
it "removes the .git directory when cleaning" do
@pod.specification.stubs(:source).returns(
:git => "git://github.com/lukeredpath/libPusher.git", :download_only => false
)
downloader = Pod::Downloader.for_pod(@pod)
downloader.download
downloader.clean
(@pod.root + '.git').should.not.exist
end
end
describe "for Mercurial" do
......
......@@ -45,7 +45,7 @@ else
@config_before = config
create_config!
config.doc = false
config.generate_docs = false
end
after do
......@@ -118,6 +118,26 @@ else
'DEPENDENCIES' => ["Reachability (from `#{url}')"]
}
end
it "install a dummy source file" do
create_config!
podfile = Pod::Podfile.new do
self.platform :ios
xcodeproj 'dummy'
dependency do |s|
s.name = 'JSONKit'
s.version = '1.2'
s.source = { :git => SpecHelper.fixture('integration/JSONKit').to_s, :tag => 'v1.2' }
s.source_files = 'JSONKit.*'
end
end
installer = SpecHelper::Installer.new(podfile)
installer.install!
dummy = (config.project_pods_root + 'PodsDummy.m').read
dummy.should.include?('@implementation PodsDummy')
end
it "installs a library with a podspec defined inline" do
podfile = Pod::Podfile.new do
......@@ -188,6 +208,8 @@ else
dependency 'SSToolkit'
end
Pod::Generator::Documentation.any_instance.stubs(:already_installed?).returns(false)
installer = SpecHelper::Installer.new(podfile)
installer.install!
......
......@@ -9,6 +9,7 @@ end
module SpecHelper
module Command
def command(*argv)
argv << '--no-color'
Pod::Command.parse(*argv)
end
......
require File.expand_path('../../../spec_helper', __FILE__)
describe "Pod::Command::Spec::Linter" do
extend SpecHelper::TemporaryDirectory
def write_podspec(text, name = 'JSONKit.podspec')
file = temporary_directory + 'JSONKit.podspec'
File.open(file, 'w') {|f| f.write(text) }
spec = Pod::Specification.from_file(file)
[spec, file]
end
def stub_podspec(pattern = nil, replacement = nil)
spec = (fixture('spec-repos') + 'master/JSONKit/1.4/JSONKit.podspec').read
spec.gsub!(/https:\/\/github\.com\/johnezang\/JSONKit\.git/, fixture('integration/JSONKit').to_s)
spec.gsub!(pattern, replacement) if pattern && replacement
spec
end
it "fails a specifications that does not contain the minimum required attributes" do
spec, file = write_podspec('Pod::Spec.new do |s| end')
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.join(' | ') =~ /name.*version.*summary.*homepage.*authors.*(source.*part_of).*source_files/
end
it "fails specifications if the name does not match the name of the file" do
spec, file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKitAAA'"))
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
linter.errors[0].should =~ /The name of the spec should match the name of the file/
end
it "fails a specification if a path starts with a slash" do
spec, file = write_podspec(stub_podspec(/s.source_files = 'JSONKit\.\*'/, "s.source_files = '/JSONKit.*'"))
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
linter.errors[0].should =~ /Paths cannot start with a slash/
end
it "fails a specification if the plafrom is unrecognized" do
spec, file = write_podspec(stub_podspec(/s.name *= 'JSONKit'/, "s.name = 'JSONKit'\ns.platform = :iososx\n"))
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = true, true
linter.lint.should == false
linter.errors.count.should == 1
linter.errors[0].should =~ /Unrecognized platfrom/
end
it "fails validation if the specification contains warnings" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = false, true
linter.lint.should == false
linter.errors.should.be.empty
linter.warnings.should.not.be.empty
end
it "validates in lenient mode if there are no erros but there are warnings" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = true, true
linter.lint.should == true
linter.errors.should.be.empty
linter.warnings.should.not.be.empty
end
it "respects quick mode" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.expects(:peform_multiplatform_analysis).never
linter.expects(:install_pod).never
linter.expects(:xcodebuild_output_for_platfrom).never
linter.expects(:file_patterns_errors_for_platfrom).never
linter.lenient, linter.quick = false, true
linter.lint
end
it "produces deprecation notices" do
spec, file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\n if config.ios?\nend"))
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = false, true
linter.lint.should == false
linter.errors.should.be.empty
linter.warnings.join(' | ').should =~ /`config.ios\?' and `config.osx\?' are deprecated and will be removed in version 0.7/
end
it "uses xcodebuild to generate notes and warnings" do
spec, file = write_podspec(stub_podspec)
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.lenient, linter.quick = false, false
linter.lint.should == false
linter.notes.join(' | ').should.include "JSONKit/JSONKit.m:1640:27: warning: equality comparison with extraneous parentheses" unless `which xcodebuild`.strip.empty?
end
it "checks for file patterns" do
spec, file = write_podspec(stub_podspec(/s\.source_files = 'JSONKit\.\*'/, "s.source_files = 'JSONKit.*'\ns.resources = 'WRONG_FOLDER'"))
linter = Pod::Command::Spec::Linter.new(spec, file)
linter.stubs(:xcodebuild_output_for_platfrom).returns([])
linter.lenient, linter.quick = false, false
linter.lint.should == false
linter.errors.join(' | ').should.include "[resources = 'WRONG_FOLDER'] -> did not match any file"
end
end
......@@ -36,6 +36,7 @@ describe Pod::Generator::Documentation do
'--keep-undocumented-objects',
'--keep-undocumented-members',
'--keep-intermediate-files',
'--exit-threshold', '2',
'--index-desc', 'README',
# TODO We need to either make this a hash so that options can be merged
# or not use any defaults in case an options are specified.
......
require File.expand_path('../../../spec_helper', __FILE__)
describe Pod::Generator::DummySource do
extend SpecHelper::TemporaryDirectory
before do
setup_temporary_directory
end
after do
teardown_temporary_directory
end
it "generates a dummy sourcefile with the appropriate class" do
generator = Pod::Generator::DummySource.new
file = temporary_directory + 'PodsDummy.m'
generator.save_as(file)
file.read.should == <<-EOS
@interface PodsDummy : NSObject
@end
@implementation PodsDummy
@end
EOS
end
end
......@@ -26,8 +26,8 @@ describe "Pod::Installer" do
@xcconfig['ALWAYS_SEARCH_USER_PATHS'].should == 'YES'
end
it "configures the project to load categories from the static library" do
@xcconfig['OTHER_LDFLAGS'].should == '-ObjC -all_load'
it "configures the project to load all members that implement Objective-c classes or categories from the static library" do
@xcconfig['OTHER_LDFLAGS'].should == '-ObjC'
end
it "sets the PODS_ROOT build variable" do
......
......@@ -18,36 +18,44 @@ describe Pod::Platform do
@platform.should == Pod::Platform.new(:ios)
end
it "can be compared for equality with another platform with the same symbolic name and the same deployment target" do
@platform.should.not == Pod::Platform.new(:ios, '4.0')
Pod::Platform.new(:ios, '4.0').should == Pod::Platform.new(:ios, '4.0')
end
it "can be compared for equality with a matching symbolic name (backwards compatibility reasons)" do
@platform.should == :ios
end
it "presents an accurate string representation" do
@platform.to_s.should == "iOS"
@platform.to_s.should == "iOS"
Pod::Platform.new(:osx).to_s.should == 'OS X'
Pod::Platform.new(nil).to_s.should == "iOS - OS X"
Pod::Platform.new(:ios, { :deployment_target => '5.0.0' }).to_s.should == 'iOS 5.0.0'
Pod::Platform.new(:osx, { :deployment_target => '10.7' }).to_s.should == 'OS X 10.7'
end
it "correctly indicates if it supports another platfrom" do
ios4 = Pod::Platform.new(:ios, { :deployment_target => '4.0.0' })
ios5 = Pod::Platform.new(:ios, { :deployment_target => '5.0.0' })
ios5.should.support?(ios4)
ios4.should.not.support?(ios5)
osx6 = Pod::Platform.new(:osx, { :deployment_target => '10.6' })
osx7 = Pod::Platform.new(:osx, { :deployment_target => '10.7' })
osx7.should.support?(osx6)
osx6.should.not.support?(osx7)
both = Pod::Platform.new(nil)
both.should.support?(ios4)
both.should.support?(osx6)
both.should.support?(nil)
Pod::Platform.new(:ios, '5.0.0').to_s.should == 'iOS 5.0.0'
Pod::Platform.new(:osx, '10.7').to_s.should == 'OS X 10.7'
end
it "uses it's name as it's symbold version" do
@platform.to_sym.should == :ios
end
it "allows to specify the deployment target on initialization" do
p = Pod::Platform.new(:ios, '4.0.0')
p.deployment_target.should == Pod::Version.new('4.0.0')
end
it "allows to specify the deployment target in a hash on initialization (backwards compatibility from 0.6)" do
p = Pod::Platform.new(:ios, { :deployment_target => '4.0.0' })
p.deployment_target.should == Pod::Version.new('4.0.0')
end
it "allows to specify the deployment target after initialization" do
p = Pod::Platform.new(:ios, '4.0.0')
p.deployment_target = '4.0.0'
p.deployment_target.should == Pod::Version.new('4.0.0')
p.deployment_target = Pod::Version.new('4.0.0')
p.deployment_target.should == Pod::Version.new('4.0.0')
end
end
describe "Pod::Platform with a nil value" do
......@@ -59,3 +67,35 @@ describe "Pod::Platform with a nil value" do
@platform.should.be.nil
end
end
describe "Pod::Platform#support?" do
it "supports another platform is with the same operating system" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:ios)
p1.should.support?(p2)
p1 = Pod::Platform.new(:osx)
p2 = Pod::Platform.new(:osx)
p1.should.support?(p2)
end
it "supports a nil platform" do
p1 = Pod::Platform.new(:ios)
p1.should.support?(nil)
end
it "supports a platform with a lower or equal deployment_target" do
p1 = Pod::Platform.new(:ios, '5.0')
p2 = Pod::Platform.new(:ios, '4.0')
p1.should.support?(p1)
p1.should.support?(p2)
p2.should.not.support?(p1)
end
it "supports a platform regardless of the deployment_target if one of the two does not specify it" do
p1 = Pod::Platform.new(:ios)
p2 = Pod::Platform.new(:ios, '4.0')
p1.should.support?(p2)
p2.should.support?(p1)
end
end
......@@ -48,7 +48,7 @@ describe "Pod::Podfile" do
Pod::Podfile.new {}.should.not.generate_bridge_support
Pod::Podfile.new { generate_bridge_support! }.should.generate_bridge_support
end
it 'specifies that ARC compatibility flag should be generated' do
Pod::Podfile.new { set_arc_compatibility_flag! }.should.set_arc_compatibility_flag
end
......@@ -260,6 +260,15 @@ describe "Pod::Podfile" do
@target_definition.relative_pods_root.should == '${SRCROOT}/../Pods'
end
it "simply returns the $(PODS_ROOT) path if no xcodeproj file is available and doesn't needs to integrate" do
config.integrate_targets.should.equal true
config.integrate_targets = false
@target_definition.relative_pods_root.should == '${SRCROOT}/../Pods'
@target_definition.stubs(:xcodeproj).returns(nil)
@target_definition.relative_pods_root.should == '${SRCROOT}/Pods'
config.integrate_targets = true
end
it "returns the xcconfig file path relative to the project's $(SRCROOT)" do
@target_definition.xcconfig_relative_path.should == '../Pods/Pods.xcconfig'
end
......@@ -271,6 +280,17 @@ describe "Pod::Podfile" do
end
describe "concerning validations" do
it "raises if it should integrate and can't find an xcodeproj" do
config.integrate_targets.should.equal true
target_definition = Pod::Podfile.new {}.target_definitions[:default]
target_definition.stubs(:xcodeproj).returns(nil)
exception = lambda {
target_definition.relative_pods_root
}.should.raise Pod::Informative
exception.message.should.include "Xcode project"
end
xit "raises if no platform is specified" do
exception = lambda {
Pod::Podfile.new {}.validate!
......
......@@ -39,7 +39,7 @@ describe "Pod::Resolver" do
lambda { @resolver.resolve }.should.not.raise
end
it "raises once any of the dependencies does not match the platform of the root spec (Podfile)" do
it "raises once any of the dependencies does not match the platform of its podfile target" do
set = Pod::Spec::Set.new(config.repos_dir + 'master/ASIHTTPRequest')
@resolver.cached_sets['ASIHTTPRequest'] = set
......@@ -59,27 +59,15 @@ describe "Pod::Resolver" do
lambda { @resolver.resolve }.should.raise Pod::Informative
end
it "does not raise if all of the dependencies have a deployment target equal or lower of the root spec (Podfile)" do
it "raises once any of the dependencies does not have a deployment_target compatible with its podfile target" do
set = Pod::Spec::Set.new(config.repos_dir + 'master/ASIHTTPRequest')
@resolver.cached_sets['ASIHTTPRequest'] = set
@podfile.platform :ios, "4.0"
def set.stub_platform=(platform); @stubbed_platform = platform; end
def set.specification; spec = super; spec.platform = @stubbed_platform; spec; end
@podfile.platform :ios, { :deployment_target => "4.0.0" }
set.stub_platform = :ios, { :deployment_target => "4.0.0" }
Pod::Specification.any_instance.stubs(:platforms).returns([ Pod::Platform.new(:ios, '4.0'), Pod::Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.not.raise
end
it "raises once any of the dependencies requires a higher deployment target of the root spec (Podfile)" do
set = Pod::Spec::Set.new(config.repos_dir + 'master/ASIHTTPRequest')
@resolver.cached_sets['ASIHTTPRequest'] = set
def set.stub_platform=(platform); @stubbed_platform = platform; end
def set.specification; spec = super; spec.platform = @stubbed_platform; spec; end
@podfile.platform :ios, { :deployment_target => "4.0.0" }
set.stub_platform = :ios, { :deployment_target => "5.0.0" }
Pod::Specification.any_instance.stubs(:platforms).returns([ Pod::Platform.new(:ios, '5.0'), Pod::Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.raise Pod::Informative
end
......
......@@ -149,28 +149,22 @@ describe "A Pod::Specification, in general," do
@spec = Pod::Spec.new
end
def validate(&block)
Proc.new(&block).should.raise(Pod::Informative)
it "returns the platform that the static library should be build for" do
@spec.platform = :ios
@spec.platform.should == :ios
end
it "raises if the specification does not contain the minimum required attributes" do
exception = validate { @spec.validate! }
exception.message =~ /name.*version.*summary.*homepage.*authors.*(source.*part_of).*source_files/
it "returns the platform and the deployment target" do
@spec.platform = :ios, '4.0'
@spec.platform.should == :ios
@spec.platform.deployment_target.should == Pod::Version.new('4.0')
end
it "raises if the platform is unrecognized" do
validate { @spec.validate! }.message.should.not.include 'platform'
@spec.platform = :ios
validate { @spec.validate! }.message.should.not.include 'platform'
@spec.platform = :osx
validate { @spec.validate! }.message.should.not.include 'platform'
@spec.platform = :windows
validate { @spec.validate! }.message.should.include 'platform'
end
it "returns the platform that the static library should be build for" do
@spec.platform = :ios
@spec.platform.should == :ios
it "returns the platfroms for which the pod is supported" do
@spec.platform = :ios, '4.0'
@spec.platforms.count.should == 1
@spec.platforms.first.should == :ios
@spec.platforms.first.deployment_target.should == Pod::Version.new('4.0')
end
it "returns the license of the Pod" do
......@@ -185,7 +179,7 @@ describe "A Pod::Specification, in general," do
:text => 'Permission is hereby granted ...'
}
end
it "returns the license of the Pod specified in the old format" do
@spec.license = 'MIT'
@spec.license.should == {
......@@ -200,7 +194,7 @@ describe "A Pod::Specification, in general," do
'--project-company', '"Company Name"',
'--company-id', 'com.company',
'--ignore', 'Common',
'--ignore', '.m']
'--ignore', '.m']
}
@spec.documentation[:html].should == 'http://EXAMPLE/#{@name}/documentation'
@spec.documentation[:appledoc].should == ['--project-name', '#{@name}',
......@@ -305,11 +299,11 @@ describe "A Pod::Specification with :local source" do
s.source_files = "."
end
end
it "is marked as local" do
@spec.should.be.local
end
it "it returns the expanded local path" do
@spec.local_path.should == fixture("integration/JSONKit")
end
......@@ -381,6 +375,8 @@ describe "A Pod::Specification, concerning its attributes that support different
s.ios.dependency 'JSONKit'
s.osx.dependency 'SSZipArchive'
s.ios.deployment_target = '4.0'
end
end
......@@ -399,6 +395,12 @@ describe "A Pod::Specification, concerning its attributes that support different
}
end
it "returns the list of the supported platfroms and deployment targets" do
@spec.platforms.count.should == 2
@spec.platforms.should.include? Pod::Platform.new(:osx)
@spec.platforms.should.include? Pod::Platform.new(:ios, '4.0')
end
it "returns the same list of compiler flags for each platform" do
@spec.compiler_flags.should == {
:ios => ' -Wdeprecated-implementations -fobjc-arc',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment