Skip to content

Commit

Permalink
Clean pods *after* resolving and activating. Fixes #414.
Browse files Browse the repository at this point in the history
  • Loading branch information
alloy committed Jul 23, 2012
1 parent 135ce81 commit 7634571
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -7,7 +7,7 @@ group :development do

gem "mocha", "~> 0.11.4"
gem "bacon"
gem "kicker"
gem "kicker", "~> 3.0.0pre1"
gem "mocha-on-bacon"
gem "rake"
gem "rb-fsevent"
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Expand Up @@ -41,7 +41,7 @@ GEM
hashie (1.2.0)
i18n (0.6.0)
json (1.7.3)
kicker (2.6.1)
kicker (3.0.0pre1)
listen
listen (0.4.7)
rb-fchange (~> 0.0.5)
Expand Down Expand Up @@ -88,7 +88,7 @@ DEPENDENCIES
bacon
cocoapods!
github-markup
kicker
kicker (~> 3.0.0pre1)
mocha (~> 0.11.4)
mocha-on-bacon
pry
Expand Down
24 changes: 15 additions & 9 deletions lib/cocoapods/dependency.rb
Expand Up @@ -146,27 +146,33 @@ def initialize(name, params)
end

def specification_from_sandbox(sandbox, platform)
specification_from_local(sandbox, platform) || specification_from_external(sandbox, platform)
end

def specification_from_local(sandbox, platform)
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.top_specification
else
copy_external_source_into_sandbox(sandbox)
local_pod = sandbox.installed_pod_named(name, platform)
local_pod.clean if config.clean? && local_pod.exists?
local_pod.top_specification
end
end

def specification_from_external(sandbox, platform)
copy_external_source_into_sandbox(sandbox, platform)
specification_from_local(sandbox, platform)
end

def ==(other_source)
return if other_source.nil?
name == other_source.name && params == other_source.params
end
end

class GitSource < AbstractExternalSource
def copy_external_source_into_sandbox(sandbox)
def copy_external_source_into_sandbox(sandbox, platform)
puts " * Pre-downloading: '#{name}'" unless config.silent?
Downloader.for_target(sandbox.root + name, @params).tap do |downloader|
downloader.download
downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download
if local_pod = sandbox.installed_pod_named(name, platform)
local_pod.downloaded = true
end
end

Expand All @@ -181,7 +187,7 @@ def description

# can be http, file, etc
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?
Expand Down
24 changes: 12 additions & 12 deletions lib/cocoapods/installer.rb
Expand Up @@ -57,12 +57,17 @@ def install_dependencies!
puts marker << ( pod.exists? ? "Using #{name}" : "Installing #{name}".green )
end

unless pod.exists?
download_pod(pod)
# The docs need to be generated before cleaning because
# the documentation is created for all the subspecs.
download_pod(pod) unless pod.exists?

# This will not happen if the pod existed before we started the install
# process.
if pod.downloaded?
# The docs need to be generated before cleaning because the
# documentation is created for all the subspecs.
generate_docs(pod)
pod.clean if config.clean
# Here we clean pod's that just have been downloaded or have been
# pre-downloaded in AbstractExternalSource#specification_from_sandbox.
pod.clean! if config.clean?
end
end
end
Expand All @@ -79,6 +84,7 @@ def download_pod(pod)
else
downloader.download
end
pod.downloaded = true
end

#TODO: move to generator ?
Expand Down Expand Up @@ -207,18 +213,12 @@ def pods_by_target
specs_by_target.each do |target_definition, specs|
@pods_by_spec[target_definition.platform] = {}
result[target_definition] = specs.map do |spec|
pod = pod_for_spec(spec, target_definition.platform)
pod.add_specification(spec)
pod
@sandbox.local_pod_for_spec(spec, target_definition.platform)
end.uniq.compact
end
result
end

def pod_for_spec(spec, platform)
@pods_by_spec[platform][spec.top_level_parent.name] ||= LocalPod.new(spec, @sandbox, platform)
end

private

def print_title(title, only_verbose = true)
Expand Down
13 changes: 10 additions & 3 deletions lib/cocoapods/local_pod.rb
Expand Up @@ -38,6 +38,13 @@ class LocalPod
#
attr_reader :platform

# @return [Boolean] Wether or not the pod has been downloaded in the
# current install process and still needs its docs
# generated and be cleaned.
#
attr_accessor :downloaded
alias_method :downloaded?, :downloaded

# @param [Specification] specification
# The first activated specification of the pod.
# @param [Sandbox] sandbox
Expand Down Expand Up @@ -139,7 +146,7 @@ def implode
#
# @return [void]
#
def clean
def clean!
clean_paths.each { |path| FileUtils.rm_rf(path) }
@cleaned = true
end
Expand Down Expand Up @@ -299,8 +306,8 @@ def xcconfig
#
def all_specs_public_header_files
if @cleaned
raise Informative, "The pod is cleaned and cannot compute the all the "\
"header files as they might be deleted."
raise Informative, "The pod is cleaned and cannot compute the " \
"header files, as some might have been deleted."
end

all_specs = [ top_specification ] + top_specification.subspecs
Expand Down
21 changes: 15 additions & 6 deletions lib/cocoapods/sandbox.rb
Expand Up @@ -9,6 +9,7 @@ class Sandbox
def initialize(path)
@root = Pathname.new(path)
@header_search_paths = [HEADERS_DIR]
@cached_local_pods = {}

FileUtils.mkdir_p(@root)
end
Expand Down Expand Up @@ -56,17 +57,25 @@ def prepare_for_install
headers_root.rmtree if headers_root.exist?
end

def podspec_for_name(name)
if spec_path = Dir[root + "#{name}/*.podspec"].first
Pathname.new(spec_path)
elsif spec_path = Dir[root + "Local Podspecs/#{name}.podspec"].first
Pathname.new(spec_path)
def local_pod_for_spec(spec, platform)
key = [spec.top_level_parent.name, platform.to_sym]
(@cached_local_pods[key] ||= LocalPod.new(spec.top_level_parent, self, platform)).tap do |pod|
pod.add_specification(spec)
end
end

def installed_pod_named(name, platform)
if spec_path = podspec_for_name(name)
LocalPod.from_podspec(spec_path, self, platform)
key = [name, platform.to_sym]
@cached_local_pods[key] ||= LocalPod.from_podspec(spec_path, self, platform)
end
end

def podspec_for_name(name)
if spec_path = Dir[root + "#{name}/*.podspec"].first
Pathname.new(spec_path)
elsif spec_path = Dir[root + "Local Podspecs/#{name}.podspec"].first
Pathname.new(spec_path)
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions spec/unit/dependency_spec.rb
Expand Up @@ -88,5 +88,19 @@ module Pod
end
end
end

describe Dependency::ExternalSources::GitSource do
before do
@dependency = Dependency.new("cocoapods", :git => "git://github.com/cocoapods/cocoapods")
end

it "marks a LocalPod as downloaded if it's downloaded" do
Downloader.stubs(:for_target).returns(stub_everything)

pod = mock('LocaPod', :downloaded= => true)
sandbox = stub('Sandbox', :root => '', :installed_pod_named => pod)
@dependency.external_source.copy_external_source_into_sandbox(sandbox, Platform.ios)
end
end
end
end
34 changes: 34 additions & 0 deletions spec/unit/sandbox_spec.rb
Expand Up @@ -76,4 +76,38 @@
@sandbox.prepare_for_install
@sandbox.headers_root.should.not.exist
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
(@sandbox.root + 'Local Podspecs').mkdir
FileUtils.cp(fixture('banana-lib') + 'BananaLib.podspec', @sandbox.root + 'Local Podspecs')
@sandbox.podspec_for_name('BananaLib').should == @sandbox.root + 'Local Podspecs/BananaLib.podspec'
end

it "returns a LocalPod for a spec file in the sandbox" do
FileUtils.cp_r(fixture('banana-lib'), @sandbox.root + 'BananaLib')
pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios)
pod.should.be.instance_of Pod::LocalPod
pod.top_specification.name.should == 'BananaLib'
end

it "returns a LocalPod for a spec instance which source is expected to be in the sandbox" do
spec = Pod::Specification.from_file(fixture('banana-lib') + 'BananaLib.podspec')
pod = @sandbox.local_pod_for_spec(spec, Pod::Platform.ios)
pod.should.be.instance_of Pod::LocalPod
pod.top_specification.name.should == 'BananaLib'
end

it "always returns the same cached LocalPod instance for the same spec and platform" do
FileUtils.cp_r(fixture('banana-lib'), @sandbox.root + 'BananaLib')
spec = Pod::Specification.from_file(@sandbox.root + 'BananaLib/BananaLib.podspec')

pod = @sandbox.installed_pod_named('BananaLib', Pod::Platform.ios)
@sandbox.installed_pod_named('BananaLib', Pod::Platform.ios).should.eql pod
@sandbox.local_pod_for_spec(spec, Pod::Platform.ios).should.eql pod
end
end

0 comments on commit 7634571

Please sign in to comment.