xcocoapods 1.5.3

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