cocoapods 1.5.2 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +365 -1
  3. data/bin/pod +1 -1
  4. data/lib/cocoapods/command/cache/clean.rb +1 -1
  5. data/lib/cocoapods/command/init.rb +4 -2
  6. data/lib/cocoapods/command/install.rb +7 -0
  7. data/lib/cocoapods/command/lib/lint.rb +8 -1
  8. data/lib/cocoapods/command/outdated.rb +4 -9
  9. data/lib/cocoapods/command/repo/add.rb +1 -1
  10. data/lib/cocoapods/command/repo/list.rb +1 -1
  11. data/lib/cocoapods/command/repo/push.rb +17 -12
  12. data/lib/cocoapods/command/repo/remove.rb +1 -1
  13. data/lib/cocoapods/command/repo/update.rb +1 -1
  14. data/lib/cocoapods/command/setup.rb +1 -1
  15. data/lib/cocoapods/command/spec/create.rb +39 -39
  16. data/lib/cocoapods/command/spec/lint.rb +8 -1
  17. data/lib/cocoapods/command.rb +3 -1
  18. data/lib/cocoapods/config.rb +13 -2
  19. data/lib/cocoapods/downloader/cache.rb +1 -1
  20. data/lib/cocoapods/executable.rb +3 -3
  21. data/lib/cocoapods/external_sources/abstract_external_source.rb +23 -13
  22. data/lib/cocoapods/external_sources.rb +7 -4
  23. data/lib/cocoapods/gem_version.rb +1 -1
  24. data/lib/cocoapods/generator/acknowledgements/markdown.rb +6 -0
  25. data/lib/cocoapods/generator/acknowledgements/plist.rb +13 -2
  26. data/lib/cocoapods/generator/app_target_helper.rb +141 -17
  27. data/lib/cocoapods/generator/copy_resources_script.rb +14 -3
  28. data/lib/cocoapods/generator/dummy_source.rb +14 -5
  29. data/lib/cocoapods/generator/embed_frameworks_script.rb +37 -20
  30. data/lib/cocoapods/generator/header.rb +1 -1
  31. data/lib/cocoapods/generator/info_plist_file.rb +12 -4
  32. data/lib/cocoapods/generator/prefix_header.rb +2 -2
  33. data/lib/cocoapods/hooks_manager.rb +28 -17
  34. data/lib/cocoapods/installer/analyzer/analysis_result.rb +52 -22
  35. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +14 -6
  36. data/lib/cocoapods/installer/analyzer/pod_variant.rb +4 -5
  37. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +3 -14
  38. data/lib/cocoapods/installer/analyzer/specs_state.rb +28 -4
  39. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +27 -14
  40. data/lib/cocoapods/installer/analyzer/target_inspector.rb +17 -11
  41. data/lib/cocoapods/installer/analyzer.rb +391 -284
  42. data/lib/cocoapods/installer/installation_options.rb +2 -0
  43. data/lib/cocoapods/installer/pod_source_installer.rb +31 -43
  44. data/lib/cocoapods/installer/post_install_hooks_context.rb +72 -47
  45. data/lib/cocoapods/installer/pre_install_hooks_context.rb +22 -13
  46. data/lib/cocoapods/installer/source_provider_hooks_context.rb +3 -1
  47. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +44 -11
  48. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +69 -29
  49. data/lib/cocoapods/installer/user_project_integrator.rb +6 -4
  50. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +25 -16
  51. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +104 -0
  52. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +23 -50
  53. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +296 -177
  54. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +51 -33
  55. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +93 -0
  56. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +62 -69
  57. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +72 -0
  58. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +130 -122
  59. data/lib/cocoapods/installer/xcode/target_validator.rb +15 -9
  60. data/lib/cocoapods/installer.rb +140 -63
  61. data/lib/cocoapods/project.rb +16 -14
  62. data/lib/cocoapods/resolver/resolver_specification.rb +41 -0
  63. data/lib/cocoapods/resolver.rb +79 -98
  64. data/lib/cocoapods/sandbox/file_accessor.rb +11 -6
  65. data/lib/cocoapods/sandbox/headers_store.rb +9 -8
  66. data/lib/cocoapods/sandbox/path_list.rb +5 -8
  67. data/lib/cocoapods/sandbox.rb +31 -43
  68. data/lib/cocoapods/sources_manager.rb +1 -1
  69. data/lib/cocoapods/target/aggregate_target.rb +143 -85
  70. data/lib/cocoapods/target/build_settings.rb +1124 -0
  71. data/lib/cocoapods/target/framework_paths.rb +36 -0
  72. data/lib/cocoapods/target/pod_target.rb +198 -295
  73. data/lib/cocoapods/target.rb +92 -37
  74. data/lib/cocoapods/user_interface.rb +5 -0
  75. data/lib/cocoapods/validator.rb +149 -44
  76. data/lib/cocoapods.rb +0 -1
  77. metadata +31 -23
  78. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +0 -260
  79. data/lib/cocoapods/generator/xcconfig/pod_xcconfig.rb +0 -87
  80. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +0 -558
  81. data/lib/cocoapods/generator/xcconfig.rb +0 -13
