Commit d5f4684c authored by Fabio Pelosin's avatar Fabio Pelosin

[Sandbox] Store information about external sources and local Pods

parent e4be7bbb
...@@ -10,15 +10,15 @@ module Pod ...@@ -10,15 +10,15 @@ module Pod
Executable.execute_command(executable, command, raise_on_failure) Executable.execute_command(executable, command, raise_on_failure)
end end
# Indicates that an action will be perfomed. The action is passed as a # Indicates that an action will be performed. The action is passed as a
# block. # block.
# #
# @param [String] message # @param [String] message
# The message associated with the action. # The message associated with the action.
# #
# @yield The action, this block is always exectued. # @yield The action, this block is always executed.
# #
# @retur [void] # @return [void]
# #
def ui_action(message) def ui_action(message)
UI.section(" > #{message}", '', 1) do UI.section(" > #{message}", '', 1) do
...@@ -26,15 +26,15 @@ module Pod ...@@ -26,15 +26,15 @@ module Pod
end end
end end
# Indicates that a minor action will be perfomed. The action is passed as # Indicates that a minor action will be performed. The action is passed
# a block. # as a block.
# #
# @param [String] message # @param [String] message
# The message associated with the action. # The message associated with the action.
# #
# @yield The action, this block is always exectued. # @yield The action, this block is always executed.
# #
# @retur [void] # @return [void]
# #
def ui_sub_action(message) def ui_sub_action(message)
UI.section(" > #{message}", '', 2) do UI.section(" > #{message}", '', 2) do
...@@ -47,7 +47,7 @@ module Pod ...@@ -47,7 +47,7 @@ module Pod
# @param [String] message # @param [String] message
# The message associated with the action. # The message associated with the action.
# #
# @retur [void] # @return [void]
# #
def ui_message(message) def ui_message(message)
UI.puts message UI.puts message
......
...@@ -115,6 +115,10 @@ module Pod ...@@ -115,6 +115,10 @@ module Pod
raise "Abstract method" raise "Abstract method"
end end
#--------------------------------------#
# @! Subclasses helpers
private private
# Stores a specification in the `Local Podspecs` folder. # Stores a specification in the `Local Podspecs` folder.
...@@ -147,6 +151,31 @@ module Pod ...@@ -147,6 +151,31 @@ module Pod
end end
end end
# Pre-downloads a Pod passing the options to the downloader and informing
# the sandbox.
#
# @param [Sandbox] sandbox
# the sandbox where the Pod should be downloaded.
#
# @return [void]
#
def pre_download(sandbox)
UI.info("->".green + " Pre-downloading: `#{name}`") do
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(target, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
sandbox.predownloaded_pods << name
if downloader.options_specific?
source = @params
else
source = downloader.checkout_options
end
sandbox.store_checkout_source(name, source)
end
end
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
...@@ -168,14 +197,7 @@ module Pod ...@@ -168,14 +197,7 @@ module Pod
# operations are needed. # operations are needed.
# #
def copy_external_source_into_sandbox(sandbox) def copy_external_source_into_sandbox(sandbox)
UI.info("->".green + " Pre-downloading: `#{name}`") do pre_download(sandbox)
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(sandbox.root + name, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
sandbox.predownloaded_pods << name
end
end end
# @see AbstractExternalSource#description # @see AbstractExternalSource#description
...@@ -191,7 +213,7 @@ module Pod ...@@ -191,7 +213,7 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# Provides support for fetching a specification file from a Svn source # Provides support for fetching a specification file from a SVN source
# remote. # remote.
# #
# Supports all the options of the downloader (is similar to the git key of # Supports all the options of the downloader (is similar to the git key of
...@@ -209,14 +231,7 @@ module Pod ...@@ -209,14 +231,7 @@ module Pod
# operations are needed. # operations are needed.
# #
def copy_external_source_into_sandbox(sandbox) def copy_external_source_into_sandbox(sandbox)
UI.info("->".green + " Pre-downloading: `#{name}`") do pre_download(sandbox)
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(target, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
sandbox.predownloaded_pods << name
end
end end
# @see AbstractExternalSource#description # @see AbstractExternalSource#description
...@@ -232,8 +247,8 @@ module Pod ...@@ -232,8 +247,8 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# Provides support for fetching a specification file from a Svn source # Provides support for fetching a specification file from a Mercurial
# remote. # source remote.
# #
# Supports all the options of the downloader (is similar to the git key of # Supports all the options of the downloader (is similar to the git key of
# `source` attribute of a specification). # `source` attribute of a specification).
...@@ -250,14 +265,7 @@ module Pod ...@@ -250,14 +265,7 @@ module Pod
# operations are needed. # operations are needed.
# #
def copy_external_source_into_sandbox(sandbox) def copy_external_source_into_sandbox(sandbox)
UI.info("->".green + " Pre-downloading: `#{name}`") do pre_download(sandbox)
target = sandbox.root + name
target.rmtree if target.exist?
downloader = Downloader.for_target(target, @params)
downloader.download
store_podspec(sandbox, target + "#{name}.podspec")
sandbox.predownloaded_pods << name
end
end end
# @see AbstractExternalSource#description # @see AbstractExternalSource#description
...@@ -307,6 +315,7 @@ module Pod ...@@ -307,6 +315,7 @@ module Pod
# #
def copy_external_source_into_sandbox(sandbox) def copy_external_source_into_sandbox(sandbox)
store_podspec(sandbox, pod_spec_path) store_podspec(sandbox, pod_spec_path)
sandbox.store_local_path(name, @params[:local])
end end
# @see AbstractExternalSource#description # @see AbstractExternalSource#description
......
...@@ -303,11 +303,8 @@ module Pod ...@@ -303,11 +303,8 @@ module Pod
specs_by_platform[library.platform].concat(specs) specs_by_platform[library.platform].concat(specs)
end end
end end
pod_installer = PodSourceInstaller.new(sandbox, specs_by_platform)
root_spec = specs_by_platform.values.flatten.first.root pod_installer = PodSourceInstaller.new(sandbox, specs_by_platform)
local_path = root_spec.source[:local]
pod_installer.local_path = Pathname.new(local_path).expand_path if local_path# TODO
pod_installer.clean = config.clean? pod_installer.clean = config.clean?
pod_installer.aggressive_cache = config.aggressive_cache? pod_installer.aggressive_cache = config.aggressive_cache?
pod_installer.generate_docs = config.generate_docs? pod_installer.generate_docs = config.generate_docs?
...@@ -416,6 +413,8 @@ module Pod ...@@ -416,6 +413,8 @@ module Pod
# @return [void] # @return [void]
# #
def write_lockfiles def write_lockfiles
# checkout_options = sandbox.checkout_options
# TODO pass the options to the Lockfile
@lockfile = Lockfile.generate(podfile, analyzer.specifications) @lockfile = Lockfile.generate(podfile, analyzer.specifications)
UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do UI.message "- Writing Lockfile in #{UI.path config.lockfile_path}" do
...@@ -429,7 +428,7 @@ module Pod ...@@ -429,7 +428,7 @@ module Pod
# Integrates the user projects adding the dependencies on the CocoaPods # Integrates the user projects adding the dependencies on the CocoaPods
# libraries, setting them up to use the xcconfigs and performing other # libraries, setting them up to use the xcconfigs and performing other
# actions. This step is also reponsible of creating the workspace if # actions. This step is also responsible of creating the workspace if
# needed. # needed.
# #
# @return [void] # @return [void]
......
...@@ -60,10 +60,8 @@ module Pod ...@@ -60,10 +60,8 @@ module Pod
file_accessors.each do |file_accessor| file_accessors.each do |file_accessor|
files = file_accessor.source_files files = file_accessor.source_files
spec_name = file_accessor.spec.name spec_name = file_accessor.spec.name
local = file_accessor.spec.local? local = sandbox.local?(file_accessor.spec.root.name)
parent_group = local ? pods_project.local_pods : pods_project.pods parent_group = local ? pods_project.local_pods : pods_project.pods
parent_group = pods_project.pods
pods_project.add_file_references(files, spec_name, parent_group) pods_project.add_file_references(files, spec_name, parent_group)
end end
end end
......
...@@ -42,11 +42,6 @@ module Pod ...@@ -42,11 +42,6 @@ module Pod
# @!group Configuration # @!group Configuration
# @return [Pathname] the path of the source of the Pod if using the
# `:local` option.
#
attr_accessor :local_path
# @return [Bool] whether the file not used by CocoaPods should be # @return [Bool] whether the file not used by CocoaPods should be
# removed. # removed.
# #
...@@ -117,6 +112,10 @@ module Pod ...@@ -117,6 +112,10 @@ module Pod
@specific_source = downloader.checkout_options @specific_source = downloader.checkout_options
end end
end end
if specific_source
sandbox.store_checkout_source(root_spec.name, specific_source)
end
end end
# Generates the documentation for the Pod. # Generates the documentation for the Pod.
...@@ -202,7 +201,7 @@ module Pod ...@@ -202,7 +201,7 @@ module Pod
# @return [Pathname] the folder where the source of the Pod is located. # @return [Pathname] the folder where the source of the Pod is located.
# #
def root def root
local? ? local_path : sandbox.pod_dir(root_spec.name) sandbox.pod_dir(root_spec.name)
end end
# @return [Boolean] whether the source has been pre downloaded in the # @return [Boolean] whether the source has been pre downloaded in the
...@@ -216,7 +215,7 @@ module Pod ...@@ -216,7 +215,7 @@ module Pod
# CocoaPods should not interfere with the files of the user. # CocoaPods should not interfere with the files of the user.
# #
def local? def local?
!local_path.nil? sandbox.local?(root_spec.name)
end end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
......
...@@ -60,6 +60,8 @@ module Pod ...@@ -60,6 +60,8 @@ module Pod
@build_headers = HeadersStore.new(self, "BuildHeaders") @build_headers = HeadersStore.new(self, "BuildHeaders")
@public_headers = HeadersStore.new(self, "Headers") @public_headers = HeadersStore.new(self, "Headers")
@predownloaded_pods = [] @predownloaded_pods = []
@checkout_sources = {}
@local_pods = {}
FileUtils.mkdir_p(@root) FileUtils.mkdir_p(@root)
end end
...@@ -134,18 +136,6 @@ module Pod ...@@ -134,18 +136,6 @@ module Pod
root + "Pods.xcodeproj" root + "Pods.xcodeproj"
end end
# Returns the path for the Pod with the given name.
#
# @param [String] name
# The name of the Pod.
#
# @return [Pathname] the path of the Pod.
#
def pod_dir(name)
# root + "Sources/#{name}"
root + name
end
# Returns the path for the directory where to store the support files of # Returns the path for the directory where to store the support files of
# a target. # a target.
# #
...@@ -180,9 +170,9 @@ module Pod ...@@ -180,9 +170,9 @@ module Pod
path.exist? ? path : nil path.exist? ? path : nil
end end
#--------------------------------------# #-------------------------------------------------------------------------#
# @!group Pods Installation # @!group Pods storage & source
# Returns the specification for the Pod with the given name. # Returns the specification for the Pod with the given name.
# #
...@@ -197,14 +187,100 @@ module Pod ...@@ -197,14 +187,100 @@ module Pod
end end
end end
# @return [Array<String>] the names of the pods that have been # Returns the path where the Pod with the given name is stored, taking into
# account whether the Pod is locally sourced.
#
# @param [String] name
# The name of the Pod.
#
# @return [Pathname] the path of the Pod.
#
def pod_dir(name)
root_name = Specification.root_name(name)
if local?(root_name)
Pathname.new(local_pods[root_name])
else
# root + "Sources/#{name}"
root + root_name
end
end
#--------------------------------------#
# @return [Array<String>] The names of the pods that have been
# pre-downloaded from an external source. # pre-downloaded from an external source.
# #
attr_reader :predownloaded_pods attr_reader :predownloaded_pods
#-------------------------------------------------------------------------# # Checks if a Pod has been pre-downloaded by the resolver in order to fetch
# the podspec.
#
# @param [String] name
# The name of the Pod.
#
# @return [Bool] Whether the Pod has been pre-downloaded.
#
def predownloaded?(name)
root_name = Specification.root_name(name)
predownloaded_pods.include?(root_name)
end
#--------------------------------------#
# Stores the local path of a Pod.
#
# @param [String] name
# The name of the Pod.
#
# @param [Hash] source
# The hash which contains the options as returned by the
# downloader.
#
# @return [void]
#
def store_checkout_source(name, source)
root_name = Specification.root_name(name)
checkout_sources[root_name] = source
end
# @return [Hash{String=>Hash}] The options necessary to recreate the exact
# checkout of a given Pod grouped by its name.
#
attr_reader :checkout_sources
#--------------------------------------#
# Stores the local path of a Pod.
#
# @param [String] name
# The name of the Pod.
#
# @param [#to_s] path
# The local path where the Pod is stored.
#
# @return [void]
#
def store_local_path(name, path)
root_name = Specification.root_name(name)
local_pods[root_name] = path.to_s
end
# @return [Hash{String=>String}] The path of the Pods with a local source
# grouped by their name.
#
attr_reader :local_pods
# Checks if a Pod is locally sourced?
#
# @param [String] name
# The name of the Pod.
#
# @return [Bool] Whether the Pod is locally sourced.
#
def local?(name)
root_name = Specification.root_name(name)
!local_pods[root_name].nil?
end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
......
...@@ -267,18 +267,18 @@ end ...@@ -267,18 +267,18 @@ end
# Performs the checks for the test with the given folder using the given # Performs the checks for the test with the given folder using the given
# arguments. # arguments.
# #
# @parma [String] arguments # @param [String] arguments
# The arguments to pass to the Pod executable. # The arguments to pass to the Pod executable.
# #
# @parma [String] folder # @param [String] folder
# The name of the folder which contains the `before` and `after` # The name of the folder which contains the `before` and `after`
# subfolders. # subfolders.
# #
def check(arguments, folder) def check(arguments, folder)
# focused_check(arguments, folder) focused_check(arguments, folder)
end end
# Shortcut to focus on a test: Comment the implmentation of #check and # Shortcut to focus on a test: Comment the implementation of #check and
# call this from the relevant test. # call this from the relevant test.
# #
def focused_check(arguments, folder) def focused_check(arguments, folder)
...@@ -324,7 +324,7 @@ describe "Integration take 2" do ...@@ -324,7 +324,7 @@ describe "Integration take 2" do
end end
describe "Installs a Pod with a local source" do describe "Installs a Pod with a local source" do
focused_check "install --no-update --no-doc", "install_local_source" check "install --no-update --no-doc", "install_local_source"
end end
describe "Installs a Pod with an external source" do describe "Installs a Pod with an external source" do
......
...@@ -57,6 +57,35 @@ module Pod ...@@ -57,6 +57,35 @@ module Pod
it "returns the specification fetching it from the external source in any case" do it "returns the specification fetching it from the external source in any case" do
@external_source.specification_from_external(config.sandbox).name.should == 'Reachability' @external_source.specification_from_external(config.sandbox).name.should == 'Reachability'
end end
#--------------------------------------#
describe "Subclasses helpers" do
it "stores the podspec in the sandbox" do
sandbox = config.sandbox
podspec_path = fixture('integration/Reachability/Reachability.podspec')
@external_source.send(:store_podspec, sandbox, podspec_path)
path = config.sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
end
it "pre-downloads the Pod and store the relevant information in the sandbox" do
sandbox = config.sandbox
@external_source.send(:pre_download, sandbox)
path = config.sandbox.root + 'Local Podspecs/Reachability.podspec'
path.should.exist?
sandbox.predownloaded_pods.should == ["Reachability"]
sandbox.checkout_sources.should == {
"Reachability" => {
:git => fixture('integration/Reachability'),
:commit => "4ec575e4b074dcc87c44018cce656672a979b34a"
}
}
end
end
end end
#---------------------------------------------------------------------------# #---------------------------------------------------------------------------#
...@@ -174,5 +203,16 @@ module Pod ...@@ -174,5 +203,16 @@ module Pod
it "returns the description" do it "returns the description" do
@external_source.description.should.match %r|from `.*integration/Reachability`| @external_source.description.should.match %r|from `.*integration/Reachability`|
end end
it "marks the Pod as local in the sandbox" do
@external_source.copy_external_source_into_sandbox(config.sandbox)
config.sandbox.local_pods.should == {
"Reachability" => fixture('integration/Reachability').to_s
}
end
end end
#---------------------------------------------------------------------------#
end end
...@@ -24,6 +24,15 @@ module Pod ...@@ -24,6 +24,15 @@ module Pod
file_ref.path.should == "../../spec/fixtures/banana-lib/Classes/Banana.m" file_ref.path.should == "../../spec/fixtures/banana-lib/Classes/Banana.m"
end end
it "adds the files references of the local Pods in a dedicated group" do
config.sandbox.store_local_path('BananaLib', 'Some Path')
@installer.install!
group_ref = @installer.pods_project['Local Pods/BananaLib']
group_ref.should.be.not.nil
file_ref = @installer.pods_project['Local Pods/BananaLib/Banana.m']
file_ref.should.be.not.nil
end
it "adds the files references of the resources the Pods project" do it "adds the files references of the resources the Pods project" do
@installer.install! @installer.install!
group_ref = @installer.pods_project['Resources/BananaLib'] group_ref = @installer.pods_project['Resources/BananaLib']
......
...@@ -62,6 +62,17 @@ module Pod ...@@ -62,6 +62,17 @@ module Pod
pod_folder.should.exist pod_folder.should.exist
end end
it "stores the checkout options in the sandbox" do
@spec.version.head = true
@spec.source = { :git => SpecHelper.fixture('banana-lib'), :tag => 'v1.0' }
@installer.install!
sources = @installer.sandbox.checkout_sources
sources.should == { "BananaLib" => {
:git => SpecHelper.fixture('banana-lib'),
:commit=>"0b8b4084a43c38cfe308efa076fdeb3a64d9d2bc" }
}
end
end end
#--------------------------------------# #--------------------------------------#
...@@ -124,22 +135,18 @@ module Pod ...@@ -124,22 +135,18 @@ module Pod
@installer.stubs(:predownloaded?).returns(true) @installer.stubs(:predownloaded?).returns(true)
@installer.expects(:download_source).never @installer.expects(:download_source).never
@installer.stubs(:clean_installation) @installer.stubs(:clean_installation)
@installer.stubs(:link_headers)
@installer.install! @installer.install!
end end
it "doesn't downloads the source if the pod has a local source" do it "doesn't downloads the source if the pod has a local source" do
@installer.local_path = 'Some Path' config.sandbox.store_local_path('BananaLib', 'Some Path')
@installer.expects(:download_source).never @installer.expects(:download_source).never
@installer.stubs(:clean_installation)
@installer.stubs(:link_headers)
@installer.install! @installer.install!
end end
it "doesn't clean the installation if the pod has a local source" do it "doesn't clean the installation if the pod has a local source" do
@installer.local_path = 'Some Path' config.sandbox.store_local_path('BananaLib', 'Some Path')
@installer.expects(:clean_installation).never @installer.expects(:clean_installation).never
@installer.stubs(:link_headers)
@installer.install! @installer.install!
end end
......
...@@ -64,10 +64,6 @@ module Pod ...@@ -64,10 +64,6 @@ module Pod
@sandbox.project_path.should == temporary_directory + 'Sandbox/Pods.xcodeproj' @sandbox.project_path.should == temporary_directory + 'Sandbox/Pods.xcodeproj'
end end
it "returns the path for a Pod" do
@sandbox.pod_dir('JSONKit').should == temporary_directory + 'Sandbox/JSONKit'
end
it "returns the directory for the support files of a library" do it "returns the directory for the support files of a library" do
@sandbox.library_support_files_dir('Pods').should == temporary_directory + 'Sandbox' @sandbox.library_support_files_dir('Pods').should == temporary_directory + 'Sandbox'
end end
...@@ -84,15 +80,70 @@ module Pod ...@@ -84,15 +80,70 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
describe "Pods storage & source" do
it "loads the stored specification with the given name" do it "loads the stored specification with the given name" 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')
@sandbox.specification('BananaLib').name.should == 'BananaLib' @sandbox.specification('BananaLib').name.should == 'BananaLib'
end end
it "returns the directory where a Pod is stored" do
@sandbox.pod_dir('JSONKit').should == temporary_directory + 'Sandbox/JSONKit'
end
it "returns the directory where a local Pod is stored" do
@sandbox.store_local_path('BananaLib', Pathname.new('Some Path'))
@sandbox.pod_dir('BananaLib').should.be == Pathname.new('Some Path')
end
#--------------------------------------#
it "stores the list of the names of the pre-downloaded pods" do it "stores the list of the names of the pre-downloaded pods" do
@sandbox.predownloaded_pods << 'JSONKit' @sandbox.predownloaded_pods << 'BananaLib'
@sandbox.predownloaded_pods.should == ['JSONKit'] @sandbox.predownloaded_pods.should == ['BananaLib']
end
it "returns whether a Pod has been pre-downloaded" do
@sandbox.predownloaded_pods << 'BananaLib'
@sandbox.predownloaded?('BananaLib').should.be.true
@sandbox.predownloaded?('BananaLib/Subspec').should.be.true
@sandbox.predownloaded?('Monkey').should.be.false
end
#--------------------------------------#
it "stores the checkout source of a Pod" do
source = {:git => 'example.com', :commit => 'SHA'}
@sandbox.store_checkout_source('BananaLib/Subspec', source )
@sandbox.checkout_sources['BananaLib'].should == source
end
it "returns the checkout sources of the Pods" do
source = {:git => 'example.com', :commit => 'SHA'}
@sandbox.store_checkout_source('BananaLib', source )
@sandbox.checkout_sources.should == { 'BananaLib' => source }
end
#--------------------------------------#
it "stores the local path of a Pod" do
@sandbox.store_local_path('BananaLib/Subspec', Pathname.new('Some Path'))
@sandbox.local_pods['BananaLib'].should == 'Some Path'
end
it "returns the path of the local pods grouped by name" do
@sandbox.store_local_path('BananaLib', 'Some Path')
@sandbox.local_pods.should == { 'BananaLib' => 'Some Path' }
end
it "returns whether a Pod is local" do
@sandbox.store_local_path('BananaLib', Pathname.new('Some Path'))
@sandbox.local?('BananaLib').should.be.true
@sandbox.local?('BananaLib/Subspec').should.be.true
@sandbox.local?('Monkey').should.be.false
end
end 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