Commit b372d364 authored by arida's avatar arida

Merge remote-tracking branch 'cocoapods/master'

parents 015b827b d6bf4794
......@@ -4,9 +4,6 @@ inherit_from:
#- CocoaPods ------------------------------------------------------------------
ParameterLists:
CountKeywordArgs: false
AllCops:
Include:
- Dangerfile
......
......@@ -14,6 +14,9 @@ Documentation:
#- CocoaPods -----------------------------------------------------------------#
ParameterLists:
CountKeywordArgs: false
# We adopted raise instead of fail.
SignalException:
EnforcedStyle: only_raise
......
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2016-03-03 16:16:26 -0600 using RuboCop version 0.37.2.
# on 2016-06-09 08:12:30 -0500 using RuboCop version 0.37.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 4
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: AlignWith, SupportedStyles, AutoCorrect.
# SupportedStyles: keyword, variable, start_of_line
......@@ -22,21 +22,38 @@ Lint/IneffectiveAccessModifier:
- 'lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb'
- 'lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect.
Lint/LiteralInInterpolation:
Exclude:
- 'Dangerfile'
# Offense count: 1
Lint/NonLocalExitFromIterator:
Exclude:
- 'spec/unit/installer_spec.rb'
# Offense count: 1
Lint/UnreachableCode:
Exclude:
- 'Dangerfile'
# Offense count: 40
Lint/UselessAccessModifier:
Enabled: false
# Offense count: 1853
# Offense count: 2035
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
# URISchemes: http, https
Metrics/LineLength:
Max: 279
# Offense count: 1
# Configuration parameters: CountKeywordArgs.
ParameterLists:
Max: 6
# Offense count: 5
# Cop supports --auto-correct.
Performance/Casecmp:
......@@ -55,20 +72,12 @@ Performance/RedundantBlockCall:
- 'lib/cocoapods/installer/analyzer/pod_variant_set.rb'
- 'spec/unit/validator_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
Performance/RedundantMatch:
Exclude:
- 'spec/**/*'
- 'lib/cocoapods/command/lib.rb'
- 'lib/cocoapods/external_sources/podspec_source.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: MaxKeyValuePairs.
Performance/RedundantMerge:
Exclude:
- 'lib/cocoapods/installer/target_installer.rb'
- 'lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb'
# Offense count: 1
# Cop supports --auto-correct.
......@@ -76,7 +85,7 @@ Performance/StringReplacement:
Exclude:
- 'spec/functional/command/spec_spec.rb'
# Offense count: 23
# Offense count: 22
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: prefer_alias, prefer_alias_method
......@@ -106,12 +115,11 @@ Style/AlignParameters:
Exclude:
- 'lib/cocoapods/project.rb'
# Offense count: 7
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: SingleLineConditionsOnly.
Style/ConditionalAssignment:
Exclude:
- 'lib/cocoapods/command/init.rb'
- 'lib/cocoapods/command/repo/push.rb'
- 'lib/cocoapods/external_sources/abstract_external_source.rb'
- 'lib/cocoapods/sandbox/file_accessor.rb'
......@@ -137,32 +145,30 @@ Style/IfInsideElse:
Style/IndentArray:
EnforcedStyle: consistent
# Offense count: 27
# Offense count: 24
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: aligned, indented
Style/MultilineMethodCallIndentation:
Enabled: false
# Offense count: 1
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: aligned, indented
Style/MultilineOperationIndentation:
Enabled: false
# Offense count: 16
# Offense count: 12
# Cop supports --auto-correct.
Style/MutableConstant:
Exclude:
- 'bin/sandbox-pod'
- 'lib/cocoapods/command/inter_process_communication.rb'
- 'lib/cocoapods/command/lib.rb'
- 'lib/cocoapods/config.rb'
- 'lib/cocoapods/generator/copy_resources_script.rb'
- 'lib/cocoapods/installer.rb'
- 'lib/cocoapods/installer/target_installer/pod_target_installer.rb'
- 'lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb'
- 'lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb'
- 'lib/cocoapods/project.rb'
- 'spec/unit/installer/user_project_integrator/target_integrator/xcconfig_integrator_spec.rb'
......@@ -173,16 +179,8 @@ Style/NestedParenthesizedCalls:
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowSafeAssignment.
Style/ParenthesesAroundCondition:
Exclude:
- 'lib/cocoapods/command/inter_process_communication.rb'
# Offense count: 2
# Cop supports --auto-correct.
Style/RedundantParentheses:
Exclude:
- 'lib/cocoapods/sources_manager.rb'
- 'spec/unit/sandbox_spec.rb'
# Offense count: 2
......@@ -191,15 +189,14 @@ Style/RedundantSelf:
Exclude:
- 'lib/cocoapods/command.rb'
# Offense count: 16
# Offense count: 13
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
- 'lib/cocoapods/installer/file_references_installer.rb'
- 'lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb'
- 'lib/cocoapods/sandbox/path_list.rb'
- 'lib/cocoapods/sources_manager.rb'
- 'lib/cocoapods/validator.rb'
- 'spec/integration.rb'
- 'spec/unit/external_sources/path_source_spec.rb'
......@@ -228,10 +225,8 @@ Style/UnneededInterpolation:
- 'lib/cocoapods/validator.rb'
- 'spec/spec_helper/temporary_repos.rb'
# Offense count: 4
# Offense count: 2
Style/ZeroLengthPredicate:
Exclude:
- 'lib/cocoapods/command/init.rb'
- 'lib/cocoapods/command/project.rb'
- 'lib/cocoapods/installer/podfile_validator.rb'
- 'lib/cocoapods/sources_manager.rb'
......@@ -9,6 +9,7 @@ rvm:
# OS X 10.9.0-10.9.2
# TODO: currently unavailable: https://github.com/travis-ci/travis-ci/issues/2918
# - 2.0.0-p247
- 2.3.1
branches:
only:
......
......@@ -8,10 +8,19 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements
* Move Pods Project generation to an `Xcode` Namespace.
[Daniel Tomlinson](https://github.com/dantoml)
[#5480](https://github.com/CocoaPods/CocoaPods/pull/5480)
* Add the ability to inhibit swift warnings.
[Peter Ryszkiewicz](https://github.com/pRizz)
[#5414](https://github.com/CocoaPods/CocoaPods/pull/5414)
* Use `git ls-remote` to skip full clones for branch dependencies.
[Juan Civile](https://github.com/champo)
[#5376](https://github.com/CocoaPods/CocoaPods/issues/5376)
##### Bug Fixes
* Fix local pod platform conflict error message.
......@@ -34,6 +43,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Boris Bügling](https://github.com/neonichu)
[#5445](https://github.com/CocoaPods/CocoaPods/issues/5445)
* Resolve cyclic dependencies when creating pod targets.
[Juan Civile](https://github.com/champo)
[#5362](https://github.com/CocoaPods/CocoaPods/issues/5362)
## 1.0.1 (2016-06-02)
......
......@@ -11,13 +11,13 @@ end
# Ensure a clean commits history
if commits.any? { |c| c.message =~ /^Merge branch '#{branch_for_merge}'/ }
fail("Please rebase to get rid of the merge commits in this PR")
fail('Please rebase to get rid of the merge commits in this PR')
end
# Request a CHANGELOG entry, and give an example
has_app_changes = !modified_files.grep(/lib/).empty?
if !modified_files.include?("CHANGELOG.md") && has_app_changes
fail("Please include a CHANGELOG entry to credit yourself! \nYou can find it at [CHANGELOG.md](https://github.com/CocoaPods/CocoaPods/blob/master/CHANGELOG.md).", sticky: false)
if !modified_files.include?('CHANGELOG.md') && has_app_changes
fail('Please include a CHANGELOG entry to credit yourself! \nYou can find it at [CHANGELOG.md](https://github.com/CocoaPods/CocoaPods/blob/master/CHANGELOG.md).', :sticky => false)
markdown <<-MARKDOWN
Here's an example of your CHANGELOG entry:
......
GIT
remote: https://github.com/CocoaPods/CLAide.git
revision: 47857d569b7121c354ad15c426be04bc90c5f7c7
revision: 74a51d486dd7a12ee798d015385714c13146946d
branch: master
specs:
claide (1.0.0)
......@@ -17,14 +17,14 @@ GIT
GIT
remote: https://github.com/CocoaPods/Molinillo.git
revision: 07b0a09b82839ca562076ba3b2094c14cbdfb7a2
revision: d429ddf3daa7894990e2de99a75d2cc007b20598
branch: master
specs:
molinillo (0.4.5)
molinillo (0.5.0)
GIT
remote: https://github.com/CocoaPods/Xcodeproj.git
revision: 55af40b1fee835039947db9635c8b098bd03fe90
revision: 1b15f4c79303843e8f370afa9dd74b8ad0329785
branch: master
specs:
xcodeproj (1.1.0)
......@@ -41,7 +41,7 @@ GIT
GIT
remote: https://github.com/CocoaPods/cocoapods-downloader.git
revision: 272c56dbde497a48a7310098989ed25d0cc0bc6d
revision: 0803d2280c14347e03cc5753efdca04e3697552c
branch: master
specs:
cocoapods-downloader (1.0.0)
......@@ -108,7 +108,7 @@ PATH
colored (~> 1.2)
escape (~> 0.0.4)
fourflusher (~> 0.3.0)
molinillo (~> 0.4.5)
molinillo (~> 0.5.0)
nap (~> 1.0)
xcodeproj (>= 1.1.0, < 2.0)
......
......@@ -37,7 +37,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'cocoapods-stats', '>= 1.0.0', '< 2.0'
s.add_runtime_dependency 'cocoapods-trunk', '>= 1.0.0', '< 2.0'
s.add_runtime_dependency 'cocoapods-try', '>= 1.0.0', '< 2.0'
s.add_runtime_dependency 'molinillo', '~> 0.4.5'
s.add_runtime_dependency 'molinillo', '~> 0.5.0'
s.add_runtime_dependency 'xcodeproj', '>= 1.1.0', '< 2.0'
s.add_runtime_dependency 'activesupport', '>= 4.0.2'
......
......@@ -33,11 +33,16 @@ module Pod
cache_path: Config.instance.cache_root + 'Pods'
)
can_cache &&= !Config.instance.skip_download_cache
request = preprocess_request(request)
if can_cache
raise ArgumentError, 'Must provide a `cache_path` when caching.' unless cache_path
cache = Cache.new(cache_path)
result = cache.download_pod(request)
else
raise ArgumentError, 'Must provide a `target` when caching is disabled.' unless target
require 'cocoapods/installer/pod_source_preparer'
result, = download_request(request, target)
Installer::PodSourcePreparer.new(result.spec, result.location).prepare!
......@@ -110,6 +115,21 @@ module Pod
end
end
# Return a new request after preprocessing by the downloader
#
# @param [Request] request
# the request that needs preprocessing
#
# @return [Request] the preprocessed request
#
def self.preprocess_request(request)
Request.new(
:spec => request.spec,
:released => request.released_pod?,
:name => request.name,
:params => Downloader.preprocess_options(request.params))
end
public
class DownloaderError; include CLAide::InformativeError; end
......
......@@ -124,6 +124,7 @@ module Pod
def cached_pod(request)
cached_spec = cached_spec(request)
path = path_for_pod(request)
return unless cached_spec && path.directory?
spec = request.spec || cached_spec
Response.new(path, spec, request.params)
......
This diff is collapsed.
This diff is collapsed.
module Pod
class Installer
# Controller class responsible of creating and configuring the static
# library target in Pods project. It also creates the support file needed
# by the target.
#
class TargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
#
attr_reader :sandbox
# @return [Target] The library whose target needs to be generated.
#
attr_reader :target
# @param [Project] project @see project
# @param [Target] target @see target
#
def initialize(sandbox, target)
@sandbox = sandbox
@target = target
end
private
#-----------------------------------------------------------------------#
# @!group Installation steps
# Adds the target for the library to the Pods project with the
# appropriate build configurations.
#
# @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
#
# @return [void]
#
def add_target
product_type = target.product_type
name = target.label
platform = target.platform.name
language = target.uses_swift? ? :swift : :objc
@native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
product_name = target.product_name
product = @native_target.product_reference
product.name = product_name
target.user_build_configurations.each do |bc_name, type|
@native_target.add_build_configuration(bc_name, type)
end
@native_target.build_configurations.each do |configuration|
configuration.build_settings.merge!(custom_build_settings)
end
target.native_target = @native_target
end
# @return [String] The deployment target.
#
def deployment_target
target.platform.deployment_target.to_s
end
# Returns the customized build settings which are overridden in the build
# settings of the user target.
#
# @return [Hash{String => String}]
#
def custom_build_settings
settings = {}
unless target.archs.empty?
settings['ARCHS'] = target.archs
end
if target.requires_frameworks?
settings['PRODUCT_NAME'] = target.product_module_name
else
settings.merge!('OTHER_LDFLAGS' => '', 'OTHER_LIBTOOLFLAGS' => '')
end
settings
end
# Creates the directory where to store the support files of the target.
#
def create_support_files_dir
target.support_files_dir.mkdir
end
# Creates the Info.plist file which sets public framework attributes
#
# @return [void]
#
def create_info_plist_file
path = target.info_plist_path
UI.message "- Generating Info.plist file at #{UI.path(path)}" do
generator = Generator::InfoPlistFile.new(target)
generator.save_as(path)
add_file_to_support_group(path)
native_target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['INFOPLIST_FILE'] = relative_path.to_s
end
end
end
# Creates the module map file which ensures that the umbrella header is
# recognized with a customized path
#
# @yield_param [Generator::ModuleMap]
# yielded once to configure the private headers
#
# @return [void]
#
def create_module_map
path = target.module_map_path
UI.message "- Generating module map file at #{UI.path(path)}" do
generator = Generator::ModuleMap.new(target)
yield generator if block_given?
generator.save_as(path)
add_file_to_support_group(path)
native_target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
end
end
end
# Generates a header which ensures that all header files are exported
# in the module map
#
# @yield_param [Generator::UmbrellaHeader]
# yielded once to configure the imports
#
def create_umbrella_header
path = target.umbrella_header_path
UI.message "- Generating umbrella header at #{UI.path(path)}" do
generator = Generator::UmbrellaHeader.new(target)
yield generator if block_given?
generator.save_as(path)
# Add the file to the support group and the native target,
# so it will been added to the header build phase
file_ref = add_file_to_support_group(path)
native_target.add_file_references([file_ref])
# Make the umbrella header public
build_file = native_target.headers_build_phase.build_file(file_ref)
build_file.settings ||= {}
build_file.settings['ATTRIBUTES'] = ['Public']
end
end
# Generates a dummy source file for each target so libraries that contain
# only categories build.
#
# @return [void]
#
def create_dummy_source
path = target.dummy_source_path
generator = Generator::DummySource.new(target.label)
generator.save_as(path)
file_reference = add_file_to_support_group(path)
native_target.source_build_phase.add_file_reference(file_reference)
end
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
# @note Generated by the {#add_target} step.
#
attr_reader :native_target
private
#-----------------------------------------------------------------------#
# @!group Private helpers.
# @return [Project] the Pods project of the sandbox.
#
def project
sandbox.project
end
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
attr_reader :support_files_group
# Adds a reference to the given file in the support group of this target.
#
# @param [Pathname] path
# The path of the file to which the reference should be added.
#
# @return [PBXFileReference] the file reference of the added file.
#
def add_file_to_support_group(path)
support_files_group.new_file(path)
end
#-----------------------------------------------------------------------#
end
end
end
module Pod
class Installer
# Creates the targets which aggregate the Pods libraries in the Pods
# project and the relative support files.
#
class AggregateTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
UI.message "- Installing target `#{target.name}` #{target.platform}" do
add_target
create_support_files_dir
create_support_files_group
create_xcconfig_file
if target.requires_frameworks?
create_info_plist_file
create_module_map
create_umbrella_header
end
create_embed_frameworks_script
create_bridge_support_file
create_copy_resources_script
create_acknowledgements
create_dummy_source
end
end
#-----------------------------------------------------------------------#
private
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
target.target_definition
end
# Ensure that vendored static frameworks and libraries are not linked
# twice to the aggregate target, which shares the xcconfig of the user
# target.
#
def custom_build_settings
settings = {
'MACH_O_TYPE' => 'staticlib',
'OTHER_LDFLAGS' => '',
'OTHER_LIBTOOLFLAGS' => '',
'PODS_ROOT' => '$(SRCROOT)',
'PRODUCT_BUNDLE_IDENTIFIER' => 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}',
'SKIP_INSTALL' => 'YES',
}
super.merge(settings)
end
# Creates the group that holds the references to the support files
# generated by this installer.
#
# @return [void]
#
def create_support_files_group
parent = project.support_files_group
name = target.name
dir = target.support_files_dir
@support_files_group = parent.new_group(name, dir)
end
# Generates the contents of the xcconfig file and saves it to disk.
#
# @return [void]
#
def create_xcconfig_file
native_target.build_configurations.each do |configuration|
path = target.xcconfig_path(configuration.name)
gen = Generator::XCConfig::AggregateXCConfig.new(target, configuration.name)
gen.save_as(path)
target.xcconfigs[configuration.name] = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path)
configuration.base_configuration_reference = xcconfig_file_ref
end
end
# Generates the bridge support metadata if requested by the {Podfile}.
#
# @note The bridge support metadata is added to the resources of the
# target because it is needed for environments interpreted at
# runtime.
#
# @return [void]
#
def create_bridge_support_file
if target.podfile.generate_bridge_support?
path = target.bridge_support_path
headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
generator = Generator::BridgeSupport.new(headers)
generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
# Uniqued Resources grouped by config
#
# @return [Hash{ Symbol => Array<Pathname> }]
#
def resources_by_config
library_targets = target.pod_targets.reject do |pod_target|
pod_target.should_build? && pod_target.requires_frameworks?
end
target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
resources_by_config[config] = library_targets.flat_map do |library_target|
next [] unless library_target.include_in_build_config?(target_definition, config)
resource_paths = library_target.file_accessors.flat_map do |accessor|
accessor.resources.flat_map { |res| res.relative_path_from(project.path.dirname) }
end
resource_bundles = library_target.file_accessors.flat_map do |accessor|
accessor.resource_bundles.keys.map { |name| "#{library_target.configuration_build_dir}/#{name.shellescape}.bundle" }
end
(resource_paths + resource_bundles + [bridge_support_file].compact).uniq
end
end
end
# Creates a script that copies the resources to the bundle of the client
# target.
#
# @note The bridge support file needs to be created before the prefix
# header, otherwise it will not be added to the resources script.
#
# @return [void]
#
def create_copy_resources_script
path = target.copy_resources_script_path
generator = Generator::CopyResourcesScript.new(resources_by_config, target.platform)
generator.save_as(path)
add_file_to_support_group(path)
end
# Creates a script that embeds the frameworks to the bundle of the client
# target.
#
# @note We can't use Xcode default copy bundle resource phase, because
# we need to ensure that we only copy the resources, which are
# relevant for the current build configuration.
#
# @return [void]
#
def create_embed_frameworks_script
path = target.embed_frameworks_script_path
frameworks_by_config = {}
target.user_build_configurations.keys.each do |config|
relevant_pod_targets = target.pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config)
end
frameworks_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map { |fw| "${PODS_ROOT}/#{fw.relative_path_from(sandbox.root)}" }
frameworks << pod_target.build_product_path('$BUILT_PRODUCTS_DIR') if pod_target.should_build? && pod_target.requires_frameworks?
frameworks
end
end
generator = Generator::EmbedFrameworksScript.new(frameworks_by_config)
generator.save_as(path)
add_file_to_support_group(path)
end
# Generates the acknowledgement files (markdown and plist) for the target.
#
# @return [void]
#
def create_acknowledgements
basepath = target.acknowledgements_basepath
Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath)
file_accessors = target.pod_targets.map(&:file_accessors).flatten
generator = generator_class.new(file_accessors)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------#
end
end
end
module Pod
class Installer
class Xcode
autoload :PodsProjectGenerator, 'cocoapods/installer/xcode/pods_project_generator'
end
end
end
This diff is collapsed.
module Pod
class Installer
class Xcode
class PodsProjectGenerator
# Creates the targets which aggregate the Pods libraries in the Pods
# project and the relative support files.
#
class AggregateTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
UI.message "- Installing target `#{target.name}` #{target.platform}" do
add_target
create_support_files_dir
create_support_files_group
create_xcconfig_file
if target.requires_frameworks?
create_info_plist_file
create_module_map
create_umbrella_header
end
create_embed_frameworks_script
create_bridge_support_file
create_copy_resources_script
create_acknowledgements
create_dummy_source
end
end
#-----------------------------------------------------------------------#
private
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
target.target_definition
end
# Ensure that vendored static frameworks and libraries are not linked
# twice to the aggregate target, which shares the xcconfig of the user
# target.
#
def custom_build_settings
settings = {
'MACH_O_TYPE' => 'staticlib',
'OTHER_LDFLAGS' => '',
'OTHER_LIBTOOLFLAGS' => '',
'PODS_ROOT' => '$(SRCROOT)',
'PRODUCT_BUNDLE_IDENTIFIER' => 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}',
'SKIP_INSTALL' => 'YES',
}
super.merge(settings)
end
# Creates the group that holds the references to the support files
# generated by this installer.
#
# @return [void]
#
def create_support_files_group
parent = project.support_files_group
name = target.name
dir = target.support_files_dir
@support_files_group = parent.new_group(name, dir)
end
# Generates the contents of the xcconfig file and saves it to disk.
#
# @return [void]
#
def create_xcconfig_file
native_target.build_configurations.each do |configuration|
path = target.xcconfig_path(configuration.name)
gen = Generator::XCConfig::AggregateXCConfig.new(target, configuration.name)
gen.save_as(path)
target.xcconfigs[configuration.name] = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path)
configuration.base_configuration_reference = xcconfig_file_ref
end
end
# Generates the bridge support metadata if requested by the {Podfile}.
#
# @note The bridge support metadata is added to the resources of the
# target because it is needed for environments interpreted at
# runtime.
#
# @return [void]
#
def create_bridge_support_file
if target.podfile.generate_bridge_support?
path = target.bridge_support_path
headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
generator = Generator::BridgeSupport.new(headers)
generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
# Uniqued Resources grouped by config
#
# @return [Hash{ Symbol => Array<Pathname> }]
#
def resources_by_config
library_targets = target.pod_targets.reject do |pod_target|
pod_target.should_build? && pod_target.requires_frameworks?
end
target.user_build_configurations.keys.each_with_object({}) do |config, resources_by_config|
resources_by_config[config] = library_targets.flat_map do |library_target|
next [] unless library_target.include_in_build_config?(target_definition, config)
resource_paths = library_target.file_accessors.flat_map do |accessor|
accessor.resources.flat_map { |res| res.relative_path_from(project.path.dirname) }
end
resource_bundles = library_target.file_accessors.flat_map do |accessor|
accessor.resource_bundles.keys.map { |name| "#{library_target.configuration_build_dir}/#{name.shellescape}.bundle" }
end
(resource_paths + resource_bundles + [bridge_support_file].compact).uniq
end
end
end
# Creates a script that copies the resources to the bundle of the client
# target.
#
# @note The bridge support file needs to be created before the prefix
# header, otherwise it will not be added to the resources script.
#
# @return [void]
#
def create_copy_resources_script
path = target.copy_resources_script_path
generator = Generator::CopyResourcesScript.new(resources_by_config, target.platform)
generator.save_as(path)
add_file_to_support_group(path)
end
# Creates a script that embeds the frameworks to the bundle of the client
# target.
#
# @note We can't use Xcode default copy bundle resource phase, because
# we need to ensure that we only copy the resources, which are
# relevant for the current build configuration.
#
# @return [void]
#
def create_embed_frameworks_script
path = target.embed_frameworks_script_path
frameworks_by_config = {}
target.user_build_configurations.keys.each do |config|
relevant_pod_targets = target.pod_targets.select do |pod_target|
pod_target.include_in_build_config?(target_definition, config)
end
frameworks_by_config[config] = relevant_pod_targets.flat_map do |pod_target|
frameworks = pod_target.file_accessors.flat_map(&:vendored_dynamic_artifacts).map { |fw| "${PODS_ROOT}/#{fw.relative_path_from(sandbox.root)}" }
frameworks << pod_target.build_product_path('$BUILT_PRODUCTS_DIR') if pod_target.should_build? && pod_target.requires_frameworks?
frameworks
end
end
generator = Generator::EmbedFrameworksScript.new(frameworks_by_config)
generator.save_as(path)
add_file_to_support_group(path)
end
# Generates the acknowledgement files (markdown and plist) for the target.
#
# @return [void]
#
def create_acknowledgements
basepath = target.acknowledgements_basepath
Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath)
file_accessors = target.pod_targets.map(&:file_accessors).flatten
generator = generator_class.new(file_accessors)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------#
end
end
end
end
end
module Pod
class Installer
class Xcode
class PodsProjectGenerator
# Controller class responsible of creating and configuring the static
# library target in Pods project. It also creates the support file needed
# by the target.
#
class TargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
#
attr_reader :sandbox
# @return [Target] The library whose target needs to be generated.
#
attr_reader :target
# @param [Project] project @see project
# @param [Target] target @see target
#
def initialize(sandbox, target)
@sandbox = sandbox
@target = target
end
private
#-----------------------------------------------------------------------#
# @!group Installation steps
# Adds the target for the library to the Pods project with the
# appropriate build configurations.
#
# @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
#
# @return [void]
#
def add_target
product_type = target.product_type
name = target.label
platform = target.platform.name
language = target.uses_swift? ? :swift : :objc
@native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
product_name = target.product_name
product = @native_target.product_reference
product.name = product_name
target.user_build_configurations.each do |bc_name, type|
@native_target.add_build_configuration(bc_name, type)
end
@native_target.build_configurations.each do |configuration|
configuration.build_settings.merge!(custom_build_settings)
end
target.native_target = @native_target
end
# @return [String] The deployment target.
#
def deployment_target
target.platform.deployment_target.to_s
end
# Returns the customized build settings which are overridden in the build
# settings of the user target.
#
# @return [Hash{String => String}]
#
def custom_build_settings
settings = {}
unless target.archs.empty?
settings['ARCHS'] = target.archs
end
if target.requires_frameworks?
settings['PRODUCT_NAME'] = target.product_module_name
else
settings.merge!('OTHER_LDFLAGS' => '', 'OTHER_LIBTOOLFLAGS' => '')
end
settings
end
# Creates the directory where to store the support files of the target.
#
def create_support_files_dir
target.support_files_dir.mkdir
end
# Creates the Info.plist file which sets public framework attributes
#
# @return [void]
#
def create_info_plist_file
path = target.info_plist_path
UI.message "- Generating Info.plist file at #{UI.path(path)}" do
generator = Generator::InfoPlistFile.new(target)
generator.save_as(path)
add_file_to_support_group(path)
native_target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['INFOPLIST_FILE'] = relative_path.to_s
end
end
end
# Creates the module map file which ensures that the umbrella header is
# recognized with a customized path
#
# @yield_param [Generator::ModuleMap]
# yielded once to configure the private headers
#
# @return [void]
#
def create_module_map
path = target.module_map_path
UI.message "- Generating module map file at #{UI.path(path)}" do
generator = Generator::ModuleMap.new(target)
yield generator if block_given?
generator.save_as(path)
add_file_to_support_group(path)
native_target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
end
end
end
# Generates a header which ensures that all header files are exported
# in the module map
#
# @yield_param [Generator::UmbrellaHeader]
# yielded once to configure the imports
#
def create_umbrella_header
path = target.umbrella_header_path
UI.message "- Generating umbrella header at #{UI.path(path)}" do
generator = Generator::UmbrellaHeader.new(target)
yield generator if block_given?
generator.save_as(path)
# Add the file to the support group and the native target,
# so it will been added to the header build phase
file_ref = add_file_to_support_group(path)
native_target.add_file_references([file_ref])
# Make the umbrella header public
build_file = native_target.headers_build_phase.build_file(file_ref)
build_file.settings ||= {}
build_file.settings['ATTRIBUTES'] = ['Public']
end
end
# Generates a dummy source file for each target so libraries that contain
# only categories build.
#
# @return [void]
#
def create_dummy_source
path = target.dummy_source_path
generator = Generator::DummySource.new(target.label)
generator.save_as(path)
file_reference = add_file_to_support_group(path)
native_target.source_build_phase.add_file_reference(file_reference)
end
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
# @note Generated by the {#add_target} step.
#
attr_reader :native_target
private
#-----------------------------------------------------------------------#
# @!group Private helpers.
# @return [Project] the Pods project of the sandbox.
#
def project
sandbox.project
end
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
attr_reader :support_files_group
# Adds a reference to the given file in the support group of this target.
#
# @param [Pathname] path
# The path of the file to which the reference should be added.
#
# @return [PBXFileReference] the file reference of the added file.
#
def add_file_to_support_group(path)
support_files_group.new_file(path)
end
#-----------------------------------------------------------------------#
end
end
end
end
end
......@@ -189,8 +189,14 @@ module Pod
# dependency upon.
#
def recursive_dependent_targets
targets = dependent_targets + dependent_targets.flat_map(&:recursive_dependent_targets)
targets.uniq!
targets = dependent_targets.clone
targets.each do |target|
target.dependent_targets.each do |t|
targets.push(t) unless t == self || targets.include?(t)
end
end
targets
end
......
Subproject commit 4c7f2413a2cf1a8175c544555d000bfb6511e943
Subproject commit 409958a75378ff70582af2fbabb1441c551ed1c7
......@@ -91,6 +91,18 @@ CLIntegracon.configure do |c|
path.open('w') { |f| f << Pod::YAMLHelper.convert_hash(yaml, keys_hint, "\n\n") }
end
c.preprocess('**/*.xcodeproj', %r{(^|/)(Podfile|Manifest).lock$}) do |path|
keys_hint = if path.extname == '.lock'
Pod::Lockfile::HASH_KEY_ORDER
end
contents = path.read
if contents.strip.empty?
contents
else
Pod::YAMLHelper.convert_hash(YAML.load(contents), keys_hint, "\n\n")
end
end
# So we don't need to compare them directly
c.ignores 'Podfile'
......@@ -294,6 +306,11 @@ describe_cli 'pod' do
behaves_like cli_spec 'install_search_paths_inheritance',
'install --no-repo-update'
end
describe 'Integrates a Pod with circular subspec dependencies' do
behaves_like cli_spec 'install_circular_subspec_dependency',
'install --no-repo-update'
end
end
#--------------------------------------#
......
require File.expand_path('../../spec_helper', __FILE__)
module Pod
describe Downloader do
before do
@target_path = Pathname.new(Dir.mktmpdir)
source = { :git => SpecHelper.fixture('banana-lib'), :branch => 'master' }
@request = Downloader::Request.new(:name => 'BananaLib', :params => source)
end
after do
@target_path.rmtree if @target_path.directory?
end
it 'preprocesses requests' do
Downloader.expects(:preprocess_request).returns(@request)
Downloader.download(@request, @target_path, :can_cache => false)
end
end
end
This diff is collapsed.
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Installer::TargetInstaller do
before do
@podfile = Podfile.new do
platform :ios
project 'SampleProject/SampleProject'
target 'SampleProject'
end
@target_definition = @podfile.target_definitions['SampleProject']
@project = Project.new(config.sandbox.project_path)
config.sandbox.project = @project
path_list = Sandbox::PathList.new(fixture('banana-lib'))
@spec = fixture_spec('banana-lib/BananaLib.podspec')
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@project.add_pod_group('BananaLib', fixture('banana-lib'))
group = @project.group_for_spec('BananaLib')
file_accessor.source_files.each do |file|
@project.add_file_reference(file, group)
end
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@pod_target.file_accessors = [file_accessor]
@installer = Installer::TargetInstaller.new(config.sandbox, @pod_target)
end
it 'adds the architectures to the custom build configurations of the user target' do
@pod_target.archs = '$(ARCHS_STANDARD_64_BIT)'
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('ARCHS').should == {
'Release' => '$(ARCHS_STANDARD_64_BIT)',
'Debug' => '$(ARCHS_STANDARD_64_BIT)',
'AppStore' => '$(ARCHS_STANDARD_64_BIT)',
'Test' => '$(ARCHS_STANDARD_64_BIT)',
}
end
it 'always clears the OTHER_LDFLAGS and OTHER_LIBTOOLFLAGS, because these lib targets do not ever need any' do
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('OTHER_LDFLAGS').values.uniq.should == ['']
@installer.send(:native_target).resolved_build_setting('OTHER_LIBTOOLFLAGS').values.uniq.should == ['']
end
it 'adds Swift-specific build settings to the build settings' do
@pod_target.stubs(:requires_frameworks?).returns(true)
@pod_target.stubs(:uses_swift?).returns(true)
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('SWIFT_OPTIMIZATION_LEVEL').should == {
'Release' => nil,
'Debug' => '-Onone',
'Test' => nil,
'AppStore' => nil,
}
end
end
end
require File.expand_path('../../../../../spec_helper', __FILE__)
module Pod
class Installer
class Xcode
class PodsProjectGenerator
describe TargetInstaller do
before do
@podfile = Podfile.new do
platform :ios
project 'SampleProject/SampleProject'
target 'SampleProject'
end
@target_definition = @podfile.target_definitions['SampleProject']
@project = Project.new(config.sandbox.project_path)
config.sandbox.project = @project
path_list = Sandbox::PathList.new(fixture('banana-lib'))
@spec = fixture_spec('banana-lib/BananaLib.podspec')
file_accessor = Sandbox::FileAccessor.new(path_list, @spec.consumer(:ios))
@project.add_pod_group('BananaLib', fixture('banana-lib'))
group = @project.group_for_spec('BananaLib')
file_accessor.source_files.each do |file|
@project.add_file_reference(file, group)
end
@pod_target = PodTarget.new([@spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
@pod_target.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@pod_target.file_accessors = [file_accessor]
@installer = TargetInstaller.new(config.sandbox, @pod_target)
end
it 'adds the architectures to the custom build configurations of the user target' do
@pod_target.archs = '$(ARCHS_STANDARD_64_BIT)'
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('ARCHS').should == {
'Release' => '$(ARCHS_STANDARD_64_BIT)',
'Debug' => '$(ARCHS_STANDARD_64_BIT)',
'AppStore' => '$(ARCHS_STANDARD_64_BIT)',
'Test' => '$(ARCHS_STANDARD_64_BIT)',
}
end
it 'always clears the OTHER_LDFLAGS and OTHER_LIBTOOLFLAGS, because these lib targets do not ever need any' do
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('OTHER_LDFLAGS').values.uniq.should == ['']
@installer.send(:native_target).resolved_build_setting('OTHER_LIBTOOLFLAGS').values.uniq.should == ['']
end
it 'adds Swift-specific build settings to the build settings' do
@pod_target.stubs(:requires_frameworks?).returns(true)
@pod_target.stubs(:uses_swift?).returns(true)
@installer.send(:add_target)
@installer.send(:native_target).resolved_build_setting('SWIFT_OPTIMIZATION_LEVEL').should == {
'Release' => nil,
'Debug' => '-Onone',
'Test' => nil,
'AppStore' => nil,
}
end
end
end
end
end
end
This diff is collapsed.
This diff is collapsed.
......@@ -281,6 +281,29 @@ module Pod
@pod_target.requires_frameworks?.should == true
end
end
describe 'With dependencies' do
before do
@pod_dependency = fixture_pod_target('orange-framework/OrangeFramework.podspec')
@pod_target.dependent_targets = [@pod_dependency]
end
it 'resolves simple dependencies' do
@pod_target.recursive_dependent_targets.should == [@pod_dependency]
end
describe 'With cyclic dependencies' do
before do
@pod_dependency = fixture_pod_target('orange-framework/OrangeFramework.podspec')
@pod_dependency.dependent_targets = [@pod_target]
@pod_target.dependent_targets = [@pod_dependency]
end
it 'resolves the cycle' do
@pod_target.recursive_dependent_targets.should == [@pod_dependency]
end
end
end
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment