xcocoapods 1.5.3

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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6303 -0
  3. data/LICENSE +28 -0
  4. data/README.md +80 -0
  5. data/bin/pod +56 -0
  6. data/bin/sandbox-pod +168 -0
  7. data/lib/cocoapods.rb +73 -0
  8. data/lib/cocoapods/command.rb +175 -0
  9. data/lib/cocoapods/command/cache.rb +28 -0
  10. data/lib/cocoapods/command/cache/clean.rb +90 -0
  11. data/lib/cocoapods/command/cache/list.rb +69 -0
  12. data/lib/cocoapods/command/env.rb +66 -0
  13. data/lib/cocoapods/command/init.rb +128 -0
  14. data/lib/cocoapods/command/install.rb +45 -0
  15. data/lib/cocoapods/command/ipc.rb +19 -0
  16. data/lib/cocoapods/command/ipc/list.rb +40 -0
  17. data/lib/cocoapods/command/ipc/podfile.rb +31 -0
  18. data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
  19. data/lib/cocoapods/command/ipc/repl.rb +51 -0
  20. data/lib/cocoapods/command/ipc/spec.rb +29 -0
  21. data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
  22. data/lib/cocoapods/command/lib.rb +11 -0
  23. data/lib/cocoapods/command/lib/create.rb +105 -0
  24. data/lib/cocoapods/command/lib/lint.rb +121 -0
  25. data/lib/cocoapods/command/list.rb +39 -0
  26. data/lib/cocoapods/command/options/project_directory.rb +36 -0
  27. data/lib/cocoapods/command/options/repo_update.rb +34 -0
  28. data/lib/cocoapods/command/outdated.rb +140 -0
  29. data/lib/cocoapods/command/repo.rb +29 -0
  30. data/lib/cocoapods/command/repo/add.rb +103 -0
  31. data/lib/cocoapods/command/repo/lint.rb +82 -0
  32. data/lib/cocoapods/command/repo/list.rb +93 -0
  33. data/lib/cocoapods/command/repo/push.rb +281 -0
  34. data/lib/cocoapods/command/repo/remove.rb +36 -0
  35. data/lib/cocoapods/command/repo/update.rb +28 -0
  36. data/lib/cocoapods/command/setup.rb +103 -0
  37. data/lib/cocoapods/command/spec.rb +112 -0
  38. data/lib/cocoapods/command/spec/cat.rb +51 -0
  39. data/lib/cocoapods/command/spec/create.rb +283 -0
  40. data/lib/cocoapods/command/spec/edit.rb +87 -0
  41. data/lib/cocoapods/command/spec/env_spec.rb +53 -0
  42. data/lib/cocoapods/command/spec/lint.rb +137 -0
  43. data/lib/cocoapods/command/spec/which.rb +43 -0
  44. data/lib/cocoapods/command/update.rb +101 -0
  45. data/lib/cocoapods/config.rb +347 -0
  46. data/lib/cocoapods/core_overrides.rb +1 -0
  47. data/lib/cocoapods/downloader.rb +190 -0
  48. data/lib/cocoapods/downloader/cache.rb +233 -0
  49. data/lib/cocoapods/downloader/request.rb +86 -0
  50. data/lib/cocoapods/downloader/response.rb +16 -0
  51. data/lib/cocoapods/executable.rb +222 -0
  52. data/lib/cocoapods/external_sources.rb +57 -0
  53. data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
  54. data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
  55. data/lib/cocoapods/external_sources/path_source.rb +55 -0
  56. data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
  57. data/lib/cocoapods/gem_version.rb +5 -0
  58. data/lib/cocoapods/generator/acknowledgements.rb +107 -0
  59. data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
  60. data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
  61. data/lib/cocoapods/generator/app_target_helper.rb +244 -0
  62. data/lib/cocoapods/generator/bridge_support.rb +22 -0
  63. data/lib/cocoapods/generator/constant.rb +19 -0
  64. data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
  65. data/lib/cocoapods/generator/dummy_source.rb +31 -0
  66. data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
  67. data/lib/cocoapods/generator/header.rb +103 -0
  68. data/lib/cocoapods/generator/info_plist_file.rb +116 -0
  69. data/lib/cocoapods/generator/module_map.rb +99 -0
  70. data/lib/cocoapods/generator/prefix_header.rb +60 -0
  71. data/lib/cocoapods/generator/umbrella_header.rb +46 -0
  72. data/lib/cocoapods/hooks_manager.rb +132 -0
  73. data/lib/cocoapods/installer.rb +703 -0
  74. data/lib/cocoapods/installer/analyzer.rb +972 -0
  75. data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
  76. data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
  77. data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
  78. data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
  79. data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
  80. data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
  81. data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
  82. data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
  83. data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
  84. data/lib/cocoapods/installer/installation_options.rb +158 -0
  85. data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
  86. data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
  87. data/lib/cocoapods/installer/podfile_validator.rb +139 -0
  88. data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
  89. data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
  90. data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
  91. data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
  92. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
  93. data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
  94. data/lib/cocoapods/installer/xcode.rb +8 -0
  95. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
  96. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
  97. data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
  98. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
  99. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
  100. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
  101. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
  102. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
  103. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
  104. data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
  105. data/lib/cocoapods/open-uri.rb +33 -0
  106. data/lib/cocoapods/project.rb +414 -0
  107. data/lib/cocoapods/resolver.rb +585 -0
  108. data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
  109. data/lib/cocoapods/sandbox.rb +404 -0
  110. data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
  111. data/lib/cocoapods/sandbox/headers_store.rb +146 -0
  112. data/lib/cocoapods/sandbox/path_list.rb +220 -0
  113. data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
  114. data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
  115. data/lib/cocoapods/sources_manager.rb +157 -0
  116. data/lib/cocoapods/target.rb +261 -0
  117. data/lib/cocoapods/target/aggregate_target.rb +338 -0
  118. data/lib/cocoapods/target/build_settings.rb +1075 -0
  119. data/lib/cocoapods/target/pod_target.rb +559 -0
  120. data/lib/cocoapods/user_interface.rb +459 -0
  121. data/lib/cocoapods/user_interface/error_report.rb +187 -0
  122. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  123. data/lib/cocoapods/validator.rb +981 -0
  124. metadata +533 -0
