cocoapods 1.5.2 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
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