cocoapods 0.35.0 → 0.36.0.beta.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +185 -6
- data/README.md +1 -1
- data/lib/cocoapods.rb +4 -0
- data/lib/cocoapods/command.rb +2 -2
- data/lib/cocoapods/command/inter_process_communication.rb +1 -1
- data/lib/cocoapods/command/lib.rb +3 -0
- data/lib/cocoapods/command/list.rb +0 -35
- data/lib/cocoapods/command/search.rb +1 -2
- data/lib/cocoapods/command/spec.rb +6 -3
- data/lib/cocoapods/config.rb +1 -20
- data/lib/cocoapods/external_sources/abstract_external_source.rb +4 -0
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/embed_frameworks_script.rb +107 -0
- data/lib/cocoapods/generator/header.rb +13 -1
- data/lib/cocoapods/generator/info_plist_file.rb +84 -0
- data/lib/cocoapods/generator/module_map.rb +49 -0
- data/lib/cocoapods/generator/umbrella_header.rb +44 -0
- data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +69 -23
- data/lib/cocoapods/generator/xcconfig/private_pod_xcconfig.rb +12 -0
- data/lib/cocoapods/generator/xcconfig/public_pod_xcconfig.rb +1 -9
- data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +79 -1
- data/lib/cocoapods/hooks_manager.rb +75 -13
- data/lib/cocoapods/installer.rb +59 -2
- data/lib/cocoapods/installer/analyzer.rb +115 -38
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +6 -1
- data/lib/cocoapods/installer/file_references_installer.rb +11 -5
- data/lib/cocoapods/installer/migrator.rb +9 -0
- data/lib/cocoapods/installer/target_installer.rb +89 -5
- data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +49 -5
- data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +57 -9
- data/lib/cocoapods/installer/user_project_integrator.rb +3 -2
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +67 -6
- data/lib/cocoapods/project.rb +18 -2
- data/lib/cocoapods/resolver.rb +2 -2
- data/lib/cocoapods/sandbox/file_accessor.rb +23 -3
- data/lib/cocoapods/sandbox/headers_store.rb +4 -0
- data/lib/cocoapods/sources_manager.rb +5 -1
- data/lib/cocoapods/target.rb +117 -1
- data/lib/cocoapods/target/aggregate_target.rb +46 -4
- data/lib/cocoapods/target/pod_target.rb +39 -1
- data/lib/cocoapods/user_interface.rb +16 -21
- data/lib/cocoapods/user_interface/error_report.rb +2 -2
- data/lib/cocoapods/validator.rb +68 -23
- metadata +23 -19
data/lib/cocoapods/target.rb
CHANGED
@@ -15,18 +15,65 @@ module Pod
|
|
15
15
|
#
|
16
16
|
attr_reader :sandbox
|
17
17
|
|
18
|
+
# @return [Boolean] Whether the target needs to be implemented as a framework.
|
19
|
+
# Computed by analyzer.
|
20
|
+
#
|
21
|
+
attr_accessor :host_requires_frameworks
|
22
|
+
alias_method :host_requires_frameworks?, :host_requires_frameworks
|
23
|
+
|
18
24
|
# @return [String] the name of the library.
|
19
25
|
#
|
20
26
|
def name
|
21
27
|
label
|
22
28
|
end
|
23
29
|
|
24
|
-
# @return [String] the name of the
|
30
|
+
# @return [String] the name of the product.
|
25
31
|
#
|
26
32
|
def product_name
|
33
|
+
if requires_frameworks?
|
34
|
+
framework_name
|
35
|
+
else
|
36
|
+
static_library_name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String] the name of the product excluding the file extension or
|
41
|
+
# a product type specific prefix, depends on #requires_frameworks?
|
42
|
+
# and #product_module_name or #label.
|
43
|
+
#
|
44
|
+
def product_basename
|
45
|
+
if requires_frameworks?
|
46
|
+
product_module_name
|
47
|
+
else
|
48
|
+
label
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String] the name of the framework, depends on #label.
|
53
|
+
#
|
54
|
+
# @note This may not depend on #requires_frameworks? indirectly as it is
|
55
|
+
# used for migration.
|
56
|
+
#
|
57
|
+
def framework_name
|
58
|
+
"#{product_module_name}.framework"
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [String] the name of the library, depends on #label.
|
62
|
+
#
|
63
|
+
# @note This may not depend on #requires_frameworks? indirectly as it is
|
64
|
+
# used for migration.
|
65
|
+
#
|
66
|
+
def static_library_name
|
27
67
|
"lib#{label}.a"
|
28
68
|
end
|
29
69
|
|
70
|
+
# @return [Symbol] either :framework or :static_library, depends on
|
71
|
+
# #requires_frameworks?.
|
72
|
+
#
|
73
|
+
def product_type
|
74
|
+
requires_frameworks? ? :framework : :static_library
|
75
|
+
end
|
76
|
+
|
30
77
|
# @return [String] the XCConfig namespaced prefix.
|
31
78
|
#
|
32
79
|
def xcconfig_prefix
|
@@ -41,6 +88,20 @@ module Pod
|
|
41
88
|
|
42
89
|
#-------------------------------------------------------------------------#
|
43
90
|
|
91
|
+
# @return [Boolean] whether the generated target needs to be implemented
|
92
|
+
# as a framework
|
93
|
+
#
|
94
|
+
# @note This applies either if Swift was used by the host, which was checked
|
95
|
+
# eagerly by the analyzer before, or in the given target or its
|
96
|
+
# dependents, which can only be checked after the specs were been
|
97
|
+
# fetched.
|
98
|
+
#
|
99
|
+
def requires_frameworks?
|
100
|
+
host_requires_frameworks? || uses_swift?
|
101
|
+
end
|
102
|
+
|
103
|
+
#-------------------------------------------------------------------------#
|
104
|
+
|
44
105
|
# @!group Information storage
|
45
106
|
|
46
107
|
# @return [Hash{String=>Symbol}] A hash representing the user build
|
@@ -95,6 +156,22 @@ module Pod
|
|
95
156
|
support_files_dir + "#{label}-Private.xcconfig"
|
96
157
|
end
|
97
158
|
|
159
|
+
# @return [Pathname] the absolute path of the header file which contains
|
160
|
+
# the exported foundation constants with framework version
|
161
|
+
# information and all headers, which should been exported in the
|
162
|
+
# module map.
|
163
|
+
#
|
164
|
+
def umbrella_header_path
|
165
|
+
support_files_dir + "#{label}-umbrella.h"
|
166
|
+
end
|
167
|
+
|
168
|
+
# @return [Pathname] the absolute path of the LLVM module map file that
|
169
|
+
# defines the module structure for the compiler.
|
170
|
+
#
|
171
|
+
def module_map_path
|
172
|
+
support_files_dir + "#{label}.modulemap"
|
173
|
+
end
|
174
|
+
|
98
175
|
# @return [Pathname] the absolute path of the header file which contains
|
99
176
|
# the information about the installed pods.
|
100
177
|
#
|
@@ -115,12 +192,51 @@ module Pod
|
|
115
192
|
support_files_dir + "#{label}.bridgesupport"
|
116
193
|
end
|
117
194
|
|
195
|
+
# @return [Pathname] the absolute path of the Info.plist file.
|
196
|
+
#
|
197
|
+
def info_plist_path
|
198
|
+
support_files_dir + "Info.plist"
|
199
|
+
end
|
200
|
+
|
118
201
|
# @return [Pathname] the path of the dummy source generated by CocoaPods
|
119
202
|
#
|
120
203
|
def dummy_source_path
|
121
204
|
support_files_dir + "#{label}-dummy.m"
|
122
205
|
end
|
123
206
|
|
207
|
+
# @return [String] The configuration build dir, if the target is integrated
|
208
|
+
# as framework.
|
209
|
+
#
|
210
|
+
# @note Namespace the pod target product with its target definition name.
|
211
|
+
# Pod target products are named after their specs. The namespacing
|
212
|
+
# cannot directly happen in the product name itself, because this
|
213
|
+
# must be equal to the module name and this will be used in source
|
214
|
+
# code, which should stay agnostic over the dependency manager.
|
215
|
+
# We need namespacing at all because multiple targets can exist for
|
216
|
+
# the same podspec and their products should not collide. This
|
217
|
+
# happens when multiple user targets require the same pod, because
|
218
|
+
# they could require different sets of subspecs.
|
219
|
+
#
|
220
|
+
def configuration_build_dir
|
221
|
+
"$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/#{target_definition.label}"
|
222
|
+
end
|
223
|
+
|
124
224
|
#-------------------------------------------------------------------------#
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
# Transforms the given string into a valid +identifier+ after C99ext
|
229
|
+
# standard, so that it can be used in source code where escaping of
|
230
|
+
# ambiguous characters is not applicable.
|
231
|
+
#
|
232
|
+
# @param [String] name
|
233
|
+
# any name, which may contain leading numbers, spaces or invalid
|
234
|
+
# characters.
|
235
|
+
#
|
236
|
+
# @return [String]
|
237
|
+
#
|
238
|
+
def c99ext_identifier(name)
|
239
|
+
name.gsub(/^([0-9])/, '_\1').gsub(/[^a-zA-Z0-9_]/, '_')
|
240
|
+
end
|
125
241
|
end
|
126
242
|
end
|
@@ -20,6 +20,14 @@ module Pod
|
|
20
20
|
target_definition.label.to_s
|
21
21
|
end
|
22
22
|
|
23
|
+
# @return [String] the name to use for the source code module constructed
|
24
|
+
# for this target, and which will be used to import the module in
|
25
|
+
# implementation source files.
|
26
|
+
#
|
27
|
+
def product_module_name
|
28
|
+
c99ext_identifier(label)
|
29
|
+
end
|
30
|
+
|
23
31
|
# @return [Pathname] the folder where the client is stored used for
|
24
32
|
# computing the relative paths. If integrating it should be the
|
25
33
|
# folder where the user project is stored, otherwise it should
|
@@ -71,21 +79,32 @@ module Pod
|
|
71
79
|
#
|
72
80
|
attr_accessor :pod_targets
|
73
81
|
|
82
|
+
# @param [String] build_configuration The build configuration for which the
|
83
|
+
# the pod targets should be returned.
|
84
|
+
#
|
85
|
+
# @return [Array<PodTarget>] the pod targets for the given build
|
86
|
+
# configuration.
|
87
|
+
#
|
88
|
+
def pod_targets_for_build_configuration(build_configuration)
|
89
|
+
pod_targets.select do |pod_target|
|
90
|
+
pod_target.include_in_build_config?(build_configuration)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
74
94
|
# @return [Array<Specification>] The specifications used by this aggregate target.
|
75
95
|
#
|
76
96
|
def specs
|
77
97
|
pod_targets.map(&:specs).flatten
|
78
98
|
end
|
79
99
|
|
80
|
-
# @return [Hash{Symbol => Array<
|
100
|
+
# @return [Hash{Symbol => Array<Specification>}] The pod targets for each
|
81
101
|
# build configuration.
|
82
102
|
#
|
83
103
|
def specs_by_build_configuration
|
84
104
|
result = {}
|
85
105
|
user_build_configurations.keys.each do |build_configuration|
|
86
|
-
result[build_configuration] =
|
87
|
-
|
88
|
-
end.map(&:specs).flatten
|
106
|
+
result[build_configuration] = pod_targets_for_build_configuration(build_configuration).
|
107
|
+
flat_map(&:specs)
|
89
108
|
end
|
90
109
|
result
|
91
110
|
end
|
@@ -96,6 +115,16 @@ module Pod
|
|
96
115
|
specs.map { |spec| spec.consumer(platform) }
|
97
116
|
end
|
98
117
|
|
118
|
+
# @return [Boolean] Whether the target uses Swift code
|
119
|
+
#
|
120
|
+
def uses_swift?
|
121
|
+
pod_targets.any?(&:uses_swift?)
|
122
|
+
end
|
123
|
+
|
124
|
+
#-------------------------------------------------------------------------#
|
125
|
+
|
126
|
+
# @!group Support files
|
127
|
+
|
99
128
|
# @return [Pathname] The absolute path of acknowledgements file.
|
100
129
|
#
|
101
130
|
# @note The acknowledgements generators add the extension according to
|
@@ -111,6 +140,12 @@ module Pod
|
|
111
140
|
support_files_dir + "#{label}-resources.sh"
|
112
141
|
end
|
113
142
|
|
143
|
+
# @return [Pathname] The absolute path of the embed frameworks script.
|
144
|
+
#
|
145
|
+
def embed_frameworks_script_path
|
146
|
+
support_files_dir + "#{label}-frameworks.sh"
|
147
|
+
end
|
148
|
+
|
114
149
|
# @return [String] The xcconfig path of the root from the `$(SRCROOT)`
|
115
150
|
# variable of the user's project.
|
116
151
|
#
|
@@ -133,6 +168,13 @@ module Pod
|
|
133
168
|
"${SRCROOT}/#{relative_to_srcroot(copy_resources_script_path)}"
|
134
169
|
end
|
135
170
|
|
171
|
+
# @return [String] The path of the embed frameworks relative to the
|
172
|
+
# root of the user project.
|
173
|
+
#
|
174
|
+
def embed_frameworks_script_relative_path
|
175
|
+
"${SRCROOT}/#{relative_to_srcroot(embed_frameworks_script_path)}"
|
176
|
+
end
|
177
|
+
|
136
178
|
private
|
137
179
|
|
138
180
|
# @!group Private Helpers
|
@@ -19,8 +19,9 @@ module Pod
|
|
19
19
|
@specs = specs
|
20
20
|
@target_definition = target_definition
|
21
21
|
@sandbox = sandbox
|
22
|
-
@build_headers = Sandbox::HeadersStore.new(sandbox, '
|
22
|
+
@build_headers = Sandbox::HeadersStore.new(sandbox, 'Private')
|
23
23
|
@file_accessors = []
|
24
|
+
@resource_bundle_targets = []
|
24
25
|
end
|
25
26
|
|
26
27
|
# @return [String] the label for the target.
|
@@ -29,11 +30,31 @@ module Pod
|
|
29
30
|
"#{target_definition.label}-#{root_spec.name}"
|
30
31
|
end
|
31
32
|
|
33
|
+
# @return [String] The name to use for the source code module constructed
|
34
|
+
# for this target, and which will be used to import the module in
|
35
|
+
# implementation source files.
|
36
|
+
#
|
37
|
+
def product_module_name
|
38
|
+
root_spec.module_name
|
39
|
+
end
|
40
|
+
|
32
41
|
# @return [Array<Sandbox::FileAccessor>] the file accessors for the
|
33
42
|
# specifications of this target.
|
34
43
|
#
|
35
44
|
attr_accessor :file_accessors
|
36
45
|
|
46
|
+
# @return [Array<PBXTarget>] the resource bundle targets belonging
|
47
|
+
# to this target.
|
48
|
+
attr_reader :resource_bundle_targets
|
49
|
+
|
50
|
+
# @return [Bool] Whether or not this target should be build.
|
51
|
+
#
|
52
|
+
# A target should not be build if it has no source files.
|
53
|
+
#
|
54
|
+
def should_build?
|
55
|
+
!file_accessors.flat_map(&:source_files).empty?
|
56
|
+
end
|
57
|
+
|
37
58
|
# @return [Array<Specification::Consumer>] the specification consumers for
|
38
59
|
# the target.
|
39
60
|
#
|
@@ -41,6 +62,14 @@ module Pod
|
|
41
62
|
specs.map { |spec| spec.consumer(platform) }
|
42
63
|
end
|
43
64
|
|
65
|
+
# @return [Boolean] Whether the target uses Swift code
|
66
|
+
#
|
67
|
+
def uses_swift?
|
68
|
+
file_accessors.any? do |file_accessor|
|
69
|
+
file_accessor.source_files.any? { |sf| sf.extname == ".swift" }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
44
73
|
# @return [Specification] The root specification for the target.
|
45
74
|
#
|
46
75
|
def root_spec
|
@@ -53,6 +82,15 @@ module Pod
|
|
53
82
|
root_spec.name
|
54
83
|
end
|
55
84
|
|
85
|
+
# @param [String] bundle_name
|
86
|
+
# The name of the bundle product, which is given by the +spec+.
|
87
|
+
#
|
88
|
+
# @return [String] The derived name of the resource bundle target.
|
89
|
+
#
|
90
|
+
def resources_bundle_target_label(bundle_name)
|
91
|
+
"#{label}-#{bundle_name}"
|
92
|
+
end
|
93
|
+
|
56
94
|
# @return [Array<String>] The names of the Pods on which this target
|
57
95
|
# depends.
|
58
96
|
#
|
@@ -156,11 +156,11 @@ module Pod
|
|
156
156
|
|
157
157
|
# Prints the textual representation of a given set.
|
158
158
|
#
|
159
|
-
def pod(set, mode = :normal
|
159
|
+
def pod(set, mode = :normal)
|
160
160
|
if mode == :name_and_version
|
161
161
|
puts_indented "#{set.name} #{set.versions.first.version}"
|
162
162
|
else
|
163
|
-
pod = Specification::Set::Presenter.new(set
|
163
|
+
pod = Specification::Set::Presenter.new(set)
|
164
164
|
title = "\n-> #{pod.name} (#{pod.version})"
|
165
165
|
if pod.spec.deprecated?
|
166
166
|
title += " #{pod.deprecation_description}"
|
@@ -174,17 +174,16 @@ module Pod
|
|
174
174
|
puts_indented "pod '#{pod.name}', '~> #{pod.version}'"
|
175
175
|
labeled('Homepage', pod.homepage)
|
176
176
|
labeled('Source', pod.source_url)
|
177
|
-
labeled('Versions', pod.
|
177
|
+
labeled('Versions', pod.versions_by_source)
|
178
178
|
if mode == :stats
|
179
|
-
labeled('Pushed', pod.github_last_activity)
|
180
179
|
labeled('Authors', pod.authors) if pod.authors =~ /,/
|
181
180
|
labeled('Author', pod.authors) if pod.authors !~ /,/
|
182
181
|
labeled('License', pod.license)
|
183
182
|
labeled('Platform', pod.platform)
|
184
|
-
labeled('
|
183
|
+
labeled('Stars', pod.github_stargazers)
|
185
184
|
labeled('Forks', pod.github_forks)
|
186
185
|
end
|
187
|
-
labeled('
|
186
|
+
labeled('Subspecs', pod.subspecs)
|
188
187
|
end
|
189
188
|
end
|
190
189
|
end
|
@@ -193,20 +192,16 @@ module Pod
|
|
193
192
|
#
|
194
193
|
def labeled(label, value, justification = 12)
|
195
194
|
if value
|
196
|
-
title = "- #{label}:"
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
wrap_string(title + "#{value}", self.indentation_level)
|
206
|
-
end + "\n"
|
195
|
+
title = "- #{label}:"
|
196
|
+
if value.is_a?(Array)
|
197
|
+
lines = [wrap_string(title, self.indentation_level)]
|
198
|
+
value.each do |v|
|
199
|
+
lines << wrap_string("- #{v}", self.indentation_level + 2)
|
200
|
+
end
|
201
|
+
puts lines.join("\n")
|
202
|
+
else
|
203
|
+
puts wrap_string(title.ljust(justification) + "#{value}", self.indentation_level)
|
207
204
|
end
|
208
|
-
puts output
|
209
|
-
output
|
210
205
|
end
|
211
206
|
end
|
212
207
|
|
@@ -291,10 +286,10 @@ module Pod
|
|
291
286
|
#
|
292
287
|
def wrap_string(string, indent = 0)
|
293
288
|
if disable_wrap
|
294
|
-
string
|
289
|
+
(' ' * indent) + string
|
295
290
|
else
|
296
291
|
first_space = ' ' * indent
|
297
|
-
indented = CLAide::
|
292
|
+
indented = CLAide::Command::Banner::TextWrapper.wrap_with_indent(string, indent, 9999)
|
298
293
|
first_space + indented
|
299
294
|
end
|
300
295
|
end
|
@@ -51,7 +51,7 @@ Repositories : #{repo_information.join("\n ")}
|
|
51
51
|
|
52
52
|
#{'[!] Oh no, an error occurred.'.red}
|
53
53
|
#{error_from_podfile(exception)}
|
54
|
-
#{'Search for existing
|
54
|
+
#{'Search for existing GitHub issues similar to yours:'.yellow}
|
55
55
|
#{issues_url(exception)}
|
56
56
|
|
57
57
|
#{'If none exists, create a ticket, with the template displayed above, on:'.yellow}
|
@@ -114,7 +114,7 @@ EOS
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def installed_plugins
|
117
|
-
CLAide::Command::
|
117
|
+
CLAide::Command::PluginManager.specifications.
|
118
118
|
reduce({}) { |hash, s| hash.tap { |h| h[s.name] = s.version.to_s } }
|
119
119
|
end
|
120
120
|
|
data/lib/cocoapods/validator.rb
CHANGED
@@ -143,6 +143,10 @@ module Pod
|
|
143
143
|
#
|
144
144
|
attr_accessor :no_subspecs
|
145
145
|
|
146
|
+
# @return [Bool] Whether frameworks should be used for the installation.
|
147
|
+
#
|
148
|
+
attr_accessor :use_frameworks
|
149
|
+
|
146
150
|
#-------------------------------------------------------------------------#
|
147
151
|
|
148
152
|
# !@group Lint results
|
@@ -233,9 +237,9 @@ module Pod
|
|
233
237
|
resp = Pod::HTTP.validate_url(url)
|
234
238
|
|
235
239
|
if !resp
|
236
|
-
warning "There was a problem validating the URL #{url}."
|
240
|
+
warning('url', "There was a problem validating the URL #{url}.")
|
237
241
|
elsif !resp.success?
|
238
|
-
warning "The URL (#{url}) is not reachable."
|
242
|
+
warning('url', "The URL (#{url}) is not reachable.")
|
239
243
|
end
|
240
244
|
|
241
245
|
resp
|
@@ -255,7 +259,7 @@ module Pod
|
|
255
259
|
spec.screenshots.compact.each do |screenshot|
|
256
260
|
request = validate_url(screenshot)
|
257
261
|
if request && !(request.headers['content-type'] && request.headers['content-type'].first =~ /image\/.*/i)
|
258
|
-
warning "The screenshot #{screenshot} is not a valid image."
|
262
|
+
warning('screenshot', "The screenshot #{screenshot} is not a valid image.")
|
259
263
|
end
|
260
264
|
end
|
261
265
|
end
|
@@ -298,7 +302,8 @@ module Pod
|
|
298
302
|
# for all available platforms with xcodebuild.
|
299
303
|
#
|
300
304
|
def install_pod
|
301
|
-
|
305
|
+
deployment_target = spec.subspec_by_name(subspec_name).deployment_target(consumer.platform_name)
|
306
|
+
podfile = podfile_from_spec(consumer.platform_name, deployment_target, use_frameworks)
|
302
307
|
sandbox = Sandbox.new(config.sandbox_root)
|
303
308
|
installer = Installer.new(sandbox, podfile)
|
304
309
|
installer.install!
|
@@ -340,15 +345,19 @@ module Pod
|
|
340
345
|
end
|
341
346
|
|
342
347
|
if message.include?('error: ')
|
343
|
-
error
|
348
|
+
error('xcodebuild', message)
|
344
349
|
else
|
345
|
-
note
|
350
|
+
note('xcodebuild', message)
|
346
351
|
end
|
347
352
|
end
|
348
353
|
end
|
349
354
|
end
|
350
355
|
end
|
351
356
|
|
357
|
+
FILE_PATTERNS = %i(source_files resources preserve_paths vendored_libraries
|
358
|
+
vendored_frameworks public_header_files preserve_paths
|
359
|
+
private_header_files resource_bundles).freeze
|
360
|
+
|
352
361
|
# It checks that every file pattern specified in a spec yields
|
353
362
|
# at least one file. It requires the pods to be already present
|
354
363
|
# in the current working directory under Pods/spec.name.
|
@@ -356,42 +365,66 @@ module Pod
|
|
356
365
|
# @return [void]
|
357
366
|
#
|
358
367
|
def check_file_patterns
|
359
|
-
|
360
|
-
#
|
368
|
+
FILE_PATTERNS.each do |attr_name|
|
369
|
+
if respond_to?("_validate_#{attr_name}", true)
|
370
|
+
send("_validate_#{attr_name}")
|
371
|
+
end
|
372
|
+
|
361
373
|
if !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty?
|
362
|
-
error "The `#{attr_name}` pattern did not match any file."
|
374
|
+
error('file patterns', "The `#{attr_name}` pattern did not match any file.")
|
363
375
|
end
|
364
376
|
end
|
365
377
|
|
366
378
|
if consumer.spec.root?
|
367
379
|
unless file_accessor.license || spec.license && (spec.license[:type] == 'Public Domain' || spec.license[:text])
|
368
|
-
warning 'Unable to find a license file'
|
380
|
+
warning('license', 'Unable to find a license file')
|
369
381
|
end
|
370
382
|
end
|
371
383
|
end
|
372
384
|
|
385
|
+
def _validate_private_header_files
|
386
|
+
_validate_header_files(:private_header_files)
|
387
|
+
end
|
388
|
+
|
389
|
+
def _validate_public_header_files
|
390
|
+
_validate_header_files(:public_header_files)
|
391
|
+
end
|
392
|
+
|
393
|
+
# Ensures that a list of header files only contains header files.
|
394
|
+
#
|
395
|
+
def _validate_header_files(attr_name)
|
396
|
+
non_header_files = file_accessor.send(attr_name).
|
397
|
+
select { |f| !Sandbox::FileAccessor::HEADER_EXTENSIONS.include?(f.extname) }.
|
398
|
+
map { |f| f.relative_path_from file_accessor.root }
|
399
|
+
unless non_header_files.empty?
|
400
|
+
error(attr_name, "The pattern matches non-header files (#{non_header_files.join(', ')}).")
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
373
404
|
#-------------------------------------------------------------------------#
|
374
405
|
|
375
406
|
private
|
376
407
|
|
377
408
|
# !@group Result Helpers
|
378
409
|
|
379
|
-
def error(message)
|
380
|
-
add_result(:error, message)
|
410
|
+
def error(attribute_name, message)
|
411
|
+
add_result(:error, attribute_name, message)
|
381
412
|
end
|
382
413
|
|
383
|
-
def warning(message)
|
384
|
-
add_result(:warning, message)
|
414
|
+
def warning(attribute_name, message)
|
415
|
+
add_result(:warning, attribute_name, message)
|
385
416
|
end
|
386
417
|
|
387
|
-
def note(message)
|
388
|
-
add_result(:note, message)
|
418
|
+
def note(attribute_name, message)
|
419
|
+
add_result(:note, attribute_name, message)
|
389
420
|
end
|
390
421
|
|
391
|
-
def add_result(type, message)
|
392
|
-
result = results.find
|
422
|
+
def add_result(type, attribute_name, message)
|
423
|
+
result = results.find do |r|
|
424
|
+
r.type == type && r.attribute_name && r.message == message
|
425
|
+
end
|
393
426
|
unless result
|
394
|
-
result = Result.new(type, message)
|
427
|
+
result = Result.new(type, attribute_name, message)
|
395
428
|
results << result
|
396
429
|
end
|
397
430
|
result.platforms << consumer.platform_name if consumer
|
@@ -401,8 +434,8 @@ module Pod
|
|
401
434
|
# Specialized Result to support subspecs aggregation
|
402
435
|
#
|
403
436
|
class Result < Specification::Linter::Results::Result
|
404
|
-
def initialize(type, message)
|
405
|
-
super(type, message)
|
437
|
+
def initialize(type, attribute_name, message)
|
438
|
+
super(type, attribute_name, message)
|
406
439
|
@subspecs = []
|
407
440
|
end
|
408
441
|
|
@@ -420,19 +453,31 @@ module Pod
|
|
420
453
|
#
|
421
454
|
attr_reader :source_urls
|
422
455
|
|
456
|
+
# @param [String] platform_name
|
457
|
+
# the name of the platform, which should be declared
|
458
|
+
# in the Podfile.
|
459
|
+
#
|
460
|
+
# @param [String] deployment_target
|
461
|
+
# the deployment target, which should be declared in
|
462
|
+
# the Podfile.
|
463
|
+
#
|
464
|
+
# @param [Bool] use_frameworks
|
465
|
+
# whether frameworks should be used for the installation
|
466
|
+
#
|
423
467
|
# @return [Podfile] a podfile that requires the specification on the
|
424
|
-
#
|
468
|
+
# current platform.
|
425
469
|
#
|
426
470
|
# @note The generated podfile takes into account whether the linter is
|
427
471
|
# in local mode.
|
428
472
|
#
|
429
|
-
def podfile_from_spec(platform_name, deployment_target)
|
473
|
+
def podfile_from_spec(platform_name, deployment_target, use_frameworks = nil)
|
430
474
|
name = subspec_name ? subspec_name : spec.name
|
431
475
|
podspec = file.realpath
|
432
476
|
local = local?
|
433
477
|
urls = source_urls
|
434
478
|
podfile = Pod::Podfile.new do
|
435
479
|
urls.each { |u| source(u) }
|
480
|
+
use_frameworks!(use_frameworks) unless use_frameworks.nil?
|
436
481
|
platform(platform_name, deployment_target)
|
437
482
|
if local
|
438
483
|
pod name, :path => podspec.dirname.to_s
|