Commit ea9b1810 authored by Fabio Pelosin's avatar Fabio Pelosin

WIP Specification refactor.

parent 81d3550d
......@@ -23,7 +23,7 @@ module Pod
# specification information
def spec
@spec ||= @set.specification.part_of_other_pod? ? @set.specification.part_of_specification : @set.specification
@set.specification
end
def authors
......
......@@ -12,7 +12,6 @@ module Pod
def self.for_pod(pod)
spec = pod.specification
spec = spec.part_of_specification if spec.part_of_other_pod?
for_target(pod.root, spec.source.dup)
end
......@@ -26,9 +25,9 @@ module Pod
def clean
# implement in sub-classes
end
private
def self.for_target(target_path, options)
options = options.dup
if url = options.delete(:git)
......
......@@ -145,14 +145,6 @@ module Pod
end
end
unless download_only_specifications.empty?
file.puts
file.puts "DOWNLOAD_ONLY:"
download_only_specifications.map(&:to_s).sort.each do |name|
file.puts " - #{name}"
end
end
file.puts
file.puts "DEPENDENCIES:"
@podfile.dependencies.map(&:to_s).sort.each do |dep|
......@@ -193,7 +185,7 @@ module Pod
result = {}
specs_by_target.each do |target_definition, specs|
result[target_definition] = specs.map do |spec|
LocalPod.new(spec, @sandbox, target_definition.platform) if activated_spec?(spec)
LocalPod.new(spec, @sandbox, target_definition.platform)
end.compact
end
result
......@@ -203,24 +195,15 @@ module Pod
# dependency that is not a download-only
# one.
def activated_specifications
dependency_specifications.select { |spec| activated_spec?(spec) }
dependency_specifications
end
def activated_specifications_for_target(target_definition)
specs_by_target[target_definition].select { |spec| activated_spec?(spec) }
end
def download_only_specifications
dependency_specifications - activated_specifications
specs_by_target[target_definition]
end
private
def activated_spec?(spec)
# Don't activate specs which are only wrappers of subspecs, or share
# source with another pod but aren't activated themselves.
!spec.wrapper? && !@resolver.cached_sets[spec.name].only_part_of_other_pod?
end
def print_title(title, only_verbose = true)
if config.verbose?
......
......@@ -27,13 +27,7 @@ module Pod
targets_and_specs[target_definition] = @specs.values_at(*@loaded_specs).sort_by(&:name)
end
# Specification doesn't need to know more about the context, so we assign
# the other specification, of which this pod is a part, to the spec.
@specs.values.sort_by(&:name).each do |spec|
if spec.part_of_other_pod?
spec.part_of_specification = @cached_sets[spec.part_of.name].specification
end
end
@specs.values.sort_by(&:name)
targets_and_specs
end
......@@ -41,7 +35,8 @@ module Pod
private
def find_cached_set(dependency, platform)
@cached_sets[dependency.name] ||= begin
set_name = dependency.name.split('/').first
@cached_sets[set_name] ||= begin
if dependency.specification
Specification::Set::External.new(dependency.specification)
elsif external_source = dependency.external_source
......@@ -71,6 +66,7 @@ module Pod
if dependency.subspec_dependency?
spec = spec.subspec_by_name(dependency.name)
end
@loaded_specs << spec.name
@specs[spec.name] = spec
......@@ -84,8 +80,8 @@ module Pod
end
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
unless spec.available_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.available_platforms.join(' - ')}.".red
end
end
end
......
This diff is collapsed.
......@@ -27,10 +27,6 @@ module Pod
end
end
def only_part_of_other_pod?
@required_by.all? { |spec| spec.dependency_by_top_level_spec_name(name).only_part_of_other_pod? }
end
def name
@pod_dir.basename.to_s
end
......@@ -88,10 +84,6 @@ module Pod
@specification = before
end
def only_part_of_other_pod?
false
end
def specification_path
raise "specification_path"
end
......
......@@ -81,7 +81,7 @@ module Pod
def github_stats_if_needed(set)
return if get_value(set, :gh_date) && get_value(set, :gh_date) > Time.now - cache_expiration
spec = set.specification.part_of_other_pod? ? set.specification.part_of_specification : set.specification
spec = set.specification
url = spec.source.reject {|k,_| k == :commit || k == :tag }.values.first
repo_id = url[/github.com\/([^\/\.]*\/[^\/\.]*)\.*/, 1]
return unless repo_id
......
......@@ -9,11 +9,9 @@ module SpecHelper
def specs_by_target
@specs_by_target ||= super.tap do |hash|
hash.values.flatten.each do |spec|
unless spec.part_of_other_pod?
source = spec.source
source[:git] = SpecHelper.fixture("integration/#{spec.name}").to_s
spec.source = source
end
source = spec.source
source[:git] = SpecHelper.fixture("integration/#{spec.name}").to_s
spec.source = source
end
end
end
......@@ -113,12 +111,12 @@ else
installer.install!
YAML.load(installer.lock_file.read).should == {
'PODS' => [{ 'Reachability (1.2.3)' => ["ASIHTTPRequest (>= 1.8)"] }],
'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
'PODS' => [ 'Reachability (1.2.3)' ],
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
'DEPENDENCIES' => ["Reachability (from `#{url}')"]
}
end
it "install a dummy source file" do
create_config!
podfile = Pod::Podfile.new do
......@@ -131,7 +129,7 @@ else
s.source_files = 'JSONKit.*'
end
end
installer = SpecHelper::Installer.new(podfile)
installer.install!
......@@ -254,7 +252,7 @@ else
self.platform platform
xcodeproj 'dummy'
dependency 'Reachability', '> 2.0.5' if platform == :ios
dependency 'ASIWebPageRequest', '>= 1.8.1'
# dependency 'ASIWebPageRequest', '>= 1.8.1'
dependency 'JSONKit', '>= 1.0'
dependency 'SSZipArchive', '< 2'
end
......@@ -264,14 +262,14 @@ else
lock_file_contents = {
'PODS' => [
{ 'ASIHTTPRequest (1.8.1)' => ["Reachability"] },
{ 'ASIWebPageRequest (1.8.1)' => ["ASIHTTPRequest (= 1.8.1)"] },
# { 'ASIHTTPRequest (1.8.1)' => ["Reachability"] },
# { 'ASIWebPageRequest (1.8.1)' => ["ASIHTTPRequest (= 1.8.1)"] },
'JSONKit (1.5pre)',
'Reachability (3.0.0)',
'SSZipArchive (0.1.2)',
],
'DEPENDENCIES' => [
"ASIWebPageRequest (>= 1.8.1)",
# "ASIWebPageRequest (>= 1.8.1)",
"JSONKit (>= 1.0)",
"Reachability (> 2.0.5)",
"SSZipArchive (< 2)",
......@@ -279,9 +277,9 @@ else
}
unless platform == :ios
# No Reachability is required by ASIHTTPRequest on OSX
lock_file_contents['DEPENDENCIES'].delete_at(2)
lock_file_contents['PODS'].delete_at(3)
lock_file_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
lock_file_contents['DEPENDENCIES'].delete_at(1)
lock_file_contents['PODS'].delete_at(1)
# lock_file_contents['PODS'][0] = 'ASIHTTPRequest (1.8.1)'
end
YAML.load(installer.lock_file.read).should == lock_file_contents
......@@ -305,8 +303,9 @@ else
installer.install!
YAML.load(installer.lock_file.read).should == {
'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }],
'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
# 'PODS' => [{ 'Reachability (2.0.4)' => ["ASIHTTPRequest (>= 1.8)"] }],
'PODS' => [ 'Reachability (2.0.4)' ],
# 'DOWNLOAD_ONLY' => ["ASIHTTPRequest (1.8.1)"],
'DEPENDENCIES' => ["Reachability (= 2.0.4)"]
}
end
......
......@@ -22,11 +22,11 @@ describe Pod::Installer::TargetInstaller do
@specification = fixture_spec('banana-lib/BananaLib.podspec')
@pods = [Pod::LocalPod.new(@specification, @sandbox, Pod::Platform.ios)]
end
def do_install!
@installer.install!(@pods, @sandbox)
end
it 'adds a new static library target to the project' do
do_install!
@project.targets.count.should == 1
......@@ -43,12 +43,12 @@ describe Pod::Installer::TargetInstaller do
@pods[0].expects(:add_to_target).with(instance_of(Xcodeproj::Project::Object::PBXNativeTarget))
do_install!
end
it 'tells each pod to link its headers' do
@pods[0].expects(:link_headers)
do_install!
end
it 'adds the sandbox header search paths to the xcconfig, with quotes' do
do_install!
@installer.xcconfig.to_hash['HEADER_SEARCH_PATHS'].should.include("\"#{@sandbox.header_search_paths.join('" "')}\"")
......@@ -58,7 +58,7 @@ describe Pod::Installer::TargetInstaller do
do_install!
@installer.xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.not.include("-fobjc-arc")
end
it 'adds the -fobjc-arc to OTHER_LDFLAGS if any pods require arc (to support non-ARC projects on iOS 4.0)' do
@podfile.stubs(:set_arc_compatibility_flag? => true)
@specification.stubs(:requires_arc).returns(true)
......
......@@ -8,7 +8,8 @@ describe "Pod::Resolver" do
config.repos_dir = fixture('spec-repos')
@podfile = Pod::Podfile.new do
platform :ios
dependency 'ASIWebPageRequest'
dependency 'BlocksKit'
# dependency 'ASIWebPageRequest'
end
@resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
end
......@@ -20,16 +21,15 @@ describe "Pod::Resolver" do
it "holds the context state, such as cached specification sets" do
@resolver.resolve
@resolver.cached_sets.values.sort_by(&:name).should == [
Pod::Spec::Set.new(config.repos_dir + 'master/ASIHTTPRequest'),
Pod::Spec::Set.new(config.repos_dir + 'master/ASIWebPageRequest'),
Pod::Spec::Set.new(config.repos_dir + 'master/Reachability'),
Pod::Spec::Set.new(config.repos_dir + 'master/A2DynamicDelegate'),
Pod::Spec::Set.new(config.repos_dir + 'master/BlocksKit'),
].sort_by(&:name)
end
it "returns all specs needed for the dependency" do
specs = @resolver.resolve.values.flatten
specs.map(&:class).uniq.should == [Pod::Specification]
specs.map(&:name).sort.should == %w{ ASIHTTPRequest ASIWebPageRequest Reachability }
specs.map(&:name).sort.should == %w{ A2DynamicDelegate BlocksKit }
end
it "does not raise if all dependencies match the platform of the root spec (Podfile)" do
......@@ -40,8 +40,8 @@ describe "Pod::Resolver" do
end
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
set = Pod::Spec::Set.new(config.repos_dir + 'master/BlocksKit')
@resolver.cached_sets['BlocksKit'] = set
def set.stub_platform=(platform); @stubbed_platform = platform; end
def set.specification; spec = super; spec.platform = @stubbed_platform; spec; end
......@@ -60,14 +60,14 @@ describe "Pod::Resolver" do
end
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
set = Pod::Spec::Set.new(config.repos_dir + 'master/BlocksKit')
@resolver.cached_sets['BlocksKit'] = set
@podfile.platform :ios, "4.0"
Pod::Specification.any_instance.stubs(:platforms).returns([ Pod::Platform.new(:ios, '4.0'), Pod::Platform.new(:osx, '10.7') ])
Pod::Specification.any_instance.stubs(:available_platforms).returns([ Pod::Platform.new(:ios, '4.0'), Pod::Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.not.raise
Pod::Specification.any_instance.stubs(:platforms).returns([ Pod::Platform.new(:ios, '5.0'), Pod::Platform.new(:osx, '10.7') ])
Pod::Specification.any_instance.stubs(:available_platforms).returns([ Pod::Platform.new(:ios, '5.0'), Pod::Platform.new(:osx, '10.7') ])
lambda { @resolver.resolve }.should.raise Pod::Informative
end
......@@ -75,20 +75,80 @@ describe "Pod::Resolver" do
@podfile = Pod::Podfile.new do
platform :ios
dependency 'RestKit/Network'
dependency 'RestKit/ObjectMapping'
dependency 'RestKit/ObjectMapping/XML'
end
resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
resolver.resolve.values.flatten.map(&:name).sort.should == %w{
FileMD5Hash
LibComponentLogging-Core
LibComponentLogging-NSLog
RestKit/Network
RestKit/ObjectMapping/XML
SOCKit
XMLReader
cocoa-oauth
}
end
it "includes all the subspecs of a specification node" do
@podfile = Pod::Podfile.new do
platform :ios
dependency 'RestKit'
end
resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
resolver.resolve.values.flatten.map(&:name).sort.should == %w{
FileMD5Hash
ISO8601DateFormatter
JSONKit
LibComponentLogging-Core
LibComponentLogging-NSLog
RestKit
RestKit/Network
RestKit/ObjectMapping
RestKit/ObjectMapping/CoreData
RestKit/ObjectMapping/JSON
RestKit/ObjectMapping/XML
RestKit/UI
SOCKit
UDTableView
XMLReader
cocoa-oauth
}
end
it "if defined it includes only the main subspec of of a specification node" do
@podfile = Pod::Podfile.new do
platform :ios
dependency do |s|
s.main_subspec = 'JSON'
s.name = 'RestKit'
s.version = '0.10.0'
s.subspec 'JSON' do |js|
js.dependency 'RestKit/Network'
js.dependency 'RestKit/UI'
js.dependency 'RestKit/ObjectMapping/JSON'
js.dependency 'RestKit/ObjectMapping/CoreData'
end
s.subspec 'Network'
s.subspec 'UI'
s.subspec 'ObjectMapping' do |os|
os.subspec 'JSON'
os.subspec 'XML'
os.subspec 'CoreData'
end
end
end
resolver = Pod::Resolver.new(@podfile, stub('sandbox'))
resolver.resolve.values.flatten.map(&:name).sort.should == %w{
RestKit
RestKit/JSON
RestKit/Network
RestKit/ObjectMapping/CoreData
RestKit/ObjectMapping/JSON
RestKit/UI
}
end
end
......@@ -29,12 +29,6 @@ describe "Pod::Specification::Set" do
lambda { @set.required_version }.should.raise Pod::Informative
end
it "returns that this set is only part for other pods" do
@set.required_by(Pod::Spec.new { |s| s.part_of = 'CocoaLumberjack' })
@set.required_by(Pod::Spec.new { |s| s.part_of = 'CocoaLumberjack' })
@set.should.be.only_part_of_other_pod
end
before do
@set.required_by(Pod::Spec.new { |s| s.dependency 'CocoaLumberjack', '< 1.2.1' })
end
......@@ -51,11 +45,6 @@ describe "Pod::Specification::Set" do
@set.specification.should == Pod::Spec.new { |s| s.name = 'CocoaLumberjack'; s.version = '1.2' }
end
it "returns that this set is not only part for other pods" do
@set.required_by(Pod::Spec.new { |s| s.part_of = 'CocoaLumberjack' })
@set.should.not.be.only_part_of_other_pod
end
it "ignores dotfiles when getting the version directories" do
`touch #{fixture('spec-repos/master/CocoaLumberjack/.DS_Store')}`
lambda { @set.versions }.should.not.raise
......
......@@ -6,6 +6,10 @@ describe "A Pod::Specification loaded from a podspec" do
@spec = Pod::Specification.from_file(fixture('banana-lib/BananaLib.podspec'))
end
it "has no parent if it is the top level spec" do
@spec.parent.nil?.should == true
end
it "returns that it's not loaded from a podfile" do
@spec.should.not.be.podfile
end
......@@ -60,7 +64,6 @@ describe "A Pod::Specification loaded from a podspec" do
it "returns the pod's dependencies" do
expected = Pod::Dependency.new('monkey', '~> 1.0.1', '< 1.0.9')
@spec.dependencies.should == { :ios => [expected], :osx => [expected] }
@spec.dependency_by_top_level_spec_name('monkey').should == expected
end
it "returns the pod's xcconfig settings" do
......@@ -97,6 +100,7 @@ describe "A Pod::Specification loaded from a podspec" do
end
it "adds compiler flags if ARC is required" do
@spec.parent.should == nil
@spec.requires_arc = true
@spec.compiler_flags.should == { :ios => " -fobjc-arc", :osx => " -fobjc-arc" }
@spec.compiler_flags = "-Wunused-value"
......@@ -104,46 +108,6 @@ describe "A Pod::Specification loaded from a podspec" do
end
end
describe "A Pod::Specification that's part of another pod's source" do
before do
config.repos_dir = fixture('spec-repos')
@spec = Pod::Specification.new
end
after do
config.repos_dir = SpecHelper.tmp_repos_path
end
it "adds a dependency on the other pod's source, but not the library" do
@spec.part_of = 'monkey', '>= 1'
@spec.should.be.part_of_other_pod
dep = Pod::Dependency.new('monkey', '>= 1')
@spec.dependencies.should.not == [dep]
dep.only_part_of_other_pod = true
@spec.dependencies.should == { :ios => [dep], :osx => [dep] }
end
it "adds a dependency on the other pod's source *and* the library" do
@spec.part_of_dependency = 'monkey', '>= 1'
@spec.should.be.part_of_other_pod
@spec.dependencies[:ios].should == [Pod::Dependency.new('monkey', '>= 1')]
end
it "searches the sources for a matching specification if it has not been assigned by the Resolver yet (e.g. the search command)" do
@spec.part_of_dependency = 'SSZipArchive', '0.1.1'
@spec.part_of_specification.to_s.should == 'SSZipArchive (0.1.1)'
end
# TODO
#it "returns the specification of the pod that it's part of" do
# @spec.part_of_specification
#end
#
#it "returns the destroot of the pod that it's part of" do
# @spec.pod_destroot
#end
end
describe "A Pod::Specification, in general," do
before do
@spec = Pod::Spec.new
......@@ -160,11 +124,11 @@ describe "A Pod::Specification, in general," do
@spec.platform.deployment_target.should == Pod::Version.new('4.0')
end
it "returns the platfroms for which the pod is supported" do
it "returns the available platforms 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')
@spec.available_platforms.count.should == 1
@spec.available_platforms.first.should == :ios
@spec.available_platforms.first.deployment_target.should == Pod::Version.new('4.0')
end
it "returns the license of the Pod" do
......@@ -251,11 +215,6 @@ describe "A Pod::Specification subspec" do
end
end
it "makes a parent spec a wrapper if it has no source files of its own" do
@spec.should.be.wrapper
@spec.subspecs.first.should.not.be.wrapper
end
it "returns the top level parent spec" do
@spec.subspecs.first.top_level_parent.should == @spec
@spec.subspecs.first.subspecs.first.top_level_parent.should == @spec
......@@ -266,18 +225,9 @@ describe "A Pod::Specification subspec" do
@spec.subspecs.first.subspecs.first.name.should == 'MainSpec/FirstSubSpec/SecondSubSpec'
end
it "is a `part_of' the top level parent spec" do
dependency = Pod::Dependency.new('MainSpec', '1.2.3').tap { |d| d.only_part_of_other_pod = true }
@spec.subspecs.first.part_of.should == dependency
@spec.subspecs.first.subspecs.first.part_of.should == dependency
end
it "depends on the parent spec, if it is a subspec" do
dependency = Pod::Dependency.new('MainSpec', '1.2.3').tap { |d| d.only_part_of_other_pod = true }
@spec.subspecs.first.dependencies[:ios].should == [dependency]
@spec.subspecs.first.dependencies[:osx].should == [dependency]
@spec.subspecs.first.subspecs.first.dependencies[:ios].should == [dependency, Pod::Dependency.new('MainSpec/FirstSubSpec', '1.2.3')]
@spec.subspecs.first.subspecs.first.dependencies[:osx].should == [dependency, Pod::Dependency.new('MainSpec/FirstSubSpec', '1.2.3')]
it "correctly resolves the inheritance chain" do
@spec.subspecs.first.subspecs.first.parent.should == @spec.subspecs.first
@spec.subspecs.first.parent.should == @spec
end
it "automatically forwards undefined attributes to the top level parent" do
......@@ -288,6 +238,8 @@ describe "A Pod::Specification subspec" do
end
it "returns subspecs by name" do
@spec.subspec_by_name(nil).should == @spec
@spec.subspec_by_name('MainSpec').should == @spec
@spec.subspec_by_name('MainSpec/FirstSubSpec').should == @spec.subspecs.first
@spec.subspec_by_name('MainSpec/FirstSubSpec/SecondSubSpec').should == @spec.subspecs.first.subspecs.first
end
......@@ -337,12 +289,12 @@ describe "A Pod::Specification, concerning its attributes that support different
end
it "returns the same list of xcconfig build settings for each platform" do
build_settings = { 'OTHER_LDFLAGS' => '-lObjC -framework QuartzCore -lz' }
build_settings = { 'OTHER_LDFLAGS' => '-lObjC -lz -framework QuartzCore' }
@spec.xcconfig.should == { :ios => build_settings, :osx => build_settings }
end
it "returns the same list of compiler flags for each platform" do
compiler_flags = ' -Wdeprecated-implementations -fobjc-arc'
compiler_flags = ' -fobjc-arc -Wdeprecated-implementations'
@spec.compiler_flags.should == { :ios => compiler_flags, :osx => compiler_flags }
end
......@@ -392,21 +344,21 @@ describe "A Pod::Specification, concerning its attributes that support different
it "returns a different list of xcconfig build settings for each platform" do
@spec.xcconfig.should == {
:ios => { 'OTHER_LDFLAGS' => '-lObjC -framework QuartzCore -lz' },
:osx => { 'OTHER_LDFLAGS' => '-lObjC -all_load -framework QuartzCore -framework CoreData -lz -lxml' }
:ios => { 'OTHER_LDFLAGS' => '-lObjC -lz -framework QuartzCore' },
:osx => { 'OTHER_LDFLAGS' => '-lObjC -all_load -lz -lxml -framework QuartzCore -framework CoreData' }
}
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')
@spec.available_platforms.count.should == 2
@spec.available_platforms.should.include? Pod::Platform.new(:osx)
@spec.available_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',
:osx => ' -Wfloat-equal -fobjc-arc'
:ios => ' -fobjc-arc -Wdeprecated-implementations',
:osx => ' -fobjc-arc -Wfloat-equal'
}
end
......
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