@@ -108,6 +108,8 @@ module Pod
108
108
  option :lock_pod_sources, true
109
109
  option :warn_for_multiple_pod_sources, true
110
110
  option :share_schemes_for_development_pods, false
111
+ option :disable_input_output_paths, false
112
+ option :preserve_pod_file_structure, false
111
113
 
112
114
  module Mixin
113
115
  module ClassMethods
@@ -8,6 +8,8 @@ module Pod
8
8
  # @note This class needs to consider all the activated specs of a Pod.
9
9
  #
10
10
  class PodSourceInstaller
11
+ UNENCRYPTED_PROTOCOLS = %w(http git).freeze
12
+
11
13
  # @return [Sandbox] The installation target.
12
14
  #
13
15
  attr_reader :sandbox
@@ -24,9 +26,9 @@ module Pod
24
26
 
25
27
  # Initialize a new instance
26
28
  #
27
- # @param [Sandbox] sandbox @see sandbox
28
- # @param [Hash{Symbol=>Array}] specs_by_platform @see specs_by_platform
29
- # @param [Boolean] can_cache @see can_cache
29
+ # @param [Sandbox] sandbox @see #sandbox
30
+ # @param [Hash{Symbol=>Array}] specs_by_platform @see #specs_by_platform
31
+ # @param [Boolean] can_cache @see #can_cache
30
32
  #
31
33
  def initialize(sandbox, specs_by_platform, can_cache: true)
32
34
  @sandbox = sandbox
@@ -63,9 +65,6 @@ module Pod
63
65
 
64
66
  # Cleans the installations if appropriate.
65
67
  #
66
- # @todo As the pre install hooks need to run before cleaning this
67
- # method should be refactored.
68
- #
69
68
  # @return [void]
70
69
  #
71
70
  def clean!
@@ -74,45 +73,29 @@ module Pod
74
73
 
75
74
  # Locks the source files if appropriate.
76
75
  #
77
- # @todo As the pre install hooks need to run before cleaning this
78
- # method should be refactored.
79
- #
80
76
  # @return [void]
81
77
  #
82
78
  def lock_files!(file_accessors)
83
79
  return if local?
84
- each_source_file(file_accessors) do |source_file|
85
- FileUtils.chmod('u-w', source_file)
86
- end
80
+ FileUtils.chmod('u-w', source_files(file_accessors))
87
81
  end
88
82
 
89
83
  # Unlocks the source files if appropriate.
90
84
  #
91
- # @todo As the pre install hooks need to run before cleaning this
92
- # method should be refactored.
93
- #
94
85
  # @return [void]
95
86
  #
96
87
  def unlock_files!(file_accessors)
97
88
  return if local?
98
- each_source_file(file_accessors) do |source_file|
99
- FileUtils.chmod('u+w', source_file)
100
- end
89
+ FileUtils.chmod('u+w', source_files(file_accessors))
101
90
  end
102
91
 
103
- # @return [Hash] @see Downloader#checkout_options
104
- #
105
- attr_reader :specific_source
106
-
107
92
  #-----------------------------------------------------------------------#
108
93
 
109
94
  private
110
95
 
111
96
  # @!group Installation Steps
112
97
 
113
- # Downloads the source of the Pod. It also stores the specific options
114
- # needed to recreate the same exact installation if needed in
115
- # `#specific_source`.
98
+ # Downloads the source of the Pod.
116
99
  #
117
100
  # @return [void]
118
101
  #
