Commit b611ae93 authored by Samuel E. Giddins's avatar Samuel E. Giddins

Merge pull request #4644 from CocoaPods/seg-podfile-refactor

Podfile Refactor
parents 71ce9d47 78314087
...@@ -6,6 +6,40 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -6,6 +6,40 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
## Master ## Master
##### Breaking
* The `link_with` Podfile DSL method has been removed in favor of target
inheritance.
[Samuel Giddins](https://github.com/segiddins)
* The `:exclusive => true` Podfile DSL target option has been removed in favor
of the `inherit! :search_paths` directive.
[Samuel Giddins](https://github.com/segiddins)
* The specification of `:head` dependencies has been removed.
[Samuel Giddins](https://github.com/segiddins)
[#4673](https://github.com/CocoaPods/CocoaPods/issues/4673)
* The deprecated `:local` dependency option has been removed in favor of the
equivalent `:path` option.
[Samuel Giddins](https://github.com/segiddins)
* The deprecated `dependency` method in the Podfile DSL has been removed in
favor of the equivalent `pod` method.
[Samuel Giddins](https://github.com/segiddins)
* The deprecated `preferred_dependency` method in the Specification DSL has been
removed in favor of the equivalent `default_subspecs` method.
[Samuel Giddins](https://github.com/segiddins)
##### Highlighted Enhancements That Need Testing
* The Podfile DSL has been cleaned up, with the removal of confusing options and
the introduction of abstract targets, search paths-only inheritance, the
specification of installation options, and the removal of head dependencies.
[Samuel Giddins](https://github.com/segiddins)
[#840](https://github.com/CocoaPods/CocoaPods/issues/840)
##### Enhancements ##### Enhancements
* Add the ability to add a custom commit message when pushing a spec. * Add the ability to add a custom commit message when pushing a spec.
...@@ -101,6 +135,18 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -101,6 +135,18 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
changes, ensuring backwards-incompatible changes are properly applied. changes, ensuring backwards-incompatible changes are properly applied.
[Samuel Giddins](https://github.com/segiddins) [Samuel Giddins](https://github.com/segiddins)
* The Podfile now allows specifying installation options via the `install!`
directive.
[Samuel Giddins](https://github.com/segiddins)
[Core#151](https://github.com/CocoaPods/Core/issues/151)
* The Podfile now allows marking targets as `abstract` and specifying the pod
inheritance mode via the `inherit!` directive.
[Samuel Giddins](https://github.com/segiddins)
[#1249](https://github.com/CocoaPods/CocoaPods/issues/1249)
[#1626](https://github.com/CocoaPods/CocoaPods/issues/1626)
[#4001](https://github.com/CocoaPods/CocoaPods/issues/4001)
##### Bug Fixes ##### Bug Fixes
* Fix compiling of localized resources. * Fix compiling of localized resources.
...@@ -184,6 +230,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -184,6 +230,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Samuel Giddins](https://github.com/segiddins) [Samuel Giddins](https://github.com/segiddins)
[#4550](https://github.com/CocoaPods/CocoaPods/issues/4550) [#4550](https://github.com/CocoaPods/CocoaPods/issues/4550)
* Empty podfiles / target blocks no longer break the user's Xcode project.
[Samuel Giddins](https://github.com/segiddins)
[#3617](https://github.com/CocoaPods/CocoaPods/issues/3617)
## 0.39.0 (2015-10-09) ## 0.39.0 (2015-10-09)
......
...@@ -7,7 +7,7 @@ GIT ...@@ -7,7 +7,7 @@ GIT
GIT GIT
remote: https://github.com/CocoaPods/Core.git remote: https://github.com/CocoaPods/Core.git
revision: 0851a1e712e1e1c206ed03f67a25ef28af52fa69 revision: ca0a5d504357e48da31b274430a966d64fd62078
branch: master branch: master
specs: specs:
cocoapods-core (0.39.0) cocoapods-core (0.39.0)
......
...@@ -39,8 +39,6 @@ module Pod ...@@ -39,8 +39,6 @@ module Pod
module Options module Options
def options def options
[ [
['--no-clean', 'Leave SCM dirs like `.git` and `.svn` intact after downloading'],
['--no-integrate', 'Skip integration of the Pods libraries in the Xcode project(s)'],
['--no-repo-update', 'Skip running `pod repo update` before install'], ['--no-repo-update', 'Skip running `pod repo update` before install'],
].concat(super) ].concat(super)
end end
...@@ -51,8 +49,6 @@ module Pod ...@@ -51,8 +49,6 @@ module Pod
end end
def initialize(argv) def initialize(argv)
config.clean = argv.flag?('clean', config.clean)
config.integrate_targets = argv.flag?('integrate', config.integrate_targets)
config.skip_repo_update = !argv.flag?('repo-update', !config.skip_repo_update) config.skip_repo_update = !argv.flag?('repo-update', !config.skip_repo_update)
super super
end end
......
...@@ -34,8 +34,6 @@ module Pod ...@@ -34,8 +34,6 @@ module Pod
set_master_repo_url set_master_repo_url
set_master_repo_branch set_master_repo_branch
update_master_repo update_master_repo
elsif old_master_repo_dir.exist?
migrate_repos
else else
add_master_repo add_master_repo
end end
...@@ -48,22 +46,6 @@ module Pod ...@@ -48,22 +46,6 @@ module Pod
# @!group Setup steps # @!group Setup steps
# Migrates any repos from the old directory structure to the new
# directory structure.
#
# @todo: Remove by 1.0
#
def migrate_repos
config.repos_dir.mkpath
Dir.foreach old_master_repo_dir.parent do |repo_dir|
source_repo_dir = old_master_repo_dir.parent + repo_dir
target_repo_dir = config.repos_dir + repo_dir
if repo_dir !~ /\.+/ && source_repo_dir != config.repos_dir
FileUtils.mv source_repo_dir, target_repo_dir
end
end
end
# Sets the url of the master repo according to whether it is push. # Sets the url of the master repo according to whether it is push.
# #
# @return [void] # @return [void]
...@@ -127,12 +109,6 @@ module Pod ...@@ -127,12 +109,6 @@ module Pod
def master_repo_dir def master_repo_dir
SourcesManager.master_repo_dir SourcesManager.master_repo_dir
end end
# @return [Pathname] the directory of the old master repo.
#
def old_master_repo_dir
Pathname.new('~/.cocoapods/master').expand_path
end
end end
end end
end end
...@@ -17,11 +17,6 @@ module Pod ...@@ -17,11 +17,6 @@ module Pod
:skip_repo_update => false, :skip_repo_update => false,
:skip_download_cache => !ENV['COCOAPODS_SKIP_CACHE'].nil?, :skip_download_cache => !ENV['COCOAPODS_SKIP_CACHE'].nil?,
:clean => true,
:integrate_targets => true,
:deduplicate_targets => true,
:deterministic_uuids => ENV['COCOAPODS_DISABLE_DETERMINISTIC_UUIDS'].nil?,
:lock_pod_source => true,
:new_version_message => ENV['COCOAPODS_SKIP_UPDATE_MESSAGE'].nil?, :new_version_message => ENV['COCOAPODS_SKIP_UPDATE_MESSAGE'].nil?,
:cache_root => Pathname.new(Dir.home) + 'Library/Caches/CocoaPods', :cache_root => Pathname.new(Dir.home) + 'Library/Caches/CocoaPods',
...@@ -74,34 +69,6 @@ module Pod ...@@ -74,34 +69,6 @@ module Pod
# @!group Installation # @!group Installation
# @return [Bool] Whether the installer should clean after the installation.
#
attr_accessor :clean
alias_method :clean?, :clean
# @return [Bool] Whether the installer should remove write permissions for
# installed pod source files after the installation.
#
attr_accessor :lock_pod_source
alias_method :lock_pod_source?, :lock_pod_source
# @return [Bool] Whether CocoaPods should integrate a user target and build
# the workspace or just create the Pods project.
#
attr_accessor :integrate_targets
alias_method :integrate_targets?, :integrate_targets
# @return [Bool] Whether CocoaPods should deduplicate pod targets.
#
attr_accessor :deduplicate_targets
alias_method :deduplicate_targets?, :deduplicate_targets
# @return [Bool] Whether CocoaPods should give the pods project
# deterministic UUIDs.
#
attr_accessor :deterministic_uuids
alias_method :deterministic_uuids?, :deterministic_uuids
# @return [Bool] Whether the installer should skip the repos update. # @return [Bool] Whether the installer should skip the repos update.
# #
attr_accessor :skip_repo_update attr_accessor :skip_repo_update
......
...@@ -20,16 +20,21 @@ module Pod ...@@ -20,16 +20,21 @@ module Pod
# the location to which this pod should be downloaded. If `nil`, # the location to which this pod should be downloaded. If `nil`,
# then the pod will only be cached. # then the pod will only be cached.
# #
# @param [Boolean] can_cache
# whether caching is allowed.
#
# @param [Pathname,Nil] cache_path # @param [Pathname,Nil] cache_path
# the path used to cache pod downloads. If `nil`, then no caching # the path used to cache pod downloads.
# will be done.
# #
def self.download( def self.download(
request, request,
target, target,
cache_path: !Config.instance.skip_download_cache && Config.instance.clean? && Config.instance.cache_root + 'Pods' can_cache: true,
cache_path: Config.instance.cache_root + 'Pods'
) )
if cache_path can_cache &&= !Config.instance.skip_download_cache
if can_cache
raise ArgumentError, 'Must provide a `cache_path` when caching.' unless cache_path
cache = Cache.new(cache_path) cache = Cache.new(cache_path)
result = cache.download_pod(request) result = cache.download_pod(request)
else else
......
...@@ -46,10 +46,6 @@ module Pod ...@@ -46,10 +46,6 @@ module Pod
PodspecSource PodspecSource
elsif params.key?(:path) elsif params.key?(:path)
PathSource PathSource
elsif params.key?(:local)
UI.warn 'The `:local` option of the Podfile has been ' \
'renamed to `:path` and it is deprecated.'
PathSource
elsif Downloader.strategy_from_options(params) elsif Downloader.strategy_from_options(params)
DownloaderSource DownloaderSource
end end
......
...@@ -17,6 +17,11 @@ module Pod ...@@ -17,6 +17,11 @@ module Pod
# #
attr_reader :podfile_path attr_reader :podfile_path
# @return [Boolean] Whether the source is allowed to touch the cache.
#
attr_accessor :can_cache
alias_method :can_cache?, :can_cache
# Initialize a new instance # Initialize a new instance
# #
# @param [String] name @see name # @param [String] name @see name
...@@ -27,6 +32,7 @@ module Pod ...@@ -27,6 +32,7 @@ module Pod
@name = name @name = name
@params = params @params = params
@podfile_path = podfile_path @podfile_path = podfile_path
@can_cache = true
end end
# @return [Bool] whether an external source source is equal to another # @return [Bool] whether an external source source is equal to another
...@@ -105,7 +111,7 @@ module Pod ...@@ -105,7 +111,7 @@ module Pod
title = "Pre-downloading: `#{name}` #{description}" title = "Pre-downloading: `#{name}` #{description}"
UI.titled_section(title, :verbose_prefix => '-> ') do UI.titled_section(title, :verbose_prefix => '-> ') do
target = sandbox.pod_dir(name) target = sandbox.pod_dir(name)
download_result = Downloader.download(download_request, target) download_result = Downloader.download(download_request, target, :can_cache => can_cache)
spec = download_result.spec spec = download_result.spec
raise Informative, "Unable to find a specification for '#{name}'." unless spec raise Informative, "Unable to find a specification for '#{name}'." unless spec
......
...@@ -24,7 +24,7 @@ module Pod ...@@ -24,7 +24,7 @@ module Pod
# @see AbstractExternalSource#description # @see AbstractExternalSource#description
# #
def description def description
"from `#{params[:path] || params[:local]}`" "from `#{declared_path}`"
end end
private private
...@@ -34,7 +34,7 @@ module Pod ...@@ -34,7 +34,7 @@ module Pod
# @return [String] The path as declared by the user. # @return [String] The path as declared by the user.
# #
def declared_path def declared_path
result = params[:path] || params[:local] result = params[:path]
result.to_s if result result.to_s if result
end end
......
...@@ -87,15 +87,12 @@ module Pod ...@@ -87,15 +87,12 @@ module Pod
#---------------------------------------------------------------------# #---------------------------------------------------------------------#
private protected
# Add build settings, which ensure that the pod targets can be imported # @return [Hash<String, String>] the build settings necessary to import
# from the integrating target by all sort of imports, which are: # the pod targets.
# - `#import <…>`
# - `#import "…"`
# - `@import …;` / `import …`
# #
def generate_settings_to_import_pod_targets def settings_to_import_pod_targets
if target.requires_frameworks? if target.requires_frameworks?
framework_header_search_paths = pod_targets.select(&:should_build?).map do |target| framework_header_search_paths = pod_targets.select(&:should_build?).map do |target|
if target.scoped? if target.scoped?
...@@ -118,17 +115,32 @@ module Pod ...@@ -118,17 +115,32 @@ module Pod
if pod_targets.any? { |t| t.should_build? && t.scoped? } if pod_targets.any? { |t| t.should_build? && t.scoped? }
build_settings['FRAMEWORK_SEARCH_PATHS'] = '"$PODS_FRAMEWORK_BUILD_PATH"' build_settings['FRAMEWORK_SEARCH_PATHS'] = '"$PODS_FRAMEWORK_BUILD_PATH"'
end end
@xcconfig.merge!(build_settings) build_settings
else else
# Make headers discoverable from $PODS_ROOT/Headers directory # Make headers discoverable from $PODS_ROOT/Headers directory
header_search_paths = target.sandbox.public_headers.search_paths(target.platform) header_search_paths = target.sandbox.public_headers.search_paths(target.platform)
build_settings = { {
# by `#import "…"` # by `#import "…"`
'HEADER_SEARCH_PATHS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths), 'HEADER_SEARCH_PATHS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths),
# by `#import <…>` # by `#import <…>`
'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-isystem'), 'OTHER_CFLAGS' => '$(inherited) ' + XCConfigHelper.quote(header_search_paths, '-isystem'),
} }
@xcconfig.merge!(build_settings) end
end
private
# Add build settings, which ensure that the pod targets can be imported
# from the integrating target by all sort of imports, which are:
# - `#import <…>`
# - `#import "…"`
# - `@import …;` / `import …`
#
def generate_settings_to_import_pod_targets
@xcconfig.merge!(settings_to_import_pod_targets)
target.search_paths_aggregate_targets.each do |search_paths_target|
generator = AggregateXCConfig.new(search_paths_target, configuration_name)
@xcconfig.merge!(generator.settings_to_import_pod_targets)
end end
end end
......
...@@ -44,11 +44,9 @@ module Pod ...@@ -44,11 +44,9 @@ module Pod
# #
def initialize(name, plugin_name, block) def initialize(name, plugin_name, block)
raise ArgumentError, 'Missing name' unless name raise ArgumentError, 'Missing name' unless name
raise ArgumentError, 'Missing plugin_name' unless plugin_name
raise ArgumentError, 'Missing block' unless block raise ArgumentError, 'Missing block' unless block
UI.warn '[Hooks] The use of hooks without specifying a `plugin_name` ' \
"has been deprecated (from file `#{block.binding.eval('File.expand_path __FILE__')}`)." unless plugin_name
@name = name @name = name
@plugin_name = plugin_name @plugin_name = plugin_name
@block = block @block = block
...@@ -72,13 +70,7 @@ module Pod ...@@ -72,13 +70,7 @@ module Pod
# @param [Proc] block # @param [Proc] block
# The block. # The block.
# #
def register(plugin_name, hook_name = nil, &block) def register(plugin_name, hook_name, &block)
# TODO: Backwards compatibility with nameless plugins from CP 0.34
if hook_name.nil?
hook_name = plugin_name
plugin_name = nil
end
@registrations ||= {} @registrations ||= {}
@registrations[hook_name] ||= [] @registrations[hook_name] ||= []
@registrations[hook_name] << Hook.new(hook_name, plugin_name, block) @registrations[hook_name] << Hook.new(hook_name, plugin_name, block)
...@@ -108,7 +100,7 @@ module Pod ...@@ -108,7 +100,7 @@ module Pod
UI.message "- Running #{name.to_s.tr('_', ' ')} hooks" do UI.message "- Running #{name.to_s.tr('_', ' ')} hooks" do
hooks.each do |hook| hooks.each do |hook|
next if whitelisted_plugins && !whitelisted_plugins.key?(hook.plugin_name) next if whitelisted_plugins && !whitelisted_plugins.key?(hook.plugin_name)
UI.message "- #{hook.plugin_name || 'unknown plugin'} from " \ UI.message "- #{hook.plugin_name} from " \
"`#{hook.block.source_location.first}`" do "`#{hook.block.source_location.first}`" do
block = hook.block block = hook.block
if block.arity > 1 if block.arity > 1
......
...@@ -32,6 +32,7 @@ module Pod ...@@ -32,6 +32,7 @@ module Pod
autoload :AggregateTargetInstaller, 'cocoapods/installer/target_installer/aggregate_target_installer' autoload :AggregateTargetInstaller, 'cocoapods/installer/target_installer/aggregate_target_installer'
autoload :Analyzer, 'cocoapods/installer/analyzer' autoload :Analyzer, 'cocoapods/installer/analyzer'
autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer' autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer'
autoload :InstallationOptions, 'cocoapods/installer/installation_options'
autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context' autoload :PostInstallHooksContext, 'cocoapods/installer/post_install_hooks_context'
autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context' autoload :PreInstallHooksContext, 'cocoapods/installer/pre_install_hooks_context'
autoload :SourceProviderHooksContext, 'cocoapods/installer/source_provider_hooks_context' autoload :SourceProviderHooksContext, 'cocoapods/installer/source_provider_hooks_context'
...@@ -44,6 +45,9 @@ module Pod ...@@ -44,6 +45,9 @@ module Pod
autoload :UserProjectIntegrator, 'cocoapods/installer/user_project_integrator' autoload :UserProjectIntegrator, 'cocoapods/installer/user_project_integrator'
include Config::Mixin include Config::Mixin
include InstallationOptions::Mixin
delegate_installation_options { podfile }
# @return [Sandbox] The sandbox where the Pods should be installed. # @return [Sandbox] The sandbox where the Pods should be installed.
# #
...@@ -109,7 +113,7 @@ module Pod ...@@ -109,7 +113,7 @@ module Pod
verify_no_static_framework_transitive_dependencies verify_no_static_framework_transitive_dependencies
verify_framework_usage verify_framework_usage
generate_pods_project generate_pods_project
integrate_user_project if config.integrate_targets? integrate_user_project if installation_options.integrate_targets?
perform_post_install_actions perform_post_install_actions
end end
...@@ -221,7 +225,9 @@ module Pod ...@@ -221,7 +225,9 @@ module Pod
end end
def create_analyzer def create_analyzer
Analyzer.new(sandbox, podfile, lockfile) Analyzer.new(sandbox, podfile, lockfile).tap do |analyzer|
analyzer.installation_options = installation_options
end
end end
# Ensures that the white-listed build configurations are known to prevent # Ensures that the white-listed build configurations are known to prevent
...@@ -318,7 +324,7 @@ module Pod ...@@ -318,7 +324,7 @@ module Pod
end end
@pod_installers ||= [] @pod_installers ||= []
pod_installer = PodSourceInstaller.new(sandbox, specs_by_platform) pod_installer = PodSourceInstaller.new(sandbox, specs_by_platform, :can_cache => installation_options.clean?)
@pod_installers << pod_installer @pod_installers << pod_installer
pod_installer pod_installer
end end
...@@ -340,7 +346,7 @@ module Pod ...@@ -340,7 +346,7 @@ module Pod
# @todo Why the @pod_installers might be empty? # @todo Why the @pod_installers might be empty?
# #
def clean_pod_sources def clean_pod_sources
return unless config.clean? return unless installation_options.clean?
return unless @pod_installers return unless @pod_installers
@pod_installers.each(&:clean!) @pod_installers.each(&:clean!)
end end
...@@ -362,7 +368,7 @@ module Pod ...@@ -362,7 +368,7 @@ module Pod
# @todo Why the @pod_installers might be empty? # @todo Why the @pod_installers might be empty?
# #
def lock_pod_sources def lock_pod_sources
return unless config.lock_pod_source? return unless installation_options.lock_pod_sources?
return unless @pod_installers return unless @pod_installers
@pod_installers.each do |installer| @pod_installers.each do |installer|
pod_target = pod_targets.find { |target| target.pod_name == installer.name } pod_target = pod_targets.find { |target| target.pod_name == installer.name }
...@@ -623,13 +629,13 @@ module Pod ...@@ -623,13 +629,13 @@ module Pod
def install_libraries def install_libraries
UI.message '- Installing targets' do UI.message '- Installing targets' do
pod_targets.sort_by(&:name).each do |pod_target| pod_targets.sort_by(&:name).each do |pod_target|
next if pod_target.target_definitions.flat_map(&:dependencies).empty? next if pod_target.target_definitions.all?(&:abstract?)
target_installer = PodTargetInstaller.new(sandbox, pod_target) target_installer = PodTargetInstaller.new(sandbox, pod_target)
target_installer.install! target_installer.install!
end end
aggregate_targets.sort_by(&:name).each do |target| aggregate_targets.sort_by(&:name).each do |target|
next if target.target_definition.dependencies.empty? next if target.target_definition.abstract?
target_installer = AggregateTargetInstaller.new(sandbox, target) target_installer = AggregateTargetInstaller.new(sandbox, target)
target_installer.install! target_installer.install!
end end
...@@ -706,7 +712,7 @@ module Pod ...@@ -706,7 +712,7 @@ module Pod
pods_project.development_pods.remove_from_project if pods_project.development_pods.empty? pods_project.development_pods.remove_from_project if pods_project.development_pods.empty?
pods_project.sort(:groups_position => :below) pods_project.sort(:groups_position => :below)
pods_project.recreate_user_schemes(false) pods_project.recreate_user_schemes(false)
if config.deterministic_uuids? if installation_options.deterministic_uuids?
UI.message('- Generating deterministic UUIDs') { pods_project.predictabilize_uuids } UI.message('- Generating deterministic UUIDs') { pods_project.predictabilize_uuids }
end end
pods_project.save pods_project.save
......
...@@ -5,6 +5,9 @@ module Pod ...@@ -5,6 +5,9 @@ module Pod
# #
class Analyzer class Analyzer
include Config::Mixin include Config::Mixin
include InstallationOptions::Mixin
delegate_installation_options { podfile }
autoload :AnalysisResult, 'cocoapods/installer/analyzer/analysis_result' autoload :AnalysisResult, 'cocoapods/installer/analyzer/analysis_result'
autoload :SandboxAnalyzer, 'cocoapods/installer/analyzer/sandbox_analyzer' autoload :SandboxAnalyzer, 'cocoapods/installer/analyzer/sandbox_analyzer'
...@@ -57,7 +60,7 @@ module Pod ...@@ -57,7 +60,7 @@ module Pod
validate_podfile! validate_podfile!
validate_lockfile_version! validate_lockfile_version!
@result = AnalysisResult.new @result = AnalysisResult.new
if config.integrate_targets? if installation_options.integrate_targets?
@result.target_inspections = inspect_targets_to_integrate @result.target_inspections = inspect_targets_to_integrate
else else
verify_platforms_specified! verify_platforms_specified!
...@@ -157,6 +160,7 @@ module Pod ...@@ -157,6 +160,7 @@ module Pod
unless validator.valid? unless validator.valid?
raise Informative, validator.message raise Informative, validator.message
end end
validator.warnings.uniq.each { |w| UI.warn(w) }
end end
# @!group Analysis steps # @!group Analysis steps
...@@ -225,9 +229,14 @@ module Pod ...@@ -225,9 +229,14 @@ module Pod
# #
def generate_targets def generate_targets
pod_targets = generate_pod_targets(result.specs_by_target) pod_targets = generate_pod_targets(result.specs_by_target)
result.specs_by_target.map do |target_definition, _| aggregate_targets = result.specs_by_target.keys.reject(&:abstract?).map do |target_definition|
generate_target(target_definition, pod_targets) generate_target(target_definition, pod_targets)
end end
aggregate_targets.each do |target|
target.search_paths_aggregate_targets = aggregate_targets.select do |aggregate_target|
target.target_definition.targets_to_inherit_search_paths.include?(aggregate_target.target_definition)
end
end
end end
# Setup the aggregate target for a single user target # Setup the aggregate target for a single user target
...@@ -244,8 +253,9 @@ module Pod ...@@ -244,8 +253,9 @@ module Pod
target = AggregateTarget.new(target_definition, sandbox) target = AggregateTarget.new(target_definition, sandbox)
target.host_requires_frameworks |= target_definition.uses_frameworks? target.host_requires_frameworks |= target_definition.uses_frameworks?
if config.integrate_targets? if installation_options.integrate_targets?
target_inspection = result.target_inspections[target_definition] target_inspection = result.target_inspections[target_definition]
raise "missing inspection: #{target_definition.name}" unless target_inspection
target.user_project = target_inspection.project target.user_project = target_inspection.project
target.client_root = target.user_project_path.dirname.realpath target.client_root = target.user_project_path.dirname.realpath
target.user_target_uuids = target_inspection.project_target_uuids target.user_target_uuids = target_inspection.project_target_uuids
...@@ -276,7 +286,7 @@ module Pod ...@@ -276,7 +286,7 @@ module Pod
# @return [Array<PodTarget>] # @return [Array<PodTarget>]
# #
def generate_pod_targets(specs_by_target) def generate_pod_targets(specs_by_target)
if config.deduplicate_targets? if installation_options.deduplicate_targets?
dedupe_cache = {} dedupe_cache = {}
all_specs = specs_by_target.flat_map do |target_definition, dependent_specs| all_specs = specs_by_target.flat_map do |target_definition, dependent_specs|
...@@ -371,7 +381,7 @@ module Pod ...@@ -371,7 +381,7 @@ module Pod
def generate_pod_target(target_definitions, pod_specs) def generate_pod_target(target_definitions, pod_specs)
pod_target = PodTarget.new(pod_specs, target_definitions, sandbox) pod_target = PodTarget.new(pod_specs, target_definitions, sandbox)
if config.integrate_targets? if installation_options.integrate_targets?
target_inspections = result.target_inspections.select { |t, _| target_definitions.include?(t) }.values target_inspections = result.target_inspections.select { |t, _| target_definitions.include?(t) }.values
pod_target.user_build_configurations = target_inspections.map(&:build_configurations).reduce({}, &:merge) pod_target.user_build_configurations = target_inspections.map(&:build_configurations).reduce({}, &:merge)
pod_target.archs = target_inspections.flat_map(&:archs).compact.uniq.sort pod_target.archs = target_inspections.flat_map(&:archs).compact.uniq.sort
...@@ -456,6 +466,7 @@ module Pod ...@@ -456,6 +466,7 @@ module Pod
else else
source = ExternalSources.from_dependency(dependency, podfile.defined_in_file) source = ExternalSources.from_dependency(dependency, podfile.defined_in_file)
end end
source.can_cache = installation_options.clean?
source.fetch(sandbox) source.fetch(sandbox)
end end
...@@ -471,7 +482,6 @@ module Pod ...@@ -471,7 +482,6 @@ module Pod
deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.name) } deps_to_fetch_if_needed = deps_with_external_source.select { |dep| result.podfile_state.unchanged.include?(dep.name) }
deps_to_fetch += deps_to_fetch_if_needed.select do |dep| deps_to_fetch += deps_to_fetch_if_needed.select do |dep|
sandbox.specification(dep.name).nil? || sandbox.specification(dep.name).nil? ||
!dep.external_source[:local].nil? ||
!dep.external_source[:path].nil? || !dep.external_source[:path].nil? ||
!sandbox.pod_dir(dep.root_name).directory? || !sandbox.pod_dir(dep.root_name).directory? ||
checkout_requires_update?(dep) checkout_requires_update?(dep)
...@@ -644,7 +654,7 @@ module Pod ...@@ -644,7 +654,7 @@ module Pod
# @return [void] # @return [void]
# #
def verify_platforms_specified! def verify_platforms_specified!
unless config.integrate_targets? unless installation_options.integrate_targets?
podfile.target_definition_list.each do |target_definition| podfile.target_definition_list.each do |target_definition|
if !target_definition.empty? && target_definition.platform.nil? if !target_definition.empty? && target_definition.platform.nil?
raise Informative, 'It is necessary to specify the platform in the Podfile if not integrating.' raise Informative, 'It is necessary to specify the platform in the Podfile if not integrating.'
...@@ -665,8 +675,9 @@ module Pod ...@@ -665,8 +675,9 @@ module Pod
inspection_result = {} inspection_result = {}
UI.section 'Inspecting targets to integrate' do UI.section 'Inspecting targets to integrate' do
inspectors = podfile.target_definition_list.map do |target_definition| inspectors = podfile.target_definition_list.map do |target_definition|
next if target_definition.abstract?
TargetInspector.new(target_definition, config.installation_root) TargetInspector.new(target_definition, config.installation_root)
end end.compact
inspectors.group_by(&:compute_project_path).each do |project_path, target_inspectors| inspectors.group_by(&:compute_project_path).each do |project_path, target_inspectors|
project = Xcodeproj::Project.open(project_path) project = Xcodeproj::Project.open(project_path)
target_inspectors.each do |inspector| target_inspectors.each do |inspector|
......
...@@ -14,7 +14,7 @@ module Pod ...@@ -14,7 +14,7 @@ module Pod
# - The version of the Pod changed. # - The version of the Pod changed.
# - The SHA of the specification file changed. # - The SHA of the specification file changed.
# - The specific installed (sub)specs of the same Pod changed. # - The specific installed (sub)specs of the same Pod changed.
# - The specification is in head mode or from an external source and the # - The specification is from an external source and the
# installation process is in update mode. # installation process is in update mode.
# - The directory of the Pod is empty. # - The directory of the Pod is empty.
# - The Pod has been pre-downloaded. # - The Pod has been pre-downloaded.
...@@ -135,7 +135,7 @@ module Pod ...@@ -135,7 +135,7 @@ module Pod
# changed and thus should be reinstalled. # changed and thus should be reinstalled.
# #
# @note In update mode, as there is no way to know if a remote source # @note In update mode, as there is no way to know if a remote source
# hash changed the Pods in head mode and the ones from external # hash changed the Pods from external
# sources are always marked as changed. # sources are always marked as changed.
# #
# @note A Pod whose folder is empty is considered changed. # @note A Pod whose folder is empty is considered changed.
...@@ -152,10 +152,6 @@ module Pod ...@@ -152,10 +152,6 @@ module Pod
return true if resolved_spec_names(pod) != sandbox_spec_names(pod) return true if resolved_spec_names(pod) != sandbox_spec_names(pod)
return true if sandbox.predownloaded?(pod) return true if sandbox.predownloaded?(pod)
return true if folder_empty?(pod) return true if folder_empty?(pod)
return true if sandbox.head_pod?(pod) != sandbox_head_version?(pod)
if update_mode
return true if sandbox.head_pod?(pod)
end
false false
end end
...@@ -238,13 +234,6 @@ module Pod ...@@ -238,13 +234,6 @@ module Pod
sandbox_manifest.checksum(pod) sandbox_manifest.checksum(pod)
end end
# @return [Bool] Wether the Pod is installed in the sandbox is in head
# mode.
#
def sandbox_head_version?(pod)
sandbox_version(pod).head? == true
end
#--------------------------------------# #--------------------------------------#
def folder_exist?(pod) def folder_exist?(pod)
......
require 'active_support/core_ext/array/conversions'
module Pod module Pod
class Installer class Installer
class Analyzer class Analyzer
...@@ -102,19 +104,12 @@ module Pod ...@@ -102,19 +104,12 @@ module Pod
# #
def compute_targets(user_project) def compute_targets(user_project)
native_targets = user_project.native_targets native_targets = user_project.native_targets
if link_with = target_definition.link_with
targets = native_targets.select { |t| link_with.include?(t.name) }
raise Informative, "Unable to find the targets named #{link_with.map { |x| "`#{x}`" }.to_sentence}" \
"to link with target definition `#{target_definition.name}`" if targets.empty?
elsif target_definition.link_with_first_target?
targets = [native_targets.first].compact
raise Informative, 'Unable to find a target' if targets.empty?
else
target = native_targets.find { |t| t.name == target_definition.name.to_s } target = native_targets.find { |t| t.name == target_definition.name.to_s }
targets = [target].compact unless target
raise Informative, "Unable to find a target named `#{target_definition.name}`" if targets.empty? found = native_targets.map { |t| "`#{t.name}`" }.to_sentence
raise Informative, "Unable to find a target named `#{target_definition.name}`, did find #{found}."
end end
targets [target]
end end
# @param [Array<PBXNativeTarget] the user's targets of the project of # @param [Array<PBXNativeTarget] the user's targets of the project of
......
require 'active_support/hash_with_indifferent_access'
module Pod
class Installer
# Represents the installation options the user can customize via a
# `Podfile`.
#
class InstallationOptions
# Parses installation options from a podfile.
#
# @param [Podfile] podfile the podfile to parse installation options
# from.
#
# @raise [Informative] if `podfile` does not specify a `CocoaPods`
# install.
#
# @return [Self]
#
def self.from_podfile(podfile)
name, options = podfile.installation_method
unless name.downcase == 'cocoapods'
raise Informative, "Currently need to specify a `cocoapods` install, you chose `#{name}`."
end
new(options)
end
# Defines a new installation option.
#
# @param [#to_s] name the name of the option.
#
# @param default the default value for the option.
#
# @param [Boolean] boolean whether the option has a boolean value.
#
# @return [void]
#
# @!macro [attach] option
#
# @note this option defaults to $2.
#
# @return the $1 $0 for installation.
#
def self.option(name, default, boolean: true)
name = name.to_s
raise ArgumentError, "The `#{name}` option is already defined" if defaults.key?(name)
defaults[name] = default
attr_accessor name
alias_method "#{name}?", name if boolean
end
# @return [Hash<Symbol,Object>] all known installation options and their
# default values.
#
def self.defaults
@defaults ||= {}
end
# @return [Array<Symbol>] the names of all known installation options.
#
def self.all_options
defaults.keys
end
# Initializes the installation options with a hash of options from a
# Podfile.
#
# @param [Hash] options the options to parse.
#
# @raise [Informative] if `options` contains any unknown keys.
#
def initialize(options = {})
options = ActiveSupport::HashWithIndifferentAccess.new(options)
unknown_keys = options.keys - self.class.all_options.map(&:to_s)
raise Informative, "Unknown installation options: #{unknown_keys.to_sentence}." unless unknown_keys.empty?
self.class.defaults.each do |key, default|
value = options.fetch(key, default)
send("#{key}=", value)
end
end
# @param [Boolean] include_defaults whether values that match the default
# for their option should be included. Defaults to `true`.
#
# @return [Hash] the options, keyed by option name.
#
def to_h(include_defaults: true)
self.class.defaults.reduce(ActiveSupport::HashWithIndifferentAccess.new) do |hash, (option, default)|
value = send(option)
hash[option] = value if include_defaults || value != default
hash
end
end
def ==(other)
other.is_a?(self.class) && to_h == other.to_h
end
alias_method :eql, :==
def hash
to_h.hash
end
option :clean, true
option :deduplicate_targets, true
option :deterministic_uuids, true
option :integrate_targets, true
option :lock_pod_sources, true
module Mixin
module ClassMethods
# Delegates the creation of {#installation_options} to the `Podfile`
# returned by the given block.
#
# @param blk a block that returns the `Podfile` to create
# installation options from.
#
# @return [Void]
#
def delegate_installation_options(&blk)
define_method(:installation_options) do
@installation_options ||= InstallationOptions.from_podfile(instance_eval(&blk))
end
end
# Delegates the installation options attributes directly to
# {#installation_options}.
#
# @return [Void]
#
def delegate_installation_option_attributes!
define_method(:respond_to_missing?) do |name, *args|
installation_options.respond_to?(name, *args) || super
end
define_method(:method_missing) do |name, *args, &blk|
if installation_options.respond_to?(name)
installation_options.send(name, *args, &blk)
else
super
end
end
end
end
# @return [InstallationOptions] The installation options.
#
attr_accessor :installation_options
def self.included(mod)
mod.extend(ClassMethods)
end
end
end
end
end
...@@ -17,14 +17,21 @@ module Pod ...@@ -17,14 +17,21 @@ module Pod
# #
attr_reader :specs_by_platform attr_reader :specs_by_platform
# @return [Boolean] Whether the installer is allowed to touch the cache.
#
attr_reader :can_cache
alias_method :can_cache?, :can_cache
# Initialize a new instance # Initialize a new instance
# #
# @param [Sandbox] sandbox @see sandbox # @param [Sandbox] sandbox @see sandbox
# @param [Hash{Symbol=>Array}] specs_by_platform @see specs_by_platform # @param [Hash{Symbol=>Array}] specs_by_platform @see specs_by_platform
# @param [Boolean] can_cache @see can_cache
# #
def initialize(sandbox, specs_by_platform) def initialize(sandbox, specs_by_platform, can_cache: true)
@sandbox = sandbox @sandbox = sandbox
@specs_by_platform = specs_by_platform @specs_by_platform = specs_by_platform
@can_cache = can_cache
end end
# @return [String] A string suitable for debugging. # @return [String] A string suitable for debugging.
...@@ -110,7 +117,7 @@ module Pod ...@@ -110,7 +117,7 @@ module Pod
# @return [void] # @return [void]
# #
def download_source def download_source
download_result = Downloader.download(download_request, root) download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source
sandbox.store_checkout_source(root_spec.name, specific_source) sandbox.store_checkout_source(root_spec.name, specific_source)
...@@ -121,7 +128,6 @@ module Pod ...@@ -121,7 +128,6 @@ module Pod
Downloader::Request.new( Downloader::Request.new(
:spec => root_spec, :spec => root_spec,
:released => released?, :released => released?,
:head => head_pod?,
) )
end end
...@@ -174,12 +180,8 @@ module Pod ...@@ -174,12 +180,8 @@ module Pod
sandbox.local?(root_spec.name) sandbox.local?(root_spec.name)
end end
def head_pod?
sandbox.head_pod?(root_spec.name)
end
def released? def released?
!local? && !head_pod? && !predownloaded? && sandbox.specification(root_spec.name) != root_spec !local? && !predownloaded? && sandbox.specification(root_spec.name) != root_spec
end end
def each_source_file(file_accessors, &blk) def each_source_file(file_accessors, &blk)
......
...@@ -12,6 +12,10 @@ module Pod ...@@ -12,6 +12,10 @@ module Pod
# #
attr_reader :errors attr_reader :errors
# @return [Array<String>] any warnings that have occured during the validation
#
attr_reader :warnings
# Initialize a new instance # Initialize a new instance
# @param [Podfile] podfile # @param [Podfile] podfile
# The podfile to validate # The podfile to validate
...@@ -19,6 +23,7 @@ module Pod ...@@ -19,6 +23,7 @@ module Pod
def initialize(podfile) def initialize(podfile)
@podfile = podfile @podfile = podfile
@errors = [] @errors = []
@warnings = []
@validated = false @validated = false
end end
...@@ -27,6 +32,8 @@ module Pod ...@@ -27,6 +32,8 @@ module Pod
# #
def validate def validate
validate_pod_directives validate_pod_directives
validate_no_abstract_only_pods!
validate_dependencies_are_present!
@validated = true @validated = true
end end
...@@ -38,7 +45,7 @@ module Pod ...@@ -38,7 +45,7 @@ module Pod
def valid? def valid?
validate unless @validated validate unless @validated
@validated && errors.size == 0 @validated && errors.empty?
end end
# A message describing any errors in the # A message describing any errors in the
...@@ -54,6 +61,10 @@ module Pod ...@@ -54,6 +61,10 @@ module Pod
errors << error errors << error
end end
def add_warning(warning)
warnings << warning
end
def validate_pod_directives def validate_pod_directives
dependencies = podfile.target_definitions.flat_map do |_, target| dependencies = podfile.target_definitions.flat_map do |_, target|
target.dependencies target.dependencies
...@@ -81,6 +92,36 @@ module Pod ...@@ -81,6 +92,36 @@ module Pod
' download strategies. This is not allowed' ' download strategies. This is not allowed'
end end
end end
# Warns the user if the podfile is empty.
#
# @note The workspace is created in any case and all the user projects
# are added to it, however the projects are not integrated as
# there is no way to discern between target definitions which are
# empty and target definitions which just serve the purpose to
# wrap other ones. This is not an issue because empty target
# definitions generate empty libraries.
#
# @return [void]
#
def validate_dependencies_are_present!
if podfile.target_definitions.values.all?(&:empty?)
add_warning 'The Podfile does not contain any dependencies.'
end
end
# Verifies that no dependencies in the Podfile will end up not being built
# at all. In other words, all dependencies _must_ belong to a non-abstract
# target, or be inherited by a target where `inheritance == complete`.
#
def validate_no_abstract_only_pods!
all_dependencies = podfile.dependencies
concrete_dependencies = podfile.target_definition_list.reject(&:abstract?).flat_map(&:dependencies).uniq
abstract_only_dependencies = all_dependencies - concrete_dependencies
abstract_only_dependencies.each do |dep|
add_error "The dependency `#{dep}` is not used in any concrete target."
end
end
end end
end end
end end
...@@ -61,7 +61,6 @@ module Pod ...@@ -61,7 +61,6 @@ module Pod
def integrate! def integrate!
create_workspace create_workspace
integrate_user_targets integrate_user_targets
warn_about_empty_podfile
warn_about_xcconfig_overrides warn_about_xcconfig_overrides
save_projects save_projects
end end
...@@ -152,23 +151,6 @@ module Pod ...@@ -152,23 +151,6 @@ module Pod
end end
end end
# Warns the user if the podfile is empty.
#
# @note The workspace is created in any case and all the user projects
# are added to it, however the projects are not integrated as
# there is no way to discern between target definitions which are
# empty and target definitions which just serve the purpose to
# wrap other ones. This is not an issue because empty target
# definitions generate empty libraries.
#
# @return [void]
#
def warn_about_empty_podfile
if podfile.target_definitions.values.all?(&:empty?)
UI.warn '[!] The Podfile does not contain any dependencies.'
end
end
IGNORED_KEYS = %w(CODE_SIGN_IDENTITY).freeze IGNORED_KEYS = %w(CODE_SIGN_IDENTITY).freeze
INHERITED_FLAGS = %w($(inherited) ${inherited}).freeze INHERITED_FLAGS = %w($(inherited) ${inherited}).freeze
...@@ -234,7 +216,7 @@ module Pod ...@@ -234,7 +216,7 @@ module Pod
end end
def targets_to_integrate def targets_to_integrate
targets.reject { |target| target.target_definition.empty? } targets.reject { |target| target.target_definition.abstract? }
end end
# Prints a warning informing the user that a build configuration of # Prints a warning informing the user that a build configuration of
......
...@@ -85,7 +85,7 @@ module Pod ...@@ -85,7 +85,7 @@ module Pod
end end
if existing && existing != file_ref if existing && existing != file_ref
if existing.real_path.to_path.start_with?(pod_bundle.support_files_dir.to_path) if existing.real_path.to_path.start_with?(pod_bundle.sandbox.root.to_path << '/')
set_base_configuration_reference.call set_base_configuration_reference.call
elsif !xcconfig_includes_target_xcconfig?(config.base_configuration_reference, path) elsif !xcconfig_includes_target_xcconfig?(config.base_configuration_reference, path)
UI.warn 'CocoaPods did not set the base configuration of your ' \ UI.warn 'CocoaPods did not set the base configuration of your ' \
...@@ -93,7 +93,7 @@ module Pod ...@@ -93,7 +93,7 @@ module Pod
'config set. In order for CocoaPods integration to work at ' \ 'config set. In order for CocoaPods integration to work at ' \
'all, please either set the base configurations of the target ' \ 'all, please either set the base configurations of the target ' \
"`#{target.name}` to `#{path}` or include the `#{path}` in your " \ "`#{target.name}` to `#{path}` or include the `#{path}` in your " \
'build configuration.' "build configuration (#{UI.path(existing.real_path)})."
end end
elsif config.base_configuration_reference.nil? || file_ref.nil? elsif config.base_configuration_reference.nil? || file_ref.nil?
set_base_configuration_reference.call set_base_configuration_reference.call
......
...@@ -60,11 +60,7 @@ module Pod ...@@ -60,11 +60,7 @@ module Pod
end end
end end
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies) @activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
specs_by_target.tap do |specs_by_target| specs_by_target
specs_by_target.values.flatten.each do |spec|
sandbox.store_head_pod(spec.name) if spec.version.head?
end
end
rescue Molinillo::ResolverError => e rescue Molinillo::ResolverError => e
handle_resolver_error(e) handle_resolver_error(e)
end end
...@@ -185,7 +181,7 @@ module Pod ...@@ -185,7 +181,7 @@ module Pod
end end
requirement_satisfied && !( requirement_satisfied && !(
spec.version.prerelease? && spec.version.prerelease? &&
existing_vertices.flat_map(&:requirements).none? { |r| r.prerelease? || r.external_source || r.head? } existing_vertices.flat_map(&:requirements).none? { |r| r.prerelease? || r.external_source }
) && spec_is_platform_compatible?(activated, requirement, spec) ) && spec_is_platform_compatible?(activated, requirement, spec)
end end
...@@ -304,9 +300,6 @@ module Pod ...@@ -304,9 +300,6 @@ module Pod
else else
set = create_set_from_sources(dependency) set = create_set_from_sources(dependency)
end end
if set && dependency.head?
set = Specification::Set::Head.new(set.specification)
end
cached_sets[name] = set cached_sets[name] = set
unless set unless set
raise Molinillo::NoSuchDependencyError.new(dependency) # rubocop:disable Style/RaiseArgs raise Molinillo::NoSuchDependencyError.new(dependency) # rubocop:disable Style/RaiseArgs
...@@ -390,8 +383,7 @@ module Pod ...@@ -390,8 +383,7 @@ module Pod
elsif (conflict.possibility && conflict.possibility.version.prerelease?) && elsif (conflict.possibility && conflict.possibility.version.prerelease?) &&
(conflict.requirement && !( (conflict.requirement && !(
conflict.requirement.prerelease? || conflict.requirement.prerelease? ||
conflict.requirement.external_source || conflict.requirement.external_source)
conflict.requirement.head?)
) )
# Conflict was caused by not specifying an explicit version for the requirement #[name], # Conflict was caused by not specifying an explicit version for the requirement #[name],
# and there is no available stable version satisfying constraints for the requirement. # and there is no available stable version satisfying constraints for the requirement.
......
...@@ -59,7 +59,6 @@ module Pod ...@@ -59,7 +59,6 @@ module Pod
@root = Pathname.new(root).realpath @root = Pathname.new(root).realpath
@public_headers = HeadersStore.new(self, 'Public') @public_headers = HeadersStore.new(self, 'Public')
@predownloaded_pods = [] @predownloaded_pods = []
@head_pods = []
@checkout_sources = {} @checkout_sources = {}
@development_pods = {} @development_pods = {}
@pods_with_absolute_path = [] @pods_with_absolute_path = []
...@@ -313,37 +312,6 @@ module Pod ...@@ -313,37 +312,6 @@ module Pod
#--------------------------------------# #--------------------------------------#
# Marks a Pod as head.
#
# @param [String] name
# The name of the Pod.
#
# @return [void]
#
def store_head_pod(name)
root_name = Specification.root_name(name)
head_pods << root_name
end
# @return [Array<String>] The names of the pods that have been
# marked as head.
#
attr_reader :head_pods
# Checks if a Pod should attempt to use the head source of the git repo.
#
# @param [String] name
# The name of the Pod.
#
# @return [Bool] Whether the Pod has been marked as head.
#
def head_pod?(name)
root_name = Specification.root_name(name)
head_pods.include?(root_name)
end
#--------------------------------------#
# Stores the local path of a Pod. # Stores the local path of a Pod.
# #
# @param [String] name # @param [String] name
......
...@@ -17,6 +17,7 @@ module Pod ...@@ -17,6 +17,7 @@ module Pod
@target_definition = target_definition @target_definition = target_definition
@sandbox = sandbox @sandbox = sandbox
@pod_targets = [] @pod_targets = []
@search_paths_aggregate_targets = []
@file_accessors = [] @file_accessors = []
@xcconfigs = {} @xcconfigs = {}
end end
...@@ -103,6 +104,11 @@ module Pod ...@@ -103,6 +104,11 @@ module Pod
# #
attr_accessor :pod_targets attr_accessor :pod_targets
# @return [Array<AggregateTarget>] The aggregate targets whose pods this
# target must be able to import, but will not directly link against.
#
attr_accessor :search_paths_aggregate_targets
# @param [String] build_configuration The build configuration for which the # @param [String] build_configuration The build configuration for which the
# the pod targets should be returned. # the pod targets should be returned.
# #
......
...@@ -354,9 +354,7 @@ module Pod ...@@ -354,9 +354,7 @@ module Pod
@original_config = Config.instance.clone @original_config = Config.instance.clone
config.installation_root = validation_dir config.installation_root = validation_dir
config.silent = !config.verbose config.silent = !config.verbose
config.integrate_targets = true
config.skip_repo_update = true config.skip_repo_update = true
config.deterministic_uuids = false
end end
def tear_down_validation_environment def tear_down_validation_environment
...@@ -664,7 +662,9 @@ module Pod ...@@ -664,7 +662,9 @@ module Pod
local = local? local = local?
urls = source_urls urls = source_urls
Pod::Podfile.new do Pod::Podfile.new do
install! 'cocoapods', :deterministic_uuids => false
urls.each { |u| source(u) } urls.each { |u| source(u) }
target 'App' do
use_frameworks!(use_frameworks) use_frameworks!(use_frameworks)
platform(platform_name, deployment_target) platform(platform_name, deployment_target)
if local if local
...@@ -674,6 +674,7 @@ module Pod ...@@ -674,6 +674,7 @@ module Pod
end end
end end
end end
end
# Parse the xcode build output to identify the lines which are relevant # Parse the xcode build output to identify the lines which are relevant
# to the linter. # to the linter.
......
Subproject commit b464161555947e7992606e0b186c1e8078d36f7f Subproject commit 75f5c4b33eb3b371a4d383b007a3bfd2933563e3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
//
// SampleProjectTests.m
// SampleProjectTests
//
// Created by Samuel Giddins on 9/7/15.
// Copyright © 2015 LJR Software Limited. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface SampleProjectTests : XCTestCase
@end
@implementation SampleProjectTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end
...@@ -53,25 +53,5 @@ module Pod ...@@ -53,25 +53,5 @@ module Pod
`git log --pretty=oneline`.strip.split("\n").size.should > 1 `git log --pretty=oneline`.strip.split("\n").size.should > 1
end end
end end
before do
FileUtils.rm_rf(test_repo_path)
set_up_old_test_repo
config.repos_dir = SpecHelper.temporary_directory + 'cocoapods/repos'
Command::Setup.any_instance.stubs(:old_master_repo_dir).returns(SpecHelper.temporary_directory + 'cocoapods/master')
end
it 'migrates repos from the old directory structure to the new one' do
source = SpecHelper.temporary_directory + 'cocoapods/master'
target = config.repos_dir + 'master'
source.should.exist?
target.should.not.exist?
run_command('setup')
source.should.not.exist?
target.should.exist?
end
end end
end end
...@@ -44,9 +44,12 @@ $:.unshift((ROOT + 'spec').to_s) ...@@ -44,9 +44,12 @@ $:.unshift((ROOT + 'spec').to_s)
require 'rubygems' require 'rubygems'
require 'bundler/setup' require 'bundler/setup'
require 'pretty_bacon' require 'pretty_bacon'
require 'colored' require 'colored'
require 'clintegracon' require 'clintegracon'
require 'cocoapods-core/yaml_helper'
require 'fileutils' require 'fileutils'
require 'integration/file_tree' require 'integration/file_tree'
require 'integration/xcodeproj_project_yaml' require 'integration/xcodeproj_project_yaml'
...@@ -78,11 +81,19 @@ CLIntegracon.configure do |c| ...@@ -78,11 +81,19 @@ CLIntegracon.configure do |c|
end end
# Register special handling for YAML files # Register special handling for YAML files
c.transform_produced '**/{Podfile,Manifest}.lock' do |path| c.transform_produced %r{(^|/)(Podfile|Manifest).lock$} do |path|
# Remove CocoaPods version # Remove CocoaPods version & Podfile checksum
yaml = YAML.load(path.read) yaml = YAML.load(path.read)
yaml.delete('COCOAPODS') yaml.delete('COCOAPODS')
path.open('w') { |f| f << YAML.dump(yaml) } yaml.delete('PODFILE CHECKSUM')
keys_hint = [
'PODS',
'DEPENDENCIES',
'EXTERNAL SOURCES',
'CHECKOUT OPTIONS',
'SPEC CHECKSUMS',
]
path.open('w') { |f| f << Pod::YAMLHelper.convert_hash(yaml, keys_hint, "\n\n") }
end end
# So we don't need to compare them directly # So we don't need to compare them directly
...@@ -151,6 +162,22 @@ describe_cli 'pod' do ...@@ -151,6 +162,22 @@ describe_cli 'pod' do
# Test installation with no integration # Test installation with no integration
# Test subspecs inheritance # Test subspecs inheritance
#--------------------------------------#
describe 'Pod init' do
describe 'Initializes a Podfile with a single platform' do
behaves_like cli_spec 'init_single_platform',
'init'
end
end
#--------------------------------------#
describe 'Integrates a project with an empty Podfile with CocoaPods' do
behaves_like cli_spec 'install_no_dependencies',
'install --no-repo-update'
end
describe 'Integrates a project with CocoaPods' do describe 'Integrates a project with CocoaPods' do
behaves_like cli_spec 'install_new', behaves_like cli_spec 'install_new',
'install --no-repo-update' 'install --no-repo-update'
...@@ -298,13 +325,4 @@ describe_cli 'pod' do ...@@ -298,13 +325,4 @@ describe_cli 'pod' do
end end
#--------------------------------------# #--------------------------------------#
describe 'Pod init' do
describe 'Initializes a Podfile with a single platform' do
behaves_like cli_spec 'init_single_platform',
'init'
end
end
#--------------------------------------#
end end
...@@ -176,22 +176,6 @@ module Pod ...@@ -176,22 +176,6 @@ module Pod
@config.should.not.be.verbose @config.should.not.be.verbose
end end
it 'cleans SCM dirs in dependency checkouts' do
@config.should.clean
end
it 'locks pod source files' do
@config.should.lock_pod_source
end
it 'integrates a user target' do
@config.should.integrate_targets
end
it 'de-duplicates targets' do
@config.should.deduplicate_targets
end
it 'returns the cache root' do it 'returns the cache root' do
@config.cache_root.should == Pathname.new(File.join(ENV['HOME'], 'Library/Caches/CocoaPods')) @config.cache_root.should == Pathname.new(File.join(ENV['HOME'], 'Library/Caches/CocoaPods'))
end end
......
...@@ -15,16 +15,6 @@ module Pod ...@@ -15,16 +15,6 @@ module Pod
path.should.exist? path.should.exist?
end end
it 'supports the deprecated local key' do
params = { :local => fixture('integration/Reachability') }
dependency = Dependency.new('Reachability', params)
podfile_path = fixture('integration/Podfile')
@subject = ExternalSources.from_dependency(dependency, podfile_path)
@subject.fetch(config.sandbox)
path = config.sandbox.specifications_root + 'Reachability.podspec.json'
path.should.exist?
end
it 'returns the description' do it 'returns the description' do
@subject.description.should.match /from `.*integration\/Reachability`/ @subject.description.should.match /from `.*integration\/Reachability`/
end end
......
...@@ -19,12 +19,6 @@ module Pod ...@@ -19,12 +19,6 @@ module Pod
klass.should == @subject::PathSource klass.should == @subject::PathSource
end end
it 'supports a path source specified with the legacy :local key' do
dep = Dependency.new('Reachability', :local => '')
klass = @subject.from_dependency(dep, nil).class
klass.should == @subject::PathSource
end
it 'supports all the strategies implemented by the downloader' do it 'supports all the strategies implemented by the downloader' do
[:git, :svn, :hg, :bzr, :http].each do |strategy| [:git, :svn, :hg, :bzr, :http].each do |strategy|
dep = Dependency.new('Reachability', strategy => '') dep = Dependency.new('Reachability', strategy => '')
......
...@@ -16,13 +16,6 @@ module Pod ...@@ -16,13 +16,6 @@ module Pod
@generator = Generator::InfoPlistFile.new(pod_target) @generator = Generator::InfoPlistFile.new(pod_target)
end end
it 'handles when the version is HEAD' do
version = Version.new('0.2.0')
version.head = true
@root_spec.stubs(:version).returns(version)
@generator.target_version.should == '0.2.0'
end
it 'handles when the version is more than 3 numeric parts' do it 'handles when the version is more than 3 numeric parts' do
version = Version.new('0.2.0.1') version = Version.new('0.2.0.1')
@root_spec.stubs(:version).returns(version) @root_spec.stubs(:version).returns(version)
......
...@@ -19,26 +19,26 @@ module Pod ...@@ -19,26 +19,26 @@ module Pod
it 'raises if no name is given' do it 'raises if no name is given' do
should.raise ArgumentError do should.raise ArgumentError do
@hooks_manager.register(nil) {} @hooks_manager.register('name', nil) {}
end end
end end
it 'raises if no block is given' do it 'raises if no block is given' do
should.raise ArgumentError do should.raise ArgumentError do
@hooks_manager.register(:post_install) @hooks_manager.register('name', :post_install)
end end
end end
it 'warns if no plugin name is given' do it 'raises if no plugin name is given' do
@hooks_manager.register(:post_install) {} should.raise ArgumentError do
UI.warnings.should.match /hooks without.*deprecated/ @hooks_manager.register(nil, :post_install) {}
UI.warnings.should.match /#{__FILE__}/ end
end end
end end
describe 'run' do describe 'run' do
it 'invokes the hooks' do it 'invokes the hooks' do
@hooks_manager.register(:post_install) do |_options| @hooks_manager.register('plugin', :post_install) do |_options|
true.should.be.true true.should.be.true
end end
@hooks_manager.run(:post_install, Object.new) @hooks_manager.run(:post_install, Object.new)
...@@ -51,7 +51,7 @@ module Pod ...@@ -51,7 +51,7 @@ module Pod
end end
it 'handles the case that no listeners have registered for a name' do it 'handles the case that no listeners have registered for a name' do
@hooks_manager.register(:post_install) do |_options| @hooks_manager.register('plugin', :post_install) do |_options|
true.should.be.true true.should.be.true
end end
should.not.raise do should.not.raise do
...@@ -106,7 +106,7 @@ module Pod ...@@ -106,7 +106,7 @@ module Pod
it 'prints a message in verbose mode when any hooks are run' do it 'prints a message in verbose mode when any hooks are run' do
config.verbose = true config.verbose = true
@hooks_manager.register(:post_install) {} @hooks_manager.register('plugin', :post_install) {}
@hooks_manager.run(:post_install, Object.new) @hooks_manager.run(:post_install, Object.new)
UI.output.should.match /- Running post install hooks/ UI.output.should.match /- Running post install hooks/
end end
......
...@@ -83,24 +83,6 @@ module Pod ...@@ -83,24 +83,6 @@ module Pod
@sandbox.stubs(:predownloaded?).returns(true) @sandbox.stubs(:predownloaded?).returns(true)
@analyzer.send(:pod_changed?, 'BananaLib').should == true @analyzer.send(:pod_changed?, 'BananaLib').should == true
end end
it "considers a changed Pod whose head state doesn't match" do
@sandbox.stubs(:head_pod?).returns(true)
@analyzer.send(:pod_changed?, 'BananaLib').should == true
end
it 'considers changed a Pod whose specification is in head mode if in update mode' do
@sandbox.stubs(:head_pod?).returns(true)
@analyzer.stubs(:update_mode?).returns(true)
@analyzer.send(:pod_changed?, 'BananaLib').should == true
end
it "doesn't consider a changed Pod whose specification is in head mode if not in update mode" do
@sandbox.stubs(:head_pod?).returns(true)
@analyzer.stubs(:sandbox_head_version?).returns(true)
@analyzer.stubs(:update_mode?).returns(false)
@analyzer.send(:pod_changed?, 'BananaLib').should == false
end
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
......
...@@ -58,8 +58,7 @@ module Pod ...@@ -58,8 +58,7 @@ module Pod
describe '#compute_targets' do describe '#compute_targets' do
it 'returns the targets specified in the target definition' do it 'returns the targets specified in the target definition' do
target_definition = Podfile::TargetDefinition.new(:default, nil) target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
target_definition.link_with = ['UserTarget']
user_project = Xcodeproj::Project.new('path') user_project = Xcodeproj::Project.new('path')
user_project.new_target(:application, 'FirstTarget', :ios) user_project.new_target(:application, 'FirstTarget', :ios)
user_project.new_target(:application, 'UserTarget', :ios) user_project.new_target(:application, 'UserTarget', :ios)
...@@ -70,54 +69,44 @@ module Pod ...@@ -70,54 +69,44 @@ module Pod
end end
it 'raises if it is unable to find the targets specified by the target definition' do it 'raises if it is unable to find the targets specified by the target definition' do
target_definition = Podfile::TargetDefinition.new(:default, nil) target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
target_definition.link_with = %w(UserTarget AnotherUserTarget)
user_project = Xcodeproj::Project.new('path') user_project = Xcodeproj::Project.new('path')
target_inspector = TargetInspector.new(target_definition, config.installation_root) target_inspector = TargetInspector.new(target_definition, config.installation_root)
e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative
e.message.should.match /Unable to find the targets named `UserTarget` and `AnotherUserTarget`/ e.message.should.match /Unable to find a target named `UserTarget`/
end end
it 'returns the target with the same name of the target definition' do it 'suggests project native target names if the target cannot be found' do
target_definition = Podfile::TargetDefinition.new('UserTarget', nil) target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
user_project = Xcodeproj::Project.new('path') user_project = Xcodeproj::Project.new('path')
user_project.new_target(:application, 'FirstTarget', :ios) user_project.new_target(:application, 'FirstTarget', :ios)
user_project.new_target(:application, 'UserTarget', :ios) user_project.new_target(:application, 'SecondTarget', :ios)
user_project.new_target(:application, 'ThirdTarget', :ios)
target_inspector = TargetInspector.new(target_definition, config.installation_root)
targets = target_inspector.send(:compute_targets, user_project)
targets.map(&:name).should == ['UserTarget']
end
it 'raises if the name of the target definition does not match any file' do
target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
user_project = Xcodeproj::Project.new('path')
target_inspector = TargetInspector.new(target_definition, config.installation_root) target_inspector = TargetInspector.new(target_definition, config.installation_root)
e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative
e.message.should.match /Unable to find a target named/ e.message.should.include 'did find `FirstTarget`, `SecondTarget`, and `ThirdTarget`.'
end end
it 'returns the first target of the project if the target definition is named default' do it 'returns the target with the same name of the target definition' do
target_definition = Podfile::TargetDefinition.new('Pods', nil) target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
target_definition.link_with_first_target = true
user_project = Xcodeproj::Project.new('path') user_project = Xcodeproj::Project.new('path')
user_project.new_target(:application, 'FirstTarget', :ios) user_project.new_target(:application, 'FirstTarget', :ios)
user_project.new_target(:application, 'UserTarget', :ios) user_project.new_target(:application, 'UserTarget', :ios)
target_inspector = TargetInspector.new(target_definition, config.installation_root) target_inspector = TargetInspector.new(target_definition, config.installation_root)
targets = target_inspector.send(:compute_targets, user_project) targets = target_inspector.send(:compute_targets, user_project)
targets.map(&:name).should == ['FirstTarget'] targets.map(&:name).should == ['UserTarget']
end end
it 'raises if the default target definition cannot be linked because there are no user targets' do it 'raises if the name of the target definition does not match any file' do
target_definition = Podfile::TargetDefinition.new(:default, nil) target_definition = Podfile::TargetDefinition.new('UserTarget', nil)
user_project = Xcodeproj::Project.new('path') user_project = Xcodeproj::Project.new('path')
target_inspector = TargetInspector.new(target_definition, config.installation_root) target_inspector = TargetInspector.new(target_definition, config.installation_root)
e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative e = lambda { target_inspector.send(:compute_targets, user_project) }.should.raise Informative
e.message.should.match /Unable to find a target/ e.message.should.match /Unable to find a target named/
end end
end end
......
This diff is collapsed.
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Installer::InstallationOptions do
describe 'registered options' do
{
'clean' => true,
'deduplicate_targets' => true,
'deterministic_uuids' => true,
'integrate_targets' => true,
'lock_pod_sources' => true,
}.each do |option, default|
it "includes `#{option}` defaulting to `#{default}`" do
Installer::InstallationOptions.defaults.fetch(option).should == default
Installer::InstallationOptions.new.send(option).should == default
end
end
end
describe '.from_podfile' do
it 'raises for a non-cocoapods install' do
podfile = Podfile.new { install! 'foo', :key => 'value' }
exception = should.raise(Informative) { Installer::InstallationOptions.from_podfile(podfile) }
exception.message.should.include 'Currently need to specify a `cocoapods` install, you chose `foo`.'
end
it 'parses the name in a case-insensitive manner' do
podfile = Podfile.new { install! 'CoCoApOdS' }
should.not.raise(Informative) { Installer::InstallationOptions.from_podfile(podfile) }
end
it 'uses the installation method options to create the options' do
options = { :integrate_targets => false }
podfile = Podfile.new { install! 'cocoapods', options }
installation_options = Installer::InstallationOptions.from_podfile(podfile)
installation_options.should == Installer::InstallationOptions.new(options)
end
end
describe '#initialize' do
it 'uses all defaults when no options are specified' do
Installer::InstallationOptions.new.to_h(:include_defaults => false).should.be.empty
end
it 'sets the values as specified in the options' do
installation_options = Installer::InstallationOptions.new(:deterministic_uuids => false)
installation_options.deterministic_uuids.should.be.false
end
it 'raises when unknown keys are encountered' do
exception = should.raise(Informative) { Installer::InstallationOptions.new(:a => 'a', :b => 'b', :c => 'c') }
exception.message.should.include 'Unknown installation options: a, b, and c.'
end
end
describe '#to_h' do
it 'includes all options by default' do
installation_options = Installer::InstallationOptions.new(:deterministic_uuids => false)
installation_options.to_h.should == {
'clean' => true,
'deduplicate_targets' => true,
'deterministic_uuids' => false,
'integrate_targets' => true,
'lock_pod_sources' => true,
}
end
it 'removes default values when specified' do
installation_options = Installer::InstallationOptions.new(:deterministic_uuids => false)
installation_options.to_h(:include_defaults => false).should == {
'deterministic_uuids' => false,
}
end
end
end
end
...@@ -23,15 +23,6 @@ module Pod ...@@ -23,15 +23,6 @@ module Pod
pod_folder.should.exist pod_folder.should.exist
end end
it 'downloads the head source even if a specific source is present specified source' do
config.sandbox.store_head_pod('BananaLib')
@spec.source = { :git => SpecHelper.fixture('banana-lib'), :tag => 'v1.0' }
@installer.install!
@installer.specific_source[:commit].should == FIXTURE_HEAD
pod_folder = config.sandbox.pod_dir('BananaLib')
pod_folder.should.exist
end
it 'returns the checkout options of the downloader if any' do it 'returns the checkout options of the downloader if any' do
@spec.source = { :git => SpecHelper.fixture('banana-lib'), :branch => 'topicbranch' } @spec.source = { :git => SpecHelper.fixture('banana-lib'), :branch => 'topicbranch' }
@installer.install! @installer.install!
...@@ -39,27 +30,6 @@ module Pod ...@@ -39,27 +30,6 @@ module Pod
pod_folder = config.sandbox.pod_dir('BananaLib') pod_folder = config.sandbox.pod_dir('BananaLib')
pod_folder.should.exist pod_folder.should.exist
end end
it 'stores the checkout options in the sandbox' do
config.sandbox.store_head_pod('BananaLib')
@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 => FIXTURE_HEAD },
}
end
it 'fails when using :head for http source' do
config.sandbox.store_head_pod('BananaLib')
@spec.source = { :http => 'http://dl.google.com/googleadmobadssdk/googleadmobsearchadssdkios.zip' }
@spec.source_files = 'GoogleAdMobSearchAdsSDK/*.h'
Pod::Downloader::Http.any_instance.stubs(:download_head)
should.raise Informative do
@installer.install!
end.message.should.match /does not support the :head option, as it uses a Http source./
end
end end
#--------------------------------------# #--------------------------------------#
......
...@@ -5,6 +5,7 @@ module Pod ...@@ -5,6 +5,7 @@ module Pod
describe 'podspec/path in combination with other download strategies' do describe 'podspec/path in combination with other download strategies' do
it 'validates that podspec is not used in combination with other download strategies' do it 'validates that podspec is not used in combination with other download strategies' do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
abstract!(false)
pod 'JSONKit', :podspec => 'https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/JSONKit/1.5pre/JSONKit.podspec.json', pod 'JSONKit', :podspec => 'https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git' :git => 'git@github.com:johnezang/JSONKit.git'
end end
...@@ -19,6 +20,7 @@ module Pod ...@@ -19,6 +20,7 @@ module Pod
it 'validates that path is not used in combination with other download strategies' do it 'validates that path is not used in combination with other download strategies' do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
abstract!(false)
pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json', pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git' :git => 'git@github.com:johnezang/JSONKit.git'
end end
...@@ -33,6 +35,7 @@ module Pod ...@@ -33,6 +35,7 @@ module Pod
it 'validates when calling `valid?` before calling `validate`' do it 'validates when calling `valid?` before calling `validate`' do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
abstract!(false)
pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json', pod 'JSONKit', :path => './JSONKit/1.5pre/JSONKit.podspec.json',
:git => 'git@github.com:johnezang/JSONKit.git' :git => 'git@github.com:johnezang/JSONKit.git'
end end
...@@ -47,6 +50,7 @@ module Pod ...@@ -47,6 +50,7 @@ module Pod
describe 'multiple download strategies' do describe 'multiple download strategies' do
it 'validates that only one download strategy is specified' do it 'validates that only one download strategy is specified' do
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
abstract!(false)
pod 'JSONKit', :svn => 'svn.example.com/JSONKit', pod 'JSONKit', :svn => 'svn.example.com/JSONKit',
:git => 'git@github.com:johnezang/JSONKit.git' :git => 'git@github.com:johnezang/JSONKit.git'
end end
...@@ -58,5 +62,125 @@ module Pod ...@@ -58,5 +62,125 @@ module Pod
validator.errors[0].should.match /The dependency `JSONKit` specifies more than one/ validator.errors[0].should.match /The dependency `JSONKit` specifies more than one/
end end
end end
describe 'empty podfiles' do
it 'warns if the podfile does not contain any dependency' do
podfile = Pod::Podfile.new
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.be.valid
validator.errors.should.be.empty
validator.warnings.should == ['The Podfile does not contain any dependencies.']
end
end
describe 'abstract-only dependencies' do
it 'errors when there is only a root target' do
podfile = Pod::Podfile.new do
pod 'Alamofire'
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.not.be.valid
validator.errors.should == ['The dependency `Alamofire` is not used in any concrete target.']
end
it 'errors when there are only abstract targets' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.not.be.valid
validator.errors.should == ['The dependency `Alamofire` is not used in any concrete target.']
end
it 'does not error when an abstract target has concrete children with complete inheritance' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
target 'Concrete'
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.be.valid
validator.errors.should.be.empty
end
it 'errors when an abstract target has concrete children with no inheritance' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
target 'Concrete' do
inherit! :none
end
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.not.be.valid
validator.errors.should == ['The dependency `Alamofire` is not used in any concrete target.']
end
it 'errors when an abstract target has concrete children with only search_paths inheritance' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
target 'Concrete' do
inherit! :search_paths
end
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.not.be.valid
validator.errors.should == ['The dependency `Alamofire` is not used in any concrete target.']
end
it 'does not error when an abstract target has multiple children with varied inheritance' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
target 'Concrete' do
inherit! :none
end
target 'Other Concrete' do
end
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.be.valid
validator.errors.should.be.empty
end
it 'does not error when an abstract target has multiple children with varied inheritance' do
podfile = Pod::Podfile.new do
abstract_target 'Abstract' do
pod 'Alamofire'
target 'Concrete' do
inherit! :search_paths
end
target 'Other Concrete' do
end
end
end
validator = Installer::PodfileValidator.new(podfile)
validator.validate
validator.should.be.valid
validator.errors.should.be.empty
end
end
end end
end end
...@@ -8,7 +8,6 @@ module Pod ...@@ -8,7 +8,6 @@ module Pod
Project.new(config.sandbox.project_path).save Project.new(config.sandbox.project_path).save
@target = @project.targets.first @target = @project.targets.first
target_definition = Podfile::TargetDefinition.new('Pods', nil) target_definition = Podfile::TargetDefinition.new('Pods', nil)
target_definition.link_with_first_target = true
@pod_bundle = AggregateTarget.new(target_definition, config.sandbox) @pod_bundle = AggregateTarget.new(target_definition, config.sandbox)
@pod_bundle.user_project = @project @pod_bundle.user_project = @project
@pod_bundle.client_root = project_path.dirname @pod_bundle.client_root = project_path.dirname
...@@ -108,6 +107,18 @@ module Pod ...@@ -108,6 +107,18 @@ module Pod
it 'handles when xcconfig is set to another sandbox xcconfig' do it 'handles when xcconfig is set to another sandbox xcconfig' do
group = @project.new_group('Pods') group = @project.new_group('Pods')
old_config = group.new_file('../Pods/Target Support Files/Pods-Foo/SampleConfig.xcconfig')
@target.build_configurations.each do |config|
config.base_configuration_reference = old_config
end
XCConfigIntegrator.integrate(@pod_bundle, [@target])
@target.build_configurations.each do |config|
config.base_configuration_reference.should.not == old_config
config.base_configuration_reference.path.should == @pod_bundle.xcconfig_relative_path(config.name)
end
@pod_bundle.stubs(:label).returns('Pods-Foo')
old_config = group.new_file('../Pods/Target Support Files/Pods/SampleConfig.xcconfig') old_config = group.new_file('../Pods/Target Support Files/Pods/SampleConfig.xcconfig')
@target.build_configurations.each do |config| @target.build_configurations.each do |config|
config.base_configuration_reference = old_config config.base_configuration_reference = old_config
......
...@@ -13,7 +13,6 @@ module Pod ...@@ -13,7 +13,6 @@ module Pod
Project.new(config.sandbox.project_path).save Project.new(config.sandbox.project_path).save
@target = @project.targets.first @target = @project.targets.first
target_definition = Podfile::TargetDefinition.new('Pods', nil) target_definition = Podfile::TargetDefinition.new('Pods', nil)
target_definition.link_with_first_target = true
@pod_bundle = AggregateTarget.new(target_definition, config.sandbox) @pod_bundle = AggregateTarget.new(target_definition, config.sandbox)
@pod_bundle.user_project = @project @pod_bundle.user_project = @project
@pod_bundle.client_root = project_path.dirname @pod_bundle.client_root = project_path.dirname
......
...@@ -9,18 +9,23 @@ module Pod ...@@ -9,18 +9,23 @@ module Pod
@podfile = Podfile.new do @podfile = Podfile.new do
platform :ios platform :ios
xcodeproj sample_project_path xcodeproj sample_project_path
target 'SampleProject' do
pod 'JSONKit' pod 'JSONKit'
target :empty do target :empty do
end end
end end
end
config.sandbox.project = Project.new(config.sandbox.project_path) config.sandbox.project = Project.new(config.sandbox.project_path)
config.sandbox.project.save config.sandbox.project.save
@target = AggregateTarget.new(@podfile.target_definitions['Pods'], config.sandbox) @target = AggregateTarget.new(@podfile.target_definitions['SampleProject'], config.sandbox)
@target.client_root = sample_project_path.dirname @target.client_root = sample_project_path.dirname
@target.user_project = Xcodeproj::Project.open(@sample_project_path) @target.user_project = Xcodeproj::Project.open(@sample_project_path)
@target.user_target_uuids = ['A346496C14F9BE9A0080D870'] @target.user_target_uuids = ['A346496C14F9BE9A0080D870']
empty_library = AggregateTarget.new(@podfile.target_definitions[:empty], config.sandbox) @empty_library = AggregateTarget.new(@podfile.target_definitions[:empty], config.sandbox)
@integrator = UserProjectIntegrator.new(@podfile, config.sandbox, temporary_directory, [@target, empty_library]) @empty_library.client_root = sample_project_path.dirname
@empty_library.user_project = @target.user_project
@empty_library.user_target_uuids = ['C0C495321B9E5C47004F9854']
@integrator = UserProjectIntegrator.new(@podfile, config.sandbox, temporary_directory, [@target, @empty_library])
end end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
...@@ -42,14 +47,8 @@ module Pod ...@@ -42,14 +47,8 @@ module Pod
end end
it 'integrates the user targets' do it 'integrates the user targets' do
UserProjectIntegrator::TargetIntegrator.any_instance.expects(:integrate!) UserProjectIntegrator::TargetIntegrator.any_instance.expects(:integrate!).twice
@integrator.integrate!
end
it 'warns if the podfile does not contain any dependency' do
Podfile::TargetDefinition.any_instance.stubs(:empty?).returns(true)
@integrator.integrate! @integrator.integrate!
UI.warnings.should.include?('The Podfile does not contain any dependencies')
end end
it 'deintegrates targets that are not associated with the podfile' do it 'deintegrates targets that are not associated with the podfile' do
...@@ -57,7 +56,7 @@ module Pod ...@@ -57,7 +56,7 @@ module Pod
Deintegrator.any_instance.expects(:deintegrate_target).with additional_project.new_target(:application, 'Other App', :ios) Deintegrator.any_instance.expects(:deintegrate_target).with additional_project.new_target(:application, 'Other App', :ios)
user_project = @target.user_project user_project = @target.user_project
user_project.native_targets.each do |target| user_project.native_targets.each do |target|
next if target.name == 'SampleProject' next if %w(SampleProject SampleProjectTests).include?(target.name)
Deintegrator.any_instance.expects(:deintegrate_target).with(target) Deintegrator.any_instance.expects(:deintegrate_target).with(target)
end end
@integrator.stubs(:user_projects).returns([additional_project, user_project]) @integrator.stubs(:user_projects).returns([additional_project, user_project])
...@@ -201,9 +200,15 @@ module Pod ...@@ -201,9 +200,15 @@ module Pod
@integrator.send(:user_project_paths).should == [@sample_project_path] @integrator.send(:user_project_paths).should == [@sample_project_path]
end end
it 'skips libraries with empty target definitions' do it 'does not skip libraries with empty target definitions' do
@integrator.targets.map(&:name).should == ['Pods', 'Pods-empty'] @integrator.targets.map(&:name).should == ['Pods-SampleProject', 'Pods-SampleProject-empty']
@integrator.send(:targets_to_integrate).map(&:name).should == ['Pods'] @integrator.send(:targets_to_integrate).map(&:name).should == ['Pods-SampleProject', 'Pods-SampleProject-empty']
end
it 'does skip libraries with only abstract target definitions' do
@integrator.targets.map(&:name).should == ['Pods-SampleProject', 'Pods-SampleProject-empty']
@podfile.target_definition_list.each { |td| td.abstract = true }
@integrator.send(:targets_to_integrate).map(&:name).should == []
end end
it 'skips saving projects that are not dirtied (but touches them instead)' do it 'skips saving projects that are not dirtied (but touches them instead)' do
......
...@@ -19,7 +19,12 @@ def generate_podfile(pods = ['JSONKit']) ...@@ -19,7 +19,12 @@ def generate_podfile(pods = ['JSONKit'])
Pod::Podfile.new do Pod::Podfile.new do
platform :ios platform :ios
xcodeproj SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release xcodeproj SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release
target 'SampleProject' do
pods.each { |name| pod name } pods.each { |name| pod name }
target 'SampleProjectTests' do
inherit! :search_paths
end
end
end end
end end
...@@ -29,7 +34,12 @@ def generate_local_podfile ...@@ -29,7 +34,12 @@ def generate_local_podfile
Pod::Podfile.new do Pod::Podfile.new do
platform :ios platform :ios
xcodeproj SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release xcodeproj SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release
target 'SampleProject' do
pod 'Reachability', :path => SpecHelper.fixture('integration/Reachability') pod 'Reachability', :path => SpecHelper.fixture('integration/Reachability')
target 'SampleProjectTests' do
inherit! :search_paths
end
end
end end
end end
...@@ -41,8 +51,8 @@ module Pod ...@@ -41,8 +51,8 @@ module Pod
CocoaPodsStats::Sender.any_instance.stubs(:send) CocoaPodsStats::Sender.any_instance.stubs(:send)
podfile = generate_podfile podfile = generate_podfile
lockfile = generate_lockfile lockfile = generate_lockfile
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile) @installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
...@@ -140,13 +150,13 @@ module Pod ...@@ -140,13 +150,13 @@ module Pod
end end
it 'integrates the user targets if the corresponding config is set' do it 'integrates the user targets if the corresponding config is set' do
config.integrate_targets = true @installer.installation_options.integrate_targets = true
@installer.expects(:integrate_user_project) @installer.expects(:integrate_user_project)
@installer.install! @installer.install!
end end
it "doesn't integrates the user targets if the corresponding config is not set" do it "doesn't integrates the user targets if the corresponding config is not set" do
config.integrate_targets = false @installer.installation_options.integrate_targets = false
@installer.expects(:integrate_user_project).never @installer.expects(:integrate_user_project).never
@installer.install! @installer.install!
end end
...@@ -226,14 +236,16 @@ module Pod ...@@ -226,14 +236,16 @@ module Pod
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'TestRunner', :exclusive => true do target 'SampleProject'
target 'TestRunner' do
inherit! :search_paths
pod 'monkey', :path => (fixture_path + 'monkey').to_s pod 'monkey', :path => (fixture_path + 'monkey').to_s
end end
end end
lockfile = generate_lockfile lockfile = generate_lockfile
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile) @installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
@installer.install! @installer.install!
target = @installer.aggregate_targets.first target = @installer.aggregate_targets.first
...@@ -262,11 +274,12 @@ module Pod ...@@ -262,11 +274,12 @@ module Pod
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end end
lockfile = generate_lockfile lockfile = generate_lockfile
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile) @installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.raise(Informative) { @installer.install! }.message.should.match /conflict.*monkey/ should.raise(Informative) { @installer.install! }.message.should.match /conflict.*monkey/
end end
...@@ -281,11 +294,12 @@ module Pod ...@@ -281,11 +294,12 @@ module Pod
use_frameworks! use_frameworks!
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end end
lockfile = generate_lockfile lockfile = generate_lockfile
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile) @installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.not.raise(Informative) { @installer.install! } should.not.raise(Informative) { @installer.install! }
end end
end end
...@@ -296,14 +310,15 @@ module Pod ...@@ -296,14 +310,15 @@ module Pod
before do before do
fixture_path = ROOT + 'spec/fixtures' fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos' config.repos_dir = fixture_path + 'spec-repos'
config.integrate_targets = false
@podfile = Pod::Podfile.new do @podfile = Pod::Podfile.new do
install! 'cocoapods', 'integrate_targets' => false
platform :ios, '8.0' platform :ios, '8.0'
xcodeproj 'SampleProject/SampleProject' xcodeproj 'SampleProject/SampleProject'
use_frameworks! use_frameworks!
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end end
@lockfile = generate_lockfile @lockfile = generate_lockfile
...@@ -345,11 +360,12 @@ module Pod ...@@ -345,11 +360,12 @@ module Pod
platform :ios, '8.0' platform :ios, '8.0'
xcodeproj 'SampleProject/SampleProject' xcodeproj 'SampleProject/SampleProject'
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
target 'SampleProject'
end end
lockfile = generate_lockfile lockfile = generate_lockfile
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile, lockfile) @installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.raise(Informative) { @installer.install! }.message.should.match /use_frameworks/ should.raise(Informative) { @installer.install! }.message.should.match /use_frameworks/
end end
end end
...@@ -387,7 +403,7 @@ module Pod ...@@ -387,7 +403,7 @@ module Pod
it 'stores the targets created by the analyzer' do it 'stores the targets created by the analyzer' do
@installer.send(:analyze) @installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods'] @installer.aggregate_targets.map(&:name).sort.should == ['Pods-SampleProject', 'Pods-SampleProjectTests']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit'] @installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end end
...@@ -395,7 +411,7 @@ module Pod ...@@ -395,7 +411,7 @@ module Pod
@installer.update = true @installer.update = true
Installer::Analyzer.any_instance.expects(:update=).with(true) Installer::Analyzer.any_instance.expects(:update=).with(true)
@installer.send(:analyze) @installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods'] @installer.aggregate_targets.map(&:name).sort.should == ['Pods-SampleProject', 'Pods-SampleProjectTests']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit'] @installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end end
end end
...@@ -453,24 +469,6 @@ module Pod ...@@ -453,24 +469,6 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
describe 'Downloading dependencies' do describe 'Downloading dependencies' do
it 'installs head pods' do
podfile = Podfile.new do
platform :osx, '10.10'
pod 'CargoBay', '2.1.0'
pod 'AFNetworking/NSURLSession', :head
end
@installer.stubs(:podfile).returns(podfile)
@installer.stubs(:lockfile).returns(nil)
Downloader::Git.any_instance.expects(:download).once
Downloader::Git.any_instance.expects(:download_head).once
Downloader::Git.any_instance.stubs(:checkout_options).returns({})
@installer.prepare
@installer.resolve_dependencies
@installer.send(:root_specs).sort_by(&:name).map(&:version).map(&:head?).should == [true, nil]
@installer.download_dependencies
UI.output.should.include 'HEAD based on 2.4.1'
end
describe '#install_pod_sources' do describe '#install_pod_sources' do
it 'installs all the Pods which are marked as needing installation' do it 'installs all the Pods which are marked as needing installation' do
spec = fixture_spec('banana-lib/BananaLib.podspec') spec = fixture_spec('banana-lib/BananaLib.podspec')
...@@ -527,7 +525,7 @@ module Pod ...@@ -527,7 +525,7 @@ module Pod
describe '#clean' do describe '#clean' do
it 'it cleans only if the config instructs to do it' do it 'it cleans only if the config instructs to do it' do
config.clean = false @installer.installation_options.clean = false
@installer.send(:clean_pod_sources) @installer.send(:clean_pod_sources)
Installer::PodSourceInstaller.any_instance.expects(:install!).never Installer::PodSourceInstaller.any_instance.expects(:install!).never
end end
...@@ -546,14 +544,14 @@ module Pod ...@@ -546,14 +544,14 @@ module Pod
end end
it "creates build configurations for all of the user's targets" do it "creates build configurations for all of the user's targets" do
config.integrate_targets = true @installer.installation_options.integrate_targets = true
@installer.send(:analyze) @installer.send(:analyze)
@installer.send(:prepare_pods_project) @installer.send(:prepare_pods_project)
@installer.pods_project.build_configurations.map(&:name).sort.should == ['App Store', 'Debug', 'Release', 'Test'] @installer.pods_project.build_configurations.map(&:name).sort.should == ['App Store', 'Debug', 'Release', 'Test']
end end
it 'sets STRIP_INSTALLED_PRODUCT to NO for all configurations for the whole project' do it 'sets STRIP_INSTALLED_PRODUCT to NO for all configurations for the whole project' do
config.integrate_targets = true @installer.installation_options.integrate_targets = true
@installer.send(:analyze) @installer.send(:analyze)
@installer.send(:prepare_pods_project) @installer.send(:prepare_pods_project)
@installer.pods_project.build_settings('Debug')['STRIP_INSTALLED_PRODUCT'].should == 'NO' @installer.pods_project.build_settings('Debug')['STRIP_INSTALLED_PRODUCT'].should == 'NO'
...@@ -630,13 +628,13 @@ module Pod ...@@ -630,13 +628,13 @@ module Pod
@installer.send(:install_libraries) @installer.send(:install_libraries)
end end
it 'skips empty pod targets' do it 'does not skip empty pod targets' do
spec = fixture_spec('banana-lib/BananaLib.podspec') spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil) target_definition = Podfile::TargetDefinition.new(:default, nil)
pod_target = PodTarget.new([spec], [target_definition], config.sandbox) pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@installer.stubs(:aggregate_targets).returns([]) @installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:pod_targets).returns([pod_target]) @installer.stubs(:pod_targets).returns([pod_target])
Installer::PodTargetInstaller.any_instance.expects(:install!).never Installer::PodTargetInstaller.any_instance.expects(:install!).once
@installer.send(:install_libraries) @installer.send(:install_libraries)
end end
...@@ -908,8 +906,8 @@ module Pod ...@@ -908,8 +906,8 @@ module Pod
podfile = Pod::Podfile.new do podfile = Pod::Podfile.new do
platform :ios platform :ios
end end
config.integrate_targets = false
@installer = Installer.new(config.sandbox, podfile) @installer = Installer.new(config.sandbox, podfile)
@installer.installation_options.integrate_targets = false
end end
it 'runs the pre install hooks' do it 'runs the pre install hooks' do
......
...@@ -5,7 +5,6 @@ module Pod ...@@ -5,7 +5,6 @@ module Pod
describe 'In general' do describe 'In general' do
before do before do
@target_definition = Podfile::TargetDefinition.new('Pods', nil) @target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.link_with_first_target = true
@lib = AggregateTarget.new(@target_definition, config.sandbox) @lib = AggregateTarget.new(@target_definition, config.sandbox)
end end
...@@ -29,7 +28,6 @@ module Pod ...@@ -29,7 +28,6 @@ module Pod
describe 'Support files' do describe 'Support files' do
before do before do
@target_definition = Podfile::TargetDefinition.new('Pods', nil) @target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.link_with_first_target = true
@lib = AggregateTarget.new(@target_definition, config.sandbox) @lib = AggregateTarget.new(@target_definition, config.sandbox)
@lib.client_root = config.sandbox.root.dirname @lib.client_root = config.sandbox.root.dirname
end end
......
...@@ -326,50 +326,6 @@ module Pod ...@@ -326,50 +326,6 @@ module Pod
] ]
end end
it 'allows pre-release spec versions when a requirement has a ' \
'HEAD source' do
@podfile = Podfile.new do
platform :ios
pod 'MainSpec', :head
end
spec = Spec.new do |s|
s.name = 'MainSpec'
s.version = '1.2.3-pre'
s.platform = :ios
end
resolver = Resolver.new(config.sandbox, @podfile, empty_graph, SourcesManager.all)
resolver.expects(:find_cached_set).returns(Specification::Set::Head.new(spec))
specs = resolver.resolve.values.flatten.map(&:to_s).sort
specs.should == [
'MainSpec (HEAD based on 1.2.3-pre)',
]
end
it "marks a specification's version to be a HEAD version" do
podfile = Podfile.new do
platform :ios
pod 'FileMD5Hash'
pod 'JSONKit', :head
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, SourcesManager.all)
filemd5hash, jsonkit = resolver.resolve.values.first.sort_by(&:name)
filemd5hash.version.should.not.be.head
jsonkit.version.should.be.head
config.sandbox.head_pod?('FileMD5Hash').should.be.false
config.sandbox.head_pod?('JSONKit').should.be.true
end
it 'raises when unable to find a base spec for a HEAD dependency' do
podfile = Podfile.new do
platform :ios, '7.0'
pod 'ALEKit', :head
end
resolver = Resolver.new(config.sandbox, podfile, empty_graph, SourcesManager.all)
Source::Aggregate.any_instance.stubs(:search).with(Dependency.new('ALEKit', :head)).returns(nil)
e = should.raise(Informative) { resolver.resolve.values.flatten.map(&:to_s) }
e.message.should.match /Unable to find a specification for `ALEKit \(HEAD\)`/
end
it 'raises if it finds two conflicting explicit dependencies' do it 'raises if it finds two conflicting explicit dependencies' do
podfile = Podfile.new do podfile = Podfile.new do
platform :ios platform :ios
......
...@@ -156,20 +156,6 @@ module Pod ...@@ -156,20 +156,6 @@ module Pod
#--------------------------------------# #--------------------------------------#
it 'stores the list of the names of the pre-downloaded pods' do
@sandbox.store_head_pod('BananaLib')
@sandbox.head_pods.should == ['BananaLib']
end
it 'returns whether a Pod has been pre-downloaded' do
@sandbox.head_pods << 'BananaLib'
@sandbox.head_pod?('BananaLib').should.be.true
@sandbox.head_pod?('BananaLib/Subspec').should.be.true
@sandbox.head_pod?('Monkey').should.be.false
end
#--------------------------------------#
it 'returns the checkout sources of the Pods' do it 'returns the checkout sources of the Pods' do
@sandbox.store_pre_downloaded_pod('BananaLib/Subspec') @sandbox.store_pre_downloaded_pod('BananaLib/Subspec')
@sandbox.predownloaded_pods.should == ['BananaLib'] @sandbox.predownloaded_pods.should == ['BananaLib']
......
...@@ -5,7 +5,6 @@ module Pod ...@@ -5,7 +5,6 @@ module Pod
describe 'In general' do describe 'In general' do
before do before do
@target_definition = Podfile::TargetDefinition.new('Pods', nil) @target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.link_with_first_target = true
@target = AggregateTarget.new(@target_definition, config.sandbox) @target = AggregateTarget.new(@target_definition, config.sandbox)
end end
...@@ -42,7 +41,6 @@ module Pod ...@@ -42,7 +41,6 @@ module Pod
describe 'Support files' do describe 'Support files' do
before do before do
@target_definition = Podfile::TargetDefinition.new('Pods', nil) @target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.link_with_first_target = true
@target = AggregateTarget.new(@target_definition, config.sandbox) @target = AggregateTarget.new(@target_definition, config.sandbox)
@target.client_root = config.sandbox.root.dirname @target.client_root = config.sandbox.root.dirname
end end
......
...@@ -321,7 +321,7 @@ module Pod ...@@ -321,7 +321,7 @@ module Pod
validator.stubs(:validate_url) validator.stubs(:validate_url)
validator.stubs(:validate_screenshots) validator.stubs(:validate_screenshots)
podfile = validator.send(:podfile_from_spec, :ios, '5.0') podfile = validator.send(:podfile_from_spec, :ios, '5.0')
dependency = podfile.target_definitions['Pods'].dependencies.first dependency = podfile.target_definitions['App'].dependencies.first
dependency.external_source.key?(:podspec).should.be.true dependency.external_source.key?(:podspec).should.be.true
end end
...@@ -358,7 +358,7 @@ module Pod ...@@ -358,7 +358,7 @@ module Pod
it 'configures the deployment target' do it 'configures the deployment target' do
podfile = @validator.send(:podfile_from_spec, :ios, '5.0') podfile = @validator.send(:podfile_from_spec, :ios, '5.0')
target_definition = podfile.target_definitions['Pods'] target_definition = podfile.target_definitions['App']
platform = target_definition.platform platform = target_definition.platform
platform.symbolic_name.should == :ios platform.symbolic_name.should == :ios
platform.deployment_target.to_s.should == '5.0' platform.deployment_target.to_s.should == '5.0'
...@@ -366,13 +366,13 @@ module Pod ...@@ -366,13 +366,13 @@ module Pod
it 'includes the use_frameworks! directive' do it 'includes the use_frameworks! directive' do
podfile = @validator.send(:podfile_from_spec, :ios, '5.0', true) podfile = @validator.send(:podfile_from_spec, :ios, '5.0', true)
target_definition = podfile.target_definitions['Pods'] target_definition = podfile.target_definitions['App']
target_definition.uses_frameworks?.should == true target_definition.uses_frameworks?.should == true
end end
it 'includes the use_frameworks!(false) directive' do it 'includes the use_frameworks!(false) directive' do
podfile = @validator.send(:podfile_from_spec, :ios, '5.0', false) podfile = @validator.send(:podfile_from_spec, :ios, '5.0', false)
target_definition = podfile.target_definitions['Pods'] target_definition = podfile.target_definitions['App']
# rubocop:disable Style/DoubleNegation # rubocop:disable Style/DoubleNegation
(!!target_definition.uses_frameworks?).should == false (!!target_definition.uses_frameworks?).should == false
# rubocop:enable Style/DoubleNegation # rubocop:enable Style/DoubleNegation
......
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