@@ -0,0 +1,181 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Creates the targets which aggregate the Pods libraries in the Pods
6
+ # project and the relative support files.
7
+ #
8
+ class AggregateTargetInstaller < TargetInstaller
9
+ # Creates the target in the Pods project and the relative support files.
10
+ #
11
+ # @return [TargetInstallationResult] the result of the installation of this target.
12
+ #
13
+ def install!
14
+ UI.message "- Installing target `#{target.name}` #{target.platform}" do
15
+ native_target = add_target
16
+ create_support_files_dir
17
+ create_support_files_group
18
+ create_xcconfig_file(native_target)
19
+ if target.requires_frameworks?
20
+ create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
21
+ create_module_map(native_target)
22
+ create_umbrella_header(native_target)
23
+ elsif target.uses_swift?
24
+ create_module_map(native_target)
25
+ create_umbrella_header(native_target)
26
+ end
27
+ # Because embedded targets live in their host target, CocoaPods
28
+ # copies all of the embedded target's pod_targets to its host
29
+ # targets. Having this script for the embedded target would
30
+ # cause an App Store rejection because frameworks cannot be
31
+ # embedded in embedded targets.
32
+ #
33
+ create_embed_frameworks_script unless target.requires_host_target?
34
+ create_bridge_support_file(native_target)
35
+ create_copy_resources_script
36
+ create_acknowledgements
37
+ create_dummy_source(native_target)
38
+ clean_support_files_temp_dir
39
+ TargetInstallationResult.new(target, native_target)
40
+ end
41
+ end
42
+
43
+ #-----------------------------------------------------------------------#
44
+
45
+ private
46
+
47
+ # @return [TargetDefinition] the target definition of the library.
48
+ #
49
+ def target_definition
50
+ target.target_definition
51
+ end
52
+
53
+ # Ensure that vendored static frameworks and libraries are not linked
54
+ # twice to the aggregate target, which shares the xcconfig of the user
55
+ # target.
56
+ #
57
+ def custom_build_settings
58
+ settings = {
59
+ 'CODE_SIGN_IDENTITY[sdk=appletvos*]' => '',
60
+ 'CODE_SIGN_IDENTITY[sdk=iphoneos*]' => '',
61
+ 'CODE_SIGN_IDENTITY[sdk=watchos*]' => '',
62
+ 'MACH_O_TYPE' => 'staticlib',
63
+ 'OTHER_LDFLAGS' => '',
64
+ 'OTHER_LIBTOOLFLAGS' => '',
65
+ 'PODS_ROOT' => '$(SRCROOT)',
66
+ 'PRODUCT_BUNDLE_IDENTIFIER' => 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}',
67
+ 'SKIP_INSTALL' => 'YES',
68
+
69
+ # Needed to ensure that static libraries won't try to embed the swift stdlib,
70
+ # since there's no where to embed in for a static library.
71
+ # Not necessary for dynamic frameworks either, since the aggregate targets are never shipped
72
+ # on their own, and are always further embedded into an app target.
73
+ 'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' => 'NO',
74
+ }
75
+ super.merge(settings)
76
+ end
77
+
78
+ # Creates the group that holds the references to the support files
79
+ # generated by this installer.
80
+ #
81
+ # @return [void]
82
+ #
83
+ def create_support_files_group
84
+ parent = project.support_files_group
85
+ name = target.name
86
+ dir = target.support_files_dir
87
+ @support_files_group = parent.new_group(name, dir)
88
+ end
89
+
90
+ # Generates the contents of the xcconfig file and saves it to disk.
91
+ #
92
+ # @param [PBXNativeTarget] native_target
93
+ # the native target to link the module map file into.
94
+ #
95
+ # @return [void]
96
+ #
97
+ def create_xcconfig_file(native_target)
98
+ native_target.build_configurations.each do |configuration|
99
+ next unless target.user_build_configurations.key?(configuration.name)
100
+ path = target.xcconfig_path(configuration.name)
101
+ build_settings = target.build_settings(configuration.name)
102
+ update_changed_file(build_settings, path)
103
+ target.xcconfigs[configuration.name] = build_settings.xcconfig
104
+ xcconfig_file_ref = add_file_to_support_group(path)
105
+ configuration.base_configuration_reference = xcconfig_file_ref
106
+ end
107
+ end
108
+
109
+ # Generates the bridge support metadata if requested by the {Podfile}.
110
+ #
111
+ # @note The bridge support metadata is added to the resources of the
112
+ # target because it is needed for environments interpreted at
113
+ # runtime.
114
+ #
115
+ # @param [PBXNativeTarget] native_target
116
+ # the native target to add the bridge support file into.
117
+ #
118
+ # @return [void]
119
+ #
120
+ def create_bridge_support_file(native_target)
121
+ if target.podfile.generate_bridge_support?
122
+ path = target.bridge_support_path
123
+ headers = native_target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
124
+ generator = Generator::BridgeSupport.new(headers)
125
+ update_changed_file(generator, path)
126
+ add_file_to_support_group(path)
127
+ end
128
+ end
129
+
130
+ # Creates a script that copies the resources to the bundle of the client
131
+ # target.
132
+ #
133
+ # @note The bridge support file needs to be created before the prefix
134
+ # header, otherwise it will not be added to the resources script.
135
+ #
136
+ # @return [void]
137
+ #
138
+ def create_copy_resources_script
139
+ path = target.copy_resources_script_path
140
+ generator = Generator::CopyResourcesScript.new(target.resource_paths_by_config, target.platform)
141
+ update_changed_file(generator, path)
142
+ add_file_to_support_group(path)
143
+ end
144
+
145
+ # Creates a script that embeds the frameworks to the bundle of the client
146
+ # target.
147
+ #
148
+ # @note We can't use Xcode default copy bundle resource phase, because
149
+ # we need to ensure that we only copy the resources, which are
150
+ # relevant for the current build configuration.
151
+ #
152
+ # @return [void]
153
+ #
154
+ def create_embed_frameworks_script
155
+ path = target.embed_frameworks_script_path
156
+ generator = Generator::EmbedFrameworksScript.new(target.framework_paths_by_config)
157
+ update_changed_file(generator, path)
158
+ add_file_to_support_group(path)
159
+ end
160
+
161
+ # Generates the acknowledgement files (markdown and plist) for the target.
162
+ #
163
+ # @return [void]
164
+ #
165
+ def create_acknowledgements
166
+ basepath = target.acknowledgements_basepath
167
+ Generator::Acknowledgements.generators.each do |generator_class|
168
+ path = generator_class.path_from_basepath(basepath)
169
+ file_accessors = target.pod_targets.map(&:file_accessors).flatten
170
+ generator = generator_class.new(file_accessors)
171
+ update_changed_file(generator, path)
172
+ add_file_to_support_group(path)
173
+ end
174
+ end
175
+
176
+ #-----------------------------------------------------------------------#
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,84 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Installs an app host target to a given project.
6
+ #
7
+ class AppHostInstaller
8
+ include TargetInstallerHelper
9
+
10
+ # @return [Sandbox] sandbox
11
+ # The sandbox used for this installation.
12
+ #
13
+ attr_reader :sandbox
14
+
15
+ # @return [Pod::Project]
16
+ # The `Pods/Pods.xcodeproj` to install the app host into.
17
+ #
18
+ attr_reader :project
19
+
20
+ # @return [Platform] the platform to use for this app host.
21
+ #
22
+ attr_reader :platform
23
+
24
+ # @return [Symbol] the test type this app host is going to be used for.
25
+ #
26
+ attr_reader :test_type
27
+
28
+ # Initialize a new instance
29
+ #
30
+ # @param [Sandbox] sandbox @see #sandbox
31
+ # @param [Pod::Project] project @see #project
32
+ # @param [Platform] platform @see #platform
33
+ # @param [Symbol] test_type @see #test_type
34
+ #
35
+ def initialize(sandbox, project, platform, test_type)
36
+ @sandbox = sandbox
37
+ @project = project
38
+ @platform = platform
39
+ @test_type = test_type
40
+ end
41
+
42
+ # @return [PBXNativeTarget] the app host native target that was installed.
43
+ #
44
+ def install!
45
+ name = app_host_label
46
+ platform_name = platform.name
47
+ app_host_target = Pod::Generator::AppTargetHelper.add_app_target(project, platform_name, deployment_target,
48
+ name)
49
+ app_host_target.build_configurations.each do |configuration|
50
+ configuration.build_settings['PRODUCT_NAME'] = name
51
+ configuration.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
52
+ configuration.build_settings['CODE_SIGN_IDENTITY'] = '' if platform == :osx
53
+ configuration.build_settings['CURRENT_PROJECT_VERSION'] = '1'
54
+ end
55
+ Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, name)
56
+ create_info_plist_file_with_sandbox(sandbox, app_host_info_plist_path, app_host_target, '1.0.0', platform, :appl)
57
+ project[name].new_file(app_host_info_plist_path)
58
+ app_host_target
59
+ end
60
+
61
+ private
62
+
63
+ # @return [Pathname] The absolute path of the Info.plist to use for an app host.
64
+ #
65
+ def app_host_info_plist_path
66
+ project.path.dirname.+("#{app_host_label}/#{app_host_label}-Info.plist")
67
+ end
68
+
69
+ # @return [String] The label of the app host label to use given the platform and test type.
70
+ #
71
+ def app_host_label
72
+ "AppHost-#{Platform.string_name(platform.symbolic_name)}-#{test_type.capitalize}-Tests"
73
+ end
74
+
75
+ # @return [String] The deployment target.
76
+ #
77
+ def deployment_target
78
+ platform.deployment_target.to_s
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,334 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Controller class responsible of installing the file references of the
6
+ # specifications in the Pods project.
7
+ #
8
+ class FileReferencesInstaller
9
+ # @return [Sandbox] The sandbox of the installation.
10
+ #
11
+ attr_reader :sandbox
12
+
13
+ # @return [Array<PodTarget>] The pod targets of the installation.
14
+ #
15
+ attr_reader :pod_targets
16
+
17
+ # @return [Project] The Pods project.
18
+ #
19
+ attr_reader :pods_project
20
+
21
+ # Initialize a new instance
22
+ #
23
+ # @param [Sandbox] sandbox @see #sandbox
24
+ # @param [Array<PodTarget>] pod_targets @see #pod_targets
25
+ # @param [Project] pods_project @see #pods_project
26
+ #
27
+ def initialize(sandbox, pod_targets, pods_project)
28
+ @sandbox = sandbox
29
+ @pod_targets = pod_targets
30
+ @pods_project = pods_project
31
+ end
32
+
33
+ # Installs the file references.
34
+ #
35
+ # @return [void]
36
+ #
37
+ def install!
38
+ refresh_file_accessors
39
+ add_source_files_references
40
+ add_frameworks_bundles
41
+ add_vendored_libraries
42
+ add_resources
43
+ add_developer_files unless sandbox.development_pods.empty?
44
+ link_headers
45
+ end
46
+
47
+ #-----------------------------------------------------------------------#
48
+
49
+ private
50
+
51
+ # @!group Installation Steps
52
+
53
+ # Reads the file accessors contents from the file system.
54
+ #
55
+ # @note The contents of the file accessors are modified by the clean
56
+ # step of the #{PodSourceInstaller} and by the pre install hooks.
57
+ #
58
+ # @return [void]
59
+ #
60
+ def refresh_file_accessors
61
+ file_accessors.map(&:path_list).uniq.each(&:read_file_system)
62
+ end
63
+
64
+ # Adds the source files of the Pods to the Pods project.
65
+ #
66
+ # @note The source files are grouped by Pod and in turn by subspec
67
+ # (recursively).
68
+ #
69
+ # @return [void]
70
+ #
71
+ def add_source_files_references
72
+ UI.message '- Adding source files to Pods project' do
73
+ add_file_accessors_paths_to_pods_group(:source_files, nil, true)
74
+ end
75
+ end
76
+
77
+ # Adds the bundled frameworks to the Pods project
78
+ #
79
+ # @return [void]
80
+ #
81
+ def add_frameworks_bundles
82
+ UI.message '- Adding frameworks to Pods project' do
83
+ add_file_accessors_paths_to_pods_group(:vendored_frameworks, :frameworks)
84
+ end
85
+ end
86
+
87
+ # Adds the bundled libraries to the Pods project
88
+ #
89
+ # @return [void]
90
+ #
91
+ def add_vendored_libraries
92
+ UI.message '- Adding libraries to Pods project' do
93
+ add_file_accessors_paths_to_pods_group(:vendored_libraries, :frameworks)
94
+ end
95
+ end
96
+
97
+ # Adds the resources of the Pods to the Pods project.
98
+ #
99
+ # @note The source files are grouped by Pod and in turn by subspec
100
+ # (recursively) in the resources group.
101
+ #
102
+ # @return [void]
103
+ #
104
+ def add_resources
105
+ UI.message '- Adding resources to Pods project' do
106
+ add_file_accessors_paths_to_pods_group(:resources, :resources, true)
107
+ add_file_accessors_paths_to_pods_group(:resource_bundle_files, :resources, true)
108
+ end
109
+ end
110
+
111
+ def add_developer_files
112
+ UI.message '- Adding development pod helper files to Pods project' do
113
+ file_accessors.each do |file_accessor|
114
+ pod_name = file_accessor.spec.name
115
+ next unless sandbox.local?(pod_name)
116
+ root_name = Specification.root_name(pod_name)
117
+ paths = file_accessor.developer_files
118
+ next if paths.empty?
119
+ group = pods_project.group_for_spec(root_name, :developer)
120
+ paths.each do |path|
121
+ ref = pods_project.add_file_reference(path, group, false)
122
+ if path.extname == '.podspec'
123
+ pods_project.mark_ruby_file_ref(ref)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ # Creates the link to the headers of the Pod in the sandbox.
131
+ #
132
+ # @return [void]
133
+ #
134
+ def link_headers
135
+ UI.message '- Linking headers' do
136
+ pod_targets.each do |pod_target|
137
+ # When integrating Pod as frameworks, built Pods are built into
138
+ # frameworks, whose headers are included inside the built
139
+ # framework. Those headers do not need to be linked from the
140
+ # sandbox.
141
+ next if pod_target.requires_frameworks? && pod_target.should_build?
142
+
143
+ headers_sandbox = Pathname.new(pod_target.pod_name)
144
+ added_build_headers = false
145
+ added_public_headers = false
146
+
147
+ file_accessors = pod_target.file_accessors.reject { |fa| fa.spec.test_specification? }
148
+ file_accessors.each do |file_accessor|
149
+ # Private headers will always end up in Pods/Headers/Private/PodA/*.h
150
+ # This will allow for `""` imports to work.
151
+ header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
152
+ added_build_headers = true
153
+ pod_target.build_headers.add_files(namespaced_path, files)
154
+ end
155
+
156
+ # Public headers on the other hand will be added in Pods/Headers/Public/PodA/PodA/*.h
157
+ # The extra folder is intentional in order for `<>` imports to work.
158
+ header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files|
159
+ added_public_headers = true
160
+ sandbox.public_headers.add_files(namespaced_path, files)
161
+ end
162
+ end
163
+
164
+ pod_target.build_headers.add_search_path(headers_sandbox, pod_target.platform) if added_build_headers
165
+ sandbox.public_headers.add_search_path(headers_sandbox, pod_target.platform) if added_public_headers
166
+ end
167
+ end
168
+ end
169
+
170
+ #-----------------------------------------------------------------------#
171
+
172
+ private
173
+
174
+ # @!group Private Helpers
175
+
176
+ # @return [Array<Sandbox::FileAccessor>] The file accessors for all the
177
+ # specs platform combinations.
178
+ #
179
+ def file_accessors
180
+ @file_accessors ||= pod_targets.flat_map(&:file_accessors).compact
181
+ end
182
+
183
+ # Adds file references to the list of the paths returned by the file
184
+ # accessor with the given key to the given group of the Pods project.
185
+ #
186
+ # @param [Symbol] file_accessor_key
187
+ # The method of the file accessor which would return the list of
188
+ # the paths.
189
+ #
190
+ # @param [Symbol] group_key
191
+ # The key of the group of the Pods project.
192
+ #
193
+ # @param [Bool] reflect_file_system_structure_for_development
194
+ # Whether organizing a local pod's files in subgroups inside
195
+ # the pod's group is allowed.
196
+ #
197
+ # @return [void]
198
+ #
199
+ def add_file_accessors_paths_to_pods_group(file_accessor_key, group_key = nil, reflect_file_system_structure_for_development = false)
200
+ file_accessors.each do |file_accessor|
201
+ paths = file_accessor.send(file_accessor_key)
202
+ paths = allowable_project_paths(paths)
203
+ next if paths.empty?
204
+
205
+ pod_name = file_accessor.spec.name
206
+ local = sandbox.local?(pod_name)
207
+ base_path = local ? common_path(paths) : nil
208
+ group = pods_project.group_for_spec(pod_name, group_key)
209
+ paths.each do |path|
210
+ pods_project.add_file_reference(path, group, local && reflect_file_system_structure_for_development, base_path)
211
+ end
212
+ end
213
+ end
214
+
215
+ # Filters a list of paths down to those paths which can be added to
216
+ # the Xcode project. Some paths are intermediates and only their children
217
+ # should be added, while some paths are treated as bundles and their
218
+ # children should not be added directly.
219
+ #
220
+ # @param [Array<Pathname>] paths
221
+ # The paths to files or directories on disk.
222
+ #
223
+ # @return [Array<Pathname>] The paths which can be added to the Xcode project
224
+ #
225
+ def allowable_project_paths(paths)
226
+ lproj_paths = Set.new
227
+ lproj_paths_with_files = Set.new
228
+ allowable_paths = paths.select do |path|
229
+ path_str = path.to_s
230
+
231
+ # We add the directory for a Core Data model, but not the items in it.
232
+ next if path_str =~ /.*\.xcdatamodeld\/.+/i
233
+
234
+ # We add the directory for a Core Data migration mapping, but not the items in it.
235
+ next if path_str =~ /.*\.xcmappingmodel\/.+/i
236
+
237
+ # We add the directory for an asset catalog, but not the items in it.
238
+ next if path_str =~ /.*\.xcassets\/.+/i
239
+
240
+ if path_str =~ /\.lproj(\/|$)/i
241
+ # If the element is an .lproj directory then save it and potentially
242
+ # add it later if we don't find any contained items.
243
+ if path_str =~ /\.lproj$/i && path.directory?
244
+ lproj_paths << path
245
+ next
246
+ end
247
+
248
+ # Collect the paths for the .lproj directories that contain files.
249
+ lproj_path = /(^.*\.lproj)\/.*/i.match(path_str)[1]
250
+ lproj_paths_with_files << Pathname(lproj_path)
251
+
252
+ # Directories nested within an .lproj directory are added as file
253
+ # system references so their contained items are not added directly.
254
+ next if path.dirname.dirname == lproj_path
255
+ end
256
+
257
+ true
258
+ end
259
+
260
+ # Only add the path for the .lproj directories that do not have anything
261
+ # within them added as well. This generally happens if the glob within the
262
+ # resources directory was not a recursive glob.
263
+ allowable_paths + lproj_paths.subtract(lproj_paths_with_files).to_a
264
+ end
265
+
266
+ # Returns a Pathname of the nearest parent from which all the given paths descend.
267
+ # Converts each Pathname to a list of path components and finds the longest common prefix
268
+ #
269
+ # @param [Array<Pathname>] paths
270
+ # The paths to files or directories on disk. Must be absolute paths
271
+ #
272
+ # @return [Pathname] Pathname of the nearest parent shared by paths, or nil if none exists
273
+ #
274
+ def common_path(paths)
275
+ return nil if paths.empty?
276
+ strs = paths.map do |path|
277
+ unless path.absolute?
278
+ raise ArgumentError, "Paths must be absolute #{path}"
279
+ end
280
+ path.dirname.to_s
281
+ end
282
+ min, max = strs.minmax
283
+ min = min.split('/')
284
+ max = max.split('/')
285
+ idx = min.size.times { |i| break i if min[i] != max[i] }
286
+ result = Pathname.new(min[0...idx].join('/'))
287
+ # Don't consider "/" a common path
288
+ return result unless result.to_s == '' || result.to_s == '/'
289
+ end
290
+
291
+ # Computes the destination sub-directory in the sandbox
292
+ #
293
+ # @param [Pathname] headers_sandbox
294
+ # The sandbox where the header links should be stored for this
295
+ # Pod.
296
+ #
297
+ # @param [Sandbox::FileAccessor] file_accessor
298
+ # The consumer file accessor for which the headers need to be
299
+ # linked.
300
+ #
301
+ # @param [Array<Pathname>] headers
302
+ # The absolute paths of the headers which need to be mapped.
303
+ #
304
+ # @return [Hash{Pathname => Array<Pathname>}] A hash containing the
305
+ # headers folders as the keys and the absolute paths of the
306
+ # header files as the values.
307
+ #
308
+ def header_mappings(headers_sandbox, file_accessor, headers)
309
+ consumer = file_accessor.spec_consumer
310
+ header_mappings_dir = consumer.header_mappings_dir
311
+ dir = headers_sandbox
312
+ dir += consumer.header_dir if consumer.header_dir
313
+
314
+ mappings = {}
315
+ headers.each do |header|
316
+ next if header.to_s.include?('.framework/')
317
+
318
+ sub_dir = dir
319
+ if header_mappings_dir
320
+ relative_path = header.relative_path_from(file_accessor.path_list.root + header_mappings_dir)
321
+ sub_dir += relative_path.dirname
322
+ end
323
+ mappings[sub_dir] ||= []
324
+ mappings[sub_dir] << header
325
+ end
326
+ mappings
327
+ end
328
+
329
+ #-----------------------------------------------------------------------#
330
+ end
331
+ end
332
+ end
333
+ end
334
+ end