@@ -120,23 +103,31 @@ module Pod
120
103
  verify_source_is_secure(root_spec)
121
104
  download_result = Downloader.download(download_request, root, :can_cache => can_cache?)
122
105
 
123
- if (@specific_source = download_result.checkout_options) && specific_source != root_spec.source
106
+ if (specific_source = download_result.checkout_options) && specific_source != root_spec.source
124
107
  sandbox.store_checkout_source(root_spec.name, specific_source)
125
108
  end
126
109
  end
127
110
 
128
- # Verify the source of the spec is secure, which is used to
129
- # show a warning to the user if that isn't the case
130
- # This method doesn't verify all protocols, but currently
131
- # only prohibits unencrypted http:// connections
111
+ # Verify the source of the spec is secure, which is used to show a warning to the user if that isn't the case
112
+ # This method doesn't verify all protocols, but currently only prohibits unencrypted 'http://' and 'git://''
113
+ # connections.
114
+ #
115
+ # @return [void]
132
116
  #
133
117
  def verify_source_is_secure(root_spec)
134
- return if root_spec.source.nil? || root_spec.source[:http].nil?
135
- http_source = URI(root_spec.source[:http])
136
- return if http_source.scheme == 'https' || http_source.scheme == 'file'
137
- UI.warn "'#{root_spec.name}' uses the unencrypted http protocol to transfer the Pod. " \
138
- 'Please be sure you\'re in a safe network with only trusted hosts in there. ' \
139
- 'Please reach out to the library author to notify them of this security issue.'
118
+ return if root_spec.source.nil? || (root_spec.source[:http].nil? && root_spec.source[:git].nil?)
119
+ source = if !root_spec.source[:http].nil?
120
+ URI(root_spec.source[:http].to_s)
121
+ elsif !root_spec.source[:git].nil?
122
+ git_source = root_spec.source[:git].to_s
123
+ return unless git_source =~ /^#{URI.regexp}$/
124
+ URI(git_source)
125
+ end
126
+ if UNENCRYPTED_PROTOCOLS.include?(source.scheme) && source.host != 'localhost'
127
+ UI.warn "'#{root_spec.name}' uses the unencrypted '#{source.scheme}' protocol to transfer the Pod. " \
128
+ 'Please be sure you\'re in a safe network with only trusted hosts. ' \
129
+ 'Otherwise, please reach out to the library author to notify them of this security issue.'
130
+ end
140
131
  end
141
132
 
142
133
  def download_request
@@ -199,13 +190,10 @@ module Pod
199
190
  !local? && !predownloaded? && sandbox.specification(root_spec.name) != root_spec
200
191
  end
201
192
 
202
- def each_source_file(file_accessors, &blk)
203
- file_accessors.each do |file_accessor|
204
- file_accessor.source_files.each do |source_file|
205
- next unless source_file.exist?
206
- blk[source_file]
207
- end
208
- end
193
+ # @return [Array<Pathname>] The paths of the source files
194
+ #
195
+ def source_files(file_accessors)
196
+ file_accessors.flat_map(&:source_files)
209
197
  end
210
198
 
211
199
  #-----------------------------------------------------------------------#
@@ -4,22 +4,36 @@ module Pod
4
4
  # the context of the installer.
5
5
  #
6
6
  class PostInstallHooksContext
7
- # @return [String] The path to the sandbox root (`Pods` directory).
7
+ # @return [Sandbox] The Sandbox for the project.
8
8
  #
9
- attr_accessor :sandbox_root
9
+ attr_reader :sandbox
10
10
 
11
- # @return [Project] The Pods Xcode project.
11
+ # @return [String] The path to the sandbox root (`Pods` directory).
12
12
  #
13
- attr_accessor :pods_project
13
+ attr_reader :sandbox_root
14
14
 
15
- # @return [Sandbox] The Sandbox for the project.
15
+ # @return [Xcodeproj::Project] The Pods Xcode project.
16
16
  #
17
- attr_accessor :sandbox
17
+ attr_reader :pods_project
18
18
 
19
19
  # @return [Array<UmbrellaTargetDescription>] The list of
20
20
  # the CocoaPods umbrella targets generated by the installer.
21
21
  #
