Commit 099f22a5 authored by Fabio Pelosin's avatar Fabio Pelosin

[Dependency] Always copy the podspec of external sources to `Local Podspecs`

This reduces ambiguity and prevents bugs like #489, which was caused by the
Sandbox creating a LocalPods from the spec in the root (if present) and
ignoring the one in Local Pods.

Closes #489.
parent 9986aa4c
## Master
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.14.0.rc2...master)
###### Bug fixes
- In certain conditions the spec of an external would have been overridden
by the spec in the root of a Pod.
[#489](https://github.com/CocoaPods/CocoaPods/issues/489)
## 0.14.0.rc2 ## 0.14.0.rc2
[CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.14.0.rc1...0.14.0.rc2) [CocoaPods](https://github.com/CocoaPods/CocoaPods/compare/0.14.0.rc1...0.14.0.rc2)
...@@ -5,8 +15,11 @@ ...@@ -5,8 +15,11 @@
###### Bug fixes ###### Bug fixes
- Fix incorrect name for Pods from external sources with preferred subspecs. - Fix incorrect name for Pods from external sources with preferred subspecs.
[#485](https://github.com/CocoaPods/CocoaPods/issues/485)
- Prevent duplication of Pod with a local source and mutliple activated specs. - Prevent duplication of Pod with a local source and mutliple activated specs.
[#485](https://github.com/CocoaPods/CocoaPods/issues/485)
- Fixed the `uninitialized constant Pod::Lockfile::Digest` error. - Fixed the `uninitialized constant Pod::Lockfile::Digest` error.
[#484](https://github.com/CocoaPods/CocoaPods/issues/484)
## 0.14.0.rc1 ## 0.14.0.rc1
......
...@@ -165,12 +165,26 @@ module Pod ...@@ -165,12 +165,26 @@ module Pod
end end
def specification_from_external(sandbox, platform) def specification_from_external(sandbox, platform)
copy_external_source_into_sandbox(sandbox, platform) podspec = copy_external_source_into_sandbox(sandbox, platform)
spec = specification_from_local(sandbox, platform) spec = specification_from_local(sandbox, platform)
raise Informative, "No podspec found for `#{name}' in #{description}" unless spec raise Informative, "No podspec found for `#{name}' in #{description}" unless spec
spec spec
end end
# Can store from a pathname or a string
#
def store_podspec(sandbox, podspec)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath
if podspec.is_a?(String)
raise Informative, "No podspec found for `#{name}' in `#{description}'" unless podspec.include?('Spec.new')
output_path.open('w') { |f| f.puts(podspec) }
else
raise Informative, "No podspec found for `#{name}' in `#{description}'" unless podspec.exist?
FileUtils.copy(podspec, output_path)
end
end
def ==(other) def ==(other)
return if other.nil? return if other.nil?
name == other.name && params == other.params name == other.name && params == other.params
...@@ -184,6 +198,7 @@ module Pod ...@@ -184,6 +198,7 @@ module Pod
target.rmtree if target.exist? target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params) downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
if local_pod = sandbox.installed_pod_named(name, platform) if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.downloaded = true local_pod.downloaded = true
end end
...@@ -201,14 +216,10 @@ module Pod ...@@ -201,14 +216,10 @@ module Pod
# can be http, file, etc # can be http, file, etc
class PodspecSource < AbstractExternalSource class PodspecSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox, _) def copy_external_source_into_sandbox(sandbox, _)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec"
output_path.dirname.mkpath
puts "-> Fetching podspec for `#{name}' from: #{@params[:podspec]}" unless config.silent? puts "-> Fetching podspec for `#{name}' from: #{@params[:podspec]}" unless config.silent?
path = @params[:podspec] path = @params[:podspec]
path = Pathname.new(path).expand_path if path.start_with?("~") path = Pathname.new(path).expand_path if path.start_with?("~")
open(path) do |io| open(path) { |io| store_podspec(sandbox, io.read) }
output_path.open('w') { |f| f << io.read }
end
end end
def description def description
...@@ -224,9 +235,7 @@ module Pod ...@@ -224,9 +235,7 @@ module Pod
end end
def copy_external_source_into_sandbox(sandbox, _) def copy_external_source_into_sandbox(sandbox, _)
output_path = sandbox.root + "Local Podspecs/#{name}.podspec" store_podspec(sandbox, pod_spec_path)
output_path.dirname.mkpath
FileUtils.copy(pod_spec_path, output_path)
end end
def specification_from_local(sandbox, platform) def specification_from_local(sandbox, platform)
......
...@@ -55,11 +55,8 @@ module Pod ...@@ -55,11 +55,8 @@ module Pod
end end
def podspec_for_name(name) def podspec_for_name(name)
if spec_path = Dir[root + "#{name}/*.podspec"].first path = root + "Local Podspecs/#{name}.podspec"
Pathname.new(spec_path) path.exist? ? path : nil
elsif spec_path = Dir[root + "Local Podspecs/#{name}.podspec"].first
Pathname.new(spec_path)
end
end end
end end
......
...@@ -89,17 +89,35 @@ module Pod ...@@ -89,17 +89,35 @@ module Pod
end end
end end
describe Dependency::ExternalSources::GitSource do describe Dependency::ExternalSources do
before do before do
@dependency = Dependency.new("cocoapods", :git => "git://github.com/cocoapods/cocoapods") @sandbox = temporary_sandbox
end
it "marks a LocalPod as downloaded if it's from GitSource" do
dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
@sandbox.installed_pod_named('Reachability', Platform.ios).downloaded.should.be.true
end end
it "marks a LocalPod as downloaded if it's downloaded" do it "creates a copy of the podspec (GitSource)" do
Downloader.stubs(:for_target).returns(stub_everything) dependency = Dependency.new("Reachability", :git => fixture('integration/Reachability'))
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "creates a copy of the podspec (PodspecSource)" do
dependency = Dependency.new("Reachability", :podspec => fixture('integration/Reachability/Reachability.podspec').to_s)
dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
pod = mock('LocaPod', :downloaded= => true) it "creates a copy of the podspec (LocalSource)" do
sandbox = stub('Sandbox', :root => temporary_sandbox.root, :installed_pod_named => pod) dependency = Dependency.new("Reachability", :local => fixture('integration/Reachability'))
@dependency.external_source.copy_external_source_into_sandbox(sandbox, Platform.ios) dependency.external_source.copy_external_source_into_sandbox(@sandbox, Platform.ios)
path = @sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end end
end end
end end
......
...@@ -81,11 +81,6 @@ describe Pod::Sandbox do ...@@ -81,11 +81,6 @@ describe Pod::Sandbox do
@sandbox.build_headers.root.should.not.exist @sandbox.build_headers.root.should.not.exist
end end
it "returns the path to a spec file in the root of the pod's dir" do
FileUtils.cp_r(fixture('banana-lib'), @sandbox.root + 'BananaLib')
@sandbox.podspec_for_name('BananaLib').should == @sandbox.root + 'BananaLib/BananaLib.podspec'
end
it "returns the path to a spec file in the 'Local Podspecs' dir" do it "returns the path to a spec file in the 'Local Podspecs' dir" do
(@sandbox.root + 'Local Podspecs').mkdir (@sandbox.root + 'Local Podspecs').mkdir
FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs') FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs')
...@@ -93,13 +88,16 @@ describe Pod::Sandbox do ...@@ -93,13 +88,16 @@ describe Pod::Sandbox do
end end
it "returns a LocalPod for a spec file in the sandbox" do it "returns a LocalPod for a spec file in the sandbox" do
FileUtils.cp_r(fixture('banana-lib'), @sandbox.root + 'BananaLib') (@sandbox.root + 'Local Podspecs').mkdir
FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs')
pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios) pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios)
pod.should.be.instance_of Pod::LocalPod pod.should.be.instance_of Pod::LocalPod
pod.top_specification.name.should == 'BananaLib' pod.top_specification.name.should == 'BananaLib'
end end
it "returns a LocalPod for a spec instance which source is expected to be in the sandbox" do it "returns a LocalPod for a spec instance which source is expected to be in the sandbox" do
(@sandbox.root + 'Local Podspecs').mkdir
FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs')
spec = Pod::Specification.from_file(fixture('banana-lib') + 'BananaLib.podspec') spec = Pod::Specification.from_file(fixture('banana-lib') + 'BananaLib.podspec')
pod = @sandbox.local_pod_for_spec(spec, Pod::Platform.ios) pod = @sandbox.local_pod_for_spec(spec, Pod::Platform.ios)
pod.should.be.instance_of Pod::LocalPod pod.should.be.instance_of Pod::LocalPod
...@@ -107,8 +105,9 @@ describe Pod::Sandbox do ...@@ -107,8 +105,9 @@ describe Pod::Sandbox do
end end
it "always returns the same cached LocalPod instance for the same spec and platform" do it "always returns the same cached LocalPod instance for the same spec and platform" do
FileUtils.cp_r(fixture('banana-lib'), @sandbox.root + 'BananaLib') (@sandbox.root + 'Local Podspecs').mkdir
spec = Pod::Specification.from_file(@sandbox.root + 'BananaLib/BananaLib.podspec') FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs')
spec = Pod::Specification.from_file(@sandbox.root + 'Local Podspecs/BananaLib.podspec')
pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios) pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios)
@sandbox.installed_pod_named('BananaLib', Pod::Platform.ios).should.eql pod @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios).should.eql pod
......
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