22
- attr_accessor :umbrella_targets
22
+ attr_reader :umbrella_targets
23
+
24
+ # Initialize a new instance
25
+ #
26
+ # @param [Sandbox] sandbox see #sandbox
27
+ # @param [String] sandbox_root see #sandbox_root
28
+ # @param [Xcodeproj::Project] pods_project see #pods_project
29
+ # @param [Array<UmbrellaTargetDescription>] umbrella_targets see #umbrella_targets
30
+ #
31
+ def initialize(sandbox, sandbox_root, pods_project, umbrella_targets)
32
+ @sandbox = sandbox
33
+ @sandbox_root = sandbox_root
34
+ @pods_project = pods_project
35
+ @umbrella_targets = umbrella_targets
36
+ end
23
37
 
24
38
  # @return [PostInstallHooksContext] Convenience class generator method
25
39
  #
@@ -34,33 +48,66 @@ module Pod
34
48
  # static context.
35
49
  #
36
50
  def self.generate(sandbox, aggregate_targets)
37
- umbrella_targets_descriptions = []
38
- aggregate_targets.each do |umbrella|
39
- desc = UmbrellaTargetDescription.new
40
- desc.user_project = umbrella.user_project
41
- desc.user_targets = umbrella.user_targets
42
- desc.specs = umbrella.specs
43
- desc.platform_name = umbrella.platform.name
44
- desc.platform_deployment_target = umbrella.platform.deployment_target.to_s
45
- desc.cocoapods_target_label = umbrella.label
46
- umbrella_targets_descriptions << desc
51
+ umbrella_targets_descriptions = aggregate_targets.map do |umbrella|
52
+ user_project = umbrella.user_project
53
+ user_targets = umbrella.user_targets
54
+ specs = umbrella.specs
55
+ platform_name = umbrella.platform.name
56
+ platform_deployment_target = umbrella.platform.deployment_target.to_s
57
+ cocoapods_target_label = umbrella.label
58
+ UmbrellaTargetDescription.new(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
47
59
  end
48
60
 
49
- result = new
50
- result.sandbox_root = sandbox.root.to_s
51
- result.pods_project = sandbox.project
52
- result.sandbox = sandbox
53
- result.umbrella_targets = umbrella_targets_descriptions
54
- result
61
+ new(sandbox, sandbox.root.to_s, sandbox.project, umbrella_targets_descriptions)
55
62
  end
56
63
 
57
- # Pure data class which describes and umbrella target.
64
+ # Pure data class which describes an umbrella target.
58
65
  #
59
66
  class UmbrellaTargetDescription
60
67
  # @return [Xcodeproj::Project] The user project into which this target
61
68
  # is integrated.
62
69
  #
63
- attr_accessor :user_project
70
+ attr_reader :user_project
71
+
72
+ # @return [Array<PBXNativeTarget>]
73
+ # The list of user targets integrated by this umbrella target.
74
+ #
75
+ attr_reader :user_targets
76
+
77
+ # @return [Array<Specification>] The list of the
78
+ # specifications of the target.
79
+ #
80
+ attr_reader :specs
81
+
82
+ # @return [Symbol] The platform (either `:ios`, `:watchos`, `:tvos`, or `:osx`).
83
+ #
84
+ attr_reader :platform_name
85
+
86
+ # @return [String] The deployment target.
87
+ #
88
+ attr_reader :platform_deployment_target
89
+
90
+ # @return [String] The label for the target.
91
+ #
92
+ attr_reader :cocoapods_target_label
93
+
94
+ # Initialize a new instance
95
+ #
96
+ # @param [Xcodeproj::Project] user_project see #user_project
97
+ # @param [Array<PBXNativeTarget>] user_targets see #user_targets
98
+ # @param [Array<Specification>] specs see #specs
99
+ # @param [Symbol] platform_name see #platform_name
100
+ # @param [String] platform_deployment_target see #platform_deployment_target
101
+ # @param [String] cocoapods_target_label see #cocoapods_target_label
102
+ #
103
+ def initialize(user_project, user_targets, specs, platform_name, platform_deployment_target, cocoapods_target_label)
104
+ @user_project = user_project
105
+ @user_targets = user_targets
106
+ @specs = specs
107
+ @platform_name = platform_name
108
+ @platform_deployment_target = platform_deployment_target
109
+ @cocoapods_target_label = cocoapods_target_label
110
+ end
64
111
 
65
112
  # @return [String] The path of the user project
66
113
  # integrated by this target.
@@ -69,11 +116,6 @@ module Pod
69
116
  user_project.path if user_project
70
117
  end
71
118
 
72
- # @return [Array<PBXNativeTarget>]
73
- # The list of user targets integrated by this umbrella target.
74
- #
75
- attr_accessor :user_targets
76
-
77
119
  # @return [Array<String>] The list of the UUIDs of the
78
120
  # user targets integrated by this umbrella
79
121
  # target. They can be used to find the
@@ -84,23 +126,6 @@ module Pod
84
126
  def user_target_uuids
85
127
  user_targets.map(&:uuid)
86
128
  end
87
-
88
- # @return [Array<Specification>] The list of the
89
- # specifications of the target.
90
- #
91
- attr_accessor :specs
92
-
93
- # @return [Symbol] The platform (either `:ios`, `:watchos`, `:tvos`, or `:osx`).
94
- #
95
- attr_accessor :platform_name
96
-
97
- # @return [String] The deployment target.
98
- #
99
- attr_accessor :platform_deployment_target
100
-
101
- # @return [String] The label for the target.
102
- #
103
- attr_accessor :cocoapods_target_label
104
129
  end
105
130
  end
106
131
  end
@@ -4,21 +4,35 @@ module Pod
4
4
  # the context of the installer before analysis has been completed.
5
5
  #
6
6
  class PreInstallHooksContext
7
- # @return [String] The path to the sandbox root (`Pods` directory).
8
- #
9
- attr_accessor :sandbox_root
10
-
11
7
  # @return [Podfile] The Podfile for the project.
12
8
  #
13
- attr_accessor :podfile
9
+ attr_reader :podfile
14
10
 
15
11
  # @return [Sandbox] The Sandbox for the project.
16
12
  #
17
- attr_accessor :sandbox
13
+ attr_reader :sandbox
14
+
15
+ # @return [String] The path to the sandbox root (`Pods` directory).
16
+ #
17
+ attr_reader :sandbox_root
18
18
 
19
19
  # @return [Lockfile] The Lockfile for the project.
20
20
  #
21
- attr_accessor :lockfile
21
+ attr_reader :lockfile
22
+
23
+ # Initialize a new instance
24
+ #
25
+ # @param [Sandbox] sandbox see #sandbox
26
+ # @param [String] sandbox_root see #sandbox_root
27
+ # @param [Podfile] podfile see #podfile
28
+ # @param [Lockfile] lockfile see #lockfile
29
+ #
30
+ def initialize(podfile, sandbox, sandbox_root, lockfile)
31
+ @podfile = podfile
32
+ @sandbox = sandbox
33
+ @sandbox_root = sandbox_root
34
+ @lockfile = lockfile
35
+ end
22
36
 
23
37
  # @param [Sandbox] sandbox see {#sandbox}
24
38
  #
@@ -30,12 +44,7 @@ module Pod
30
44
  # static context.
31
45
  #
32
46
  def self.generate(sandbox, podfile, lockfile)
33
- result = new
34
- result.podfile = podfile
35
- result.sandbox = sandbox
36
- result.sandbox_root = sandbox.root.to_s
37
- result.lockfile = lockfile
38
- result
47
+ new(podfile, sandbox, sandbox.root.to_s, lockfile)
39
48
  end
40
49
  end
41
50
  end
@@ -20,7 +20,9 @@ module Pod
20
20
  @sources = []
21
21
  end
22
22
 
23
- # @param [Source] Source object to be added to the installer
23
+ # @param [Source] source object to be added to the installer
24
+ #
25
+ # @return [void]
24
26
  #
25
27
  def add_source(source)
26
28
  unless source.nil?
@@ -42,19 +42,14 @@ module Pod
42
42
  # The build configuration.
43
43
  #
44
44
  def self.set_target_xcconfig(pod_bundle, target, config)
45
- path = pod_bundle.xcconfig_relative_path(config.name)
46
- group = config.project['Pods'] || config.project.new_group('Pods')
47
- file_ref = group.files.find { |f| f.path == path }
48
- existing = config.base_configuration_reference
45
+ file_ref = create_xcconfig_ref(pod_bundle, config)
46
+ path = file_ref.path
49
47
 
50
- set_base_configuration_reference = ->() do
51
- file_ref ||= group.new_file(path)
52
- config.base_configuration_reference = file_ref
53
- end
48
+ existing = config.base_configuration_reference
54
49
 
55
50
  if existing && existing != file_ref
56
51
  if existing.real_path.to_path.start_with?(pod_bundle.sandbox.root.to_path << '/')
57
- set_base_configuration_reference.call
52
+ config.base_configuration_reference = file_ref
58
53
  elsif !xcconfig_includes_target_xcconfig?(config.base_configuration_reference, path)
59
54
  unless existing_config_is_identical_to_pod_config?(existing.real_path, pod_bundle.xcconfig_path(config.name))
60
55
  UI.warn 'CocoaPods did not set the base configuration of your ' \
@@ -66,7 +61,7 @@ module Pod
66
61
  end
67
62
  end
68
63
  elsif config.base_configuration_reference.nil? || file_ref.nil?
69
- set_base_configuration_reference.call
64
+ config.base_configuration_reference = file_ref
70
65
  end
71
66
  end
72
67
 
@@ -97,7 +92,7 @@ module Pod
97
92
  ]
98
93
  message = "The `#{target.name} [#{config.name}]` " \
99
94
  "target overrides the `#{key}` build setting defined in " \
100
- "`#{pod_bundle.xcconfig_relative_path(config.name)}'. " \
95
+ "`#{pod_bundle.pod_bundle.xcconfig_relative_path(config.name)}'. " \
101
96
  'This can lead to problems with the CocoaPods installation'
102
97
  UI.warn(message, actions)
103
98
  end
@@ -139,6 +134,44 @@ module Pod
139
134
  def self.existing_config_is_identical_to_pod_config?(existing_config_path, pod_config_path)
140
135
  existing_config_path.file? && (!pod_config_path.file? || FileUtils.compare_file(existing_config_path, pod_config_path))
141
136
  end
137
+
138
+ # Creates a file reference to the xcconfig generated by
139
+ # CocoaPods (if needed).
140
+ # If the Pods group not exists, create the group and set
141
+ # the location to the `Pods` directory.
142
+ # If the file reference exists, the location is different
143
+ # with the xcconfig's path and the symlink target paths
144
+ # are different, we will update the location.
145
+ #
146
+ # @param [Target::AggregateTarget] pod_bundle
147
+ # The Pods bundle.
148
+ #
149
+ # @param [Xcodeproj::XCBuildConfiguration] config
150
+ # The build configuration.
151
+ #
152
+ # @return [PBXFileReference] the xcconfig reference.
153
+ #
154
+ def self.create_xcconfig_ref(pod_bundle, config)
155
+ # Xcode root group's path is absolute, we must get the relative path of the sandbox to the user project
156
+ group_path = pod_bundle.relative_pods_root_path
157
+ group = config.project['Pods'] || config.project.new_group('Pods', group_path)
158
+
159
+ # support user custom paths of Pods group and xcconfigs files.
160
+ group_path = Pathname.new(group.real_path)
161
+ xcconfig_path = Pathname.new(pod_bundle.xcconfig_path(config.name))
162
+ path = xcconfig_path.relative_path_from(group_path)
163
+
164
+ filename = path.basename.to_s
165
+ file_ref = group.files.find { |f| f.display_name == filename }
166
+ if file_ref && file_ref.path != path
167
+ file_ref_path = Pathname.new(file_ref.real_path)
168
+ if !file_ref_path.exist? || !xcconfig_path.exist? || file_ref_path.realpath != xcconfig_path.realpath
169
+ file_ref.path = path.to_s
170
+ end
171
+ end
172
+
173
+ file_ref || group.new_file(path.to_s)
174
+ end
142
175
  end
143
176
  end
144
177
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/string/inflections'
2
+ require 'cocoapods/target/framework_paths'
2
3
 
3
4
  module Pod
4
5
  class Installer
@@ -48,12 +49,18 @@ module Pod
48
49
  #
49
50
  attr_reader :target
50
51
 
52
+ # @return [InstallationOptions] the installation options from the Podfile.
53
+ #
54
+ attr_reader :installation_options
55
+
51
56
  # Init a new TargetIntegrator
52
57
  #
53
58
  # @param [AggregateTarget] target @see #target
59
+ # @param [InstallationOptions] installation_options @see #installation_options
54
60
  #
55
- def initialize(target)
61
+ def initialize(target, installation_options)
56
62
  @target = target
63
+ @installation_options = installation_options
57
64
  end
58
65
 
59
66
  class << self
@@ -162,7 +169,7 @@ module Pod
162
169
  #
163
170
  def create_or_update_user_script_phases(script_phases, native_target)
164
171
  script_phase_names = script_phases.map { |k| k[:name] }
165
- # Delete script phases no longer present in the target definition.
172
+ # Delete script phases no longer present in the target.
166
173
  native_target_script_phases = native_target.shell_script_build_phases.select { |bp| !bp.name.nil? && bp.name.start_with?(USER_BUILD_PHASE_PREFIX) }
167
174
  native_target_script_phases.each do |script_phase|
168
175
  script_phase_name_without_prefix = script_phase.name.sub(USER_BUILD_PHASE_PREFIX, '')
@@ -171,16 +178,16 @@ module Pod
171
178
  end
172
179
  end
173
180
  # Create or update the ones that are expected to be.
174
- script_phases.each do |td_script_phase|
175
- name_with_prefix = USER_BUILD_PHASE_PREFIX + td_script_phase[:name]
181
+ script_phases.each do |script_phase|
182
+ name_with_prefix = USER_BUILD_PHASE_PREFIX + script_phase[:name]
176
183
  phase = TargetIntegrator.create_or_update_build_phase(native_target, name_with_prefix)
177
- phase.shell_script = td_script_phase[:script]
178
- phase.shell_path = td_script_phase[:shell_path] if td_script_phase.key?(:shell_path)
179
- phase.input_paths = td_script_phase[:input_files] if td_script_phase.key?(:input_files)
180
- phase.output_paths = td_script_phase[:output_files] if td_script_phase.key?(:output_files)
181
- phase.show_env_vars_in_log = td_script_phase[:show_env_vars_in_log] ? '1' : '0' if td_script_phase.key?(:show_env_vars_in_log)
184
+ phase.shell_script = script_phase[:script]
185
+ phase.shell_path = script_phase[:shell_path] if script_phase.key?(:shell_path)
186
+ phase.input_paths = script_phase[:input_files] if script_phase.key?(:input_files)
187
+ phase.output_paths = script_phase[:output_files] if script_phase.key?(:output_files)
188
+ phase.show_env_vars_in_log = script_phase[:show_env_vars_in_log] ? '1' : '0' if script_phase.key?(:show_env_vars_in_log)
182
189
 
183
- execution_position = td_script_phase[:execution_position]
190
+ execution_position = script_phase[:execution_position]
184
191
  unless execution_position == :any
185
192
  compile_build_phase_index = native_target.build_phases.index do |bp|
186
193
  bp.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase)
@@ -254,6 +261,23 @@ module Pod
254
261
  File.join(base_path, File.basename(basename, extname) + output_extension)
255
262
  end.uniq
256
263
  end
264
+
265
+ # Returns the framework output paths for the given input paths
266
+ #
267
+ # @param [Array<Target::FrameworkPaths>] framework_input_paths
268
+ # The framework input paths to map to output paths.
269
+ #
270
+ # @return [Array<String>] The framework output paths
271
+ #
272
+ def framework_output_paths(framework_input_paths)
273
+ framework_input_paths.flat_map do |framework_path|
274
+ framework_output_path = "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/#{File.basename(framework_path.source_path)}"
275
+ dsym_path = if (dsym_input_path = framework_path.dsym_path)
276
+ "${DWARF_DSYM_FOLDER_PATH}/#{File.basename(dsym_input_path)}"
277
+ end
278
+ [framework_output_path, dsym_path]
279
+ end.compact.uniq
280
+ end
257
281
  end
258
282
 
259
283
  # Integrates the user project targets. Only the targets that do **not**
@@ -321,18 +345,26 @@ module Pod
321
345
  # @return [void]
322
346
  #
323
347
  def add_copy_resources_script_phase
324
- native_targets.each do |native_target|
325
- script_path = target.copy_resources_script_relative_path
326
- resource_paths_by_config = target.resource_paths_by_config
327
- if resource_paths_by_config.values.all?(&:empty?)
348
+ unless target.includes_resources?
349
+ native_targets.each do |native_target|
328
350
  TargetIntegrator.remove_copy_resources_script_phase_from_target(native_target)
329
- else
330
- resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
331
- input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
332
- output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
333
- TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
334
- TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
335
351
  end
352
+ return
353
+ end
354
+ script_path = target.copy_resources_script_relative_path
355
+ input_paths = []
356
+ output_paths = []
357
+ unless installation_options.disable_input_output_paths?
358
+ resource_paths_by_config = target.resource_paths_by_config
359
+ resource_paths_flattened = resource_paths_by_config.values.flatten.uniq
360
+ input_paths = [target.copy_resources_script_relative_path, *resource_paths_flattened]
361
+ output_paths = TargetIntegrator.resource_output_paths(resource_paths_flattened)
362
+ end
363
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
364
+ native_targets.each do |native_target|
365
+ # Static library targets cannot include resources. Skip this phase from being added instead.
366
+ next if native_target.symbol_type == :static_library
367
+ TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths, output_paths)
336
368
  end
337
369
  end
338
370
 
@@ -356,17 +388,25 @@ module Pod
356
388
  # @return [void]
357
389
  #
358
390
  def add_embed_frameworks_script_phase
359
- native_targets_to_embed_in.each do |native_target|
360
- script_path = target.embed_frameworks_script_relative_path
361
- framework_paths_by_config = target.framework_paths_by_config.values.flatten.uniq
362
- if framework_paths_by_config.all?(&:empty?)
391
+ unless target.includes_frameworks?
392
+ native_targets_to_embed_in.each do |native_target|
363
393
  TargetIntegrator.remove_embed_frameworks_script_phase_from_target(native_target)
364
- else
365
- input_paths = [target.embed_frameworks_script_relative_path, *framework_paths_by_config.map { |fw| [fw[:input_path], fw[:dsym_input_path]] }.flatten.compact]
366
- output_paths = framework_paths_by_config.map { |fw| [fw[:output_path], fw[:dsym_output_path]] }.flatten.compact.uniq
367
- TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
368
- TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
369
394
  end
395
+ return
396
+ end
397
+ script_path = target.embed_frameworks_script_relative_path
398
+ input_paths = []
399
+ output_paths = []
400
+ unless installation_options.disable_input_output_paths?
401
+ framework_paths = target.framework_paths_by_config.values.flatten.uniq
402
+ framework_input_paths = framework_paths.flat_map { |path| [path.source_path, path.dsym_path] }.compact
403
+ input_paths = [target.embed_frameworks_script_relative_path, *framework_input_paths]
404
+ output_paths = TargetIntegrator.framework_output_paths(framework_paths)
405
+ TargetIntegrator.validate_input_output_path_limit(input_paths, output_paths)
406
+ end
407
+
408
+ native_targets_to_embed_in.each do |native_target|
409
+ TargetIntegrator.create_or_update_embed_frameworks_script_phase_to_target(native_target, script_path, input_paths, output_paths)
370
410
  end
371
411
  end
372
412
 
@@ -13,6 +13,10 @@ module Pod
13
13
  class UserProjectIntegrator
14
14
  autoload :TargetIntegrator, 'cocoapods/installer/user_project_integrator/target_integrator'
15
15
 
16
+ include InstallationOptions::Mixin
17
+
18
+ delegate_installation_options { podfile }
19
+
16
20
  # @return [Podfile] the podfile that should be integrated with the user
17
21
  # projects.
18
22
  #
@@ -42,9 +46,7 @@ module Pod
42
46
  # @param [Podfile] podfile @see #podfile
43
47
  # @param [Sandbox] sandbox @see #sandbox
44
48
  # @param [Pathname] installation_root @see #installation_root
45
- # @param [Array<AggregateTarget>] targets @see #targets
46
- #
47
- # @todo Too many initialization arguments
49
+ # @param [Array<AggregateTarget>] targets @see #targets
48
50
  #
49
51
  def initialize(podfile, sandbox, installation_root, targets)
50
52
  @podfile = podfile
@@ -113,7 +115,7 @@ module Pod
113
115
  #
114
116
  def integrate_user_targets
115
117
  target_integrators = targets_to_integrate.sort_by(&:name).map do |target|
116
- TargetIntegrator.new(target)
118
+ TargetIntegrator.new(target, installation_options)
117
119
  end
118
120
 
119
121
  Config.instance.with_changes(:silent => true) do