cocoapods-square-stable 0.19.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1296 -0
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/bin/pod +16 -0
- data/bin/sandbox-pod +120 -0
- data/lib/cocoapods.rb +77 -0
- data/lib/cocoapods/command.rb +116 -0
- data/lib/cocoapods/command/help.rb +23 -0
- data/lib/cocoapods/command/inter_process_communication.rb +178 -0
- data/lib/cocoapods/command/list.rb +77 -0
- data/lib/cocoapods/command/outdated.rb +56 -0
- data/lib/cocoapods/command/podfile_info.rb +91 -0
- data/lib/cocoapods/command/project.rb +88 -0
- data/lib/cocoapods/command/push.rb +172 -0
- data/lib/cocoapods/command/repo.rb +145 -0
- data/lib/cocoapods/command/search.rb +61 -0
- data/lib/cocoapods/command/setup.rb +134 -0
- data/lib/cocoapods/command/spec.rb +590 -0
- data/lib/cocoapods/config.rb +231 -0
- data/lib/cocoapods/downloader.rb +59 -0
- data/lib/cocoapods/executable.rb +118 -0
- data/lib/cocoapods/external_sources.rb +363 -0
- data/lib/cocoapods/file_list.rb +36 -0
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +40 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +64 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +54 -0
- data/lib/cocoapods/generator/dummy_source.rb +22 -0
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_environment_header.rb +86 -0
- data/lib/cocoapods/generator/xcconfig.rb +185 -0
- data/lib/cocoapods/hooks/installer_representation.rb +134 -0
- data/lib/cocoapods/hooks/library_representation.rb +94 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +571 -0
- data/lib/cocoapods/installer/analyzer.rb +559 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +248 -0
- data/lib/cocoapods/installer/target_installer.rb +379 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +180 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +224 -0
- data/lib/cocoapods/library.rb +202 -0
- data/lib/cocoapods/open_uri.rb +24 -0
- data/lib/cocoapods/project.rb +209 -0
- data/lib/cocoapods/resolver.rb +212 -0
- data/lib/cocoapods/sandbox.rb +343 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +217 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +208 -0
- data/lib/cocoapods/sources_manager.rb +276 -0
- data/lib/cocoapods/user_interface.rb +304 -0
- data/lib/cocoapods/user_interface/error_report.rb +101 -0
- data/lib/cocoapods/validator.rb +350 -0
- metadata +238 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
module Pod
|
7
|
+
module UserInterface
|
8
|
+
module ErrorReport
|
9
|
+
class << self
|
10
|
+
def report(exception)
|
11
|
+
return <<-EOS
|
12
|
+
|
13
|
+
#{'――― MARKDOWN TEMPLATE ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
14
|
+
|
15
|
+
### Report
|
16
|
+
|
17
|
+
* What did you do?
|
18
|
+
|
19
|
+
* What did you expect to happen?
|
20
|
+
|
21
|
+
* What happened instead?
|
22
|
+
|
23
|
+
|
24
|
+
### Stack
|
25
|
+
|
26
|
+
```
|
27
|
+
CocoaPods : #{Pod::VERSION}
|
28
|
+
Ruby : #{RUBY_DESCRIPTION}
|
29
|
+
RubyGems : #{Gem::VERSION}
|
30
|
+
Host : #{host_information}
|
31
|
+
Xcode : #{xcode_information}
|
32
|
+
Ruby lib dir : #{RbConfig::CONFIG['libdir']}
|
33
|
+
Repositories : #{repo_information.join("\n ")}
|
34
|
+
```
|
35
|
+
#{markdown_podfile}
|
36
|
+
### Error
|
37
|
+
|
38
|
+
```
|
39
|
+
#{exception.class} - #{exception.message}
|
40
|
+
#{exception.backtrace.join("\n")}
|
41
|
+
```
|
42
|
+
|
43
|
+
#{'――― TEMPLATE END ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――'.reversed}
|
44
|
+
|
45
|
+
#{'[!] Oh no, an error occurred.'.red}
|
46
|
+
#{error_from_podfile(exception)}
|
47
|
+
#{'Search for existing github issues similar to yours:'.yellow}
|
48
|
+
#{"https://github.com/CocoaPods/CocoaPods/issues/search?q=#{CGI.escape(exception.message)}"}
|
49
|
+
|
50
|
+
#{'If none exists, create a ticket, with the template displayed above, on:'.yellow}
|
51
|
+
https://github.com/CocoaPods/CocoaPods/issues/new
|
52
|
+
|
53
|
+
Don't forget to anonymize any private data!
|
54
|
+
|
55
|
+
EOS
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def markdown_podfile
|
61
|
+
return '' unless Config.instance.podfile_path && Config.instance.podfile_path.exist?
|
62
|
+
<<-EOS
|
63
|
+
|
64
|
+
### Podfile
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
#{Config.instance.podfile_path.read.strip}
|
68
|
+
```
|
69
|
+
EOS
|
70
|
+
end
|
71
|
+
|
72
|
+
def error_from_podfile(error)
|
73
|
+
if error.message =~ /Podfile:(\d*)/
|
74
|
+
"\nIt appears to have originated from your Podfile at line #{$1}.\n"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def host_information
|
79
|
+
product, version, build =`sw_vers`.strip.split("\n").map { |line| line.split(":").last.strip }
|
80
|
+
"#{product} #{version} (#{build})"
|
81
|
+
end
|
82
|
+
|
83
|
+
def xcode_information
|
84
|
+
version, build = `xcodebuild -version`.strip.split("\n").map { |line| line.split(" ").last }
|
85
|
+
"#{version} (#{build})"
|
86
|
+
end
|
87
|
+
|
88
|
+
def repo_information
|
89
|
+
SourcesManager.all.map do |source|
|
90
|
+
repo = source.repo
|
91
|
+
Dir.chdir(repo) do
|
92
|
+
url = `git config --get remote.origin.url 2>&1`.strip
|
93
|
+
sha = `git rev-parse HEAD 2>&1`.strip
|
94
|
+
"#{repo.basename} - #{url} @ #{sha}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,350 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
# Validates a Specification.
|
4
|
+
#
|
5
|
+
# Extends the Linter from the Core to add additional which require the
|
6
|
+
# LocalPod and the Installer.
|
7
|
+
#
|
8
|
+
# In detail it checks that the file patterns defined by the user match
|
9
|
+
# actually do match at least a file and that the Pod builds, by installing
|
10
|
+
# it without integration and building the project with xcodebuild.
|
11
|
+
#
|
12
|
+
class Validator
|
13
|
+
|
14
|
+
include Config::Mixin
|
15
|
+
|
16
|
+
# @return [Specification::Linter] the linter instance from CocoaPods
|
17
|
+
# Core.
|
18
|
+
#
|
19
|
+
attr_reader :linter
|
20
|
+
|
21
|
+
# @param [Specification, Pathname, String] spec_or_path
|
22
|
+
# the Specification or the path of the `podspec` file to lint.
|
23
|
+
#
|
24
|
+
def initialize(spec_or_path)
|
25
|
+
@linter = Specification::Linter.new(spec_or_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
#-------------------------------------------------------------------------#
|
29
|
+
|
30
|
+
# @return [Specification] the specification to lint.
|
31
|
+
#
|
32
|
+
def spec
|
33
|
+
@linter.spec
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Pathname] the path of the `podspec` file where {#spec} is
|
37
|
+
# defined.
|
38
|
+
#
|
39
|
+
def file
|
40
|
+
@linter.file
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Sandbox::FileAccessor] the file accessor for the spec.
|
44
|
+
#
|
45
|
+
attr_accessor :file_accessor
|
46
|
+
|
47
|
+
#-------------------------------------------------------------------------#
|
48
|
+
|
49
|
+
# Lints the specification adding a {Specification::Linter::Result} for any
|
50
|
+
# failed check to the {#results} list.
|
51
|
+
#
|
52
|
+
# @note This method shows immediately which pod is being processed and
|
53
|
+
# overrides the printed line once the result is known.
|
54
|
+
#
|
55
|
+
# @return [Bool] whether the specification passed validation.
|
56
|
+
#
|
57
|
+
def validate
|
58
|
+
@results = []
|
59
|
+
UI.print " -> #{spec ? spec.name : file.basename}\r" unless config.silent?
|
60
|
+
$stdout.flush
|
61
|
+
|
62
|
+
perform_linting
|
63
|
+
perform_extensive_analysis if spec && !quick
|
64
|
+
|
65
|
+
UI.puts " -> ".send(result_color) << (spec ? spec.to_s : file.basename.to_s)
|
66
|
+
print_results
|
67
|
+
validated?
|
68
|
+
end
|
69
|
+
|
70
|
+
# Prints the result of the validation to the user.
|
71
|
+
#
|
72
|
+
# @return [void]
|
73
|
+
#
|
74
|
+
def print_results
|
75
|
+
results.each do |result|
|
76
|
+
if result.platforms == [:ios]
|
77
|
+
platform_message = "[iOS] "
|
78
|
+
elsif result.platforms == [:osx]
|
79
|
+
platform_message = "[OSX] "
|
80
|
+
end
|
81
|
+
|
82
|
+
case result.type
|
83
|
+
when :error then type = "ERROR"
|
84
|
+
when :warning then type = "WARN"
|
85
|
+
when :note then type = "NOTE"
|
86
|
+
else raise "#{result.type}" end
|
87
|
+
UI.puts " - #{type.ljust(5)} | #{platform_message}#{result.message}"
|
88
|
+
end
|
89
|
+
UI.puts
|
90
|
+
end
|
91
|
+
|
92
|
+
#-------------------------------------------------------------------------#
|
93
|
+
|
94
|
+
# @!group Configuration
|
95
|
+
|
96
|
+
# @return [Bool] whether the validation should skip the checks that
|
97
|
+
# requires the download of the library.
|
98
|
+
#
|
99
|
+
attr_accessor :quick
|
100
|
+
|
101
|
+
# @return [Bool] whether the linter should not clean up temporary files
|
102
|
+
# for inspection.
|
103
|
+
#
|
104
|
+
attr_accessor :no_clean
|
105
|
+
|
106
|
+
# @return [Bool] whether the validation should be performed against the root of
|
107
|
+
# the podspec instead to its original source.
|
108
|
+
#
|
109
|
+
# @note Uses the `:path` option of the Podfile.
|
110
|
+
#
|
111
|
+
attr_writer :local
|
112
|
+
def local?; @local; end
|
113
|
+
|
114
|
+
# @return [Bool] Whether the validator should fail only on errors or also
|
115
|
+
# on warnings.
|
116
|
+
#
|
117
|
+
attr_accessor :only_errors
|
118
|
+
|
119
|
+
#-------------------------------------------------------------------------#
|
120
|
+
|
121
|
+
# !@group Lint results
|
122
|
+
|
123
|
+
#
|
124
|
+
#
|
125
|
+
attr_reader :results
|
126
|
+
|
127
|
+
# @return [Boolean]
|
128
|
+
#
|
129
|
+
def validated?
|
130
|
+
result_type != :error && (result_type != :warning || only_errors)
|
131
|
+
end
|
132
|
+
|
133
|
+
# @return [Symbol]
|
134
|
+
#
|
135
|
+
def result_type
|
136
|
+
types = results.map(&:type).uniq
|
137
|
+
if types.include?(:error) then :error
|
138
|
+
elsif types.include?(:warning) then :warning
|
139
|
+
else :note end
|
140
|
+
end
|
141
|
+
|
142
|
+
# @return [Symbol]
|
143
|
+
#
|
144
|
+
def result_color
|
145
|
+
case result_type
|
146
|
+
when :error then :red
|
147
|
+
when :warning then :yellow
|
148
|
+
else :green end
|
149
|
+
end
|
150
|
+
|
151
|
+
# @return [Pathname] the temporary directory used by the linter.
|
152
|
+
#
|
153
|
+
def validation_dir
|
154
|
+
Pathname.new('/tmp/CocoaPods/Lint')
|
155
|
+
end
|
156
|
+
|
157
|
+
#-------------------------------------------------------------------------#
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
# !@group Lint steps
|
162
|
+
|
163
|
+
#
|
164
|
+
#
|
165
|
+
def perform_linting
|
166
|
+
linter.lint
|
167
|
+
@results.concat(linter.results)
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
#
|
172
|
+
def perform_extensive_analysis
|
173
|
+
spec.available_platforms.each do |platform|
|
174
|
+
UI.message "\n\n#{spec} - Analyzing on #{platform} platform.".green.reversed
|
175
|
+
@consumer = spec.consumer(platform)
|
176
|
+
setup_validation_environment
|
177
|
+
install_pod
|
178
|
+
build_pod
|
179
|
+
check_file_patterns
|
180
|
+
tear_down_validation_environment
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
attr_accessor :consumer
|
185
|
+
|
186
|
+
def setup_validation_environment
|
187
|
+
validation_dir.rmtree if validation_dir.exist?
|
188
|
+
validation_dir.mkpath
|
189
|
+
@original_config = Config.instance.clone
|
190
|
+
config.installation_root = validation_dir
|
191
|
+
config.sandbox_root = validation_dir + 'Pods'
|
192
|
+
config.silent = !config.verbose
|
193
|
+
config.integrate_targets = false
|
194
|
+
config.skip_repo_update = true
|
195
|
+
end
|
196
|
+
|
197
|
+
def tear_down_validation_environment
|
198
|
+
validation_dir.rmtree unless no_clean
|
199
|
+
Config.instance = @original_config
|
200
|
+
end
|
201
|
+
|
202
|
+
# It creates a podfile in memory and builds a library containing the pod
|
203
|
+
# for all available platforms with xcodebuild.
|
204
|
+
#
|
205
|
+
def install_pod
|
206
|
+
podfile = podfile_from_spec(consumer.platform_name, spec.deployment_target(consumer.platform_name))
|
207
|
+
sandbox = Sandbox.new(config.sandbox_root)
|
208
|
+
installer = Installer.new(sandbox, podfile)
|
209
|
+
installer.install!
|
210
|
+
|
211
|
+
file_accessors = installer.libraries.first.file_accessors
|
212
|
+
@file_accessor = file_accessors.find { |accessor| accessor.spec == spec }
|
213
|
+
config.silent
|
214
|
+
end
|
215
|
+
|
216
|
+
# Performs platform specific analysis. It requires to download the source
|
217
|
+
# at each iteration
|
218
|
+
#
|
219
|
+
# @note Xcode warnings are treaded as notes because the spec maintainer
|
220
|
+
# might not be the author of the library
|
221
|
+
#
|
222
|
+
# @return [void]
|
223
|
+
#
|
224
|
+
def build_pod
|
225
|
+
if `which xcodebuild`.strip.empty?
|
226
|
+
UI.warn "Skipping compilation with `xcodebuild' because it can't be found.\n".yellow
|
227
|
+
else
|
228
|
+
UI.message "\nBuilding with xcodebuild.\n".yellow do
|
229
|
+
output = Dir.chdir(config.sandbox_root) { xcodebuild }
|
230
|
+
UI.puts output
|
231
|
+
parsed_output = parse_xcodebuild_output(output)
|
232
|
+
parsed_output.each do |message|
|
233
|
+
if message.include?('error: ')
|
234
|
+
error "[xcodebuild] #{message}"
|
235
|
+
else
|
236
|
+
note "[xcodebuild] #{message}"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# It checks that every file pattern specified in a spec yields
|
244
|
+
# at least one file. It requires the pods to be already present
|
245
|
+
# in the current working directory under Pods/spec.name.
|
246
|
+
#
|
247
|
+
# @return [void]
|
248
|
+
#
|
249
|
+
def check_file_patterns
|
250
|
+
[:source_files, :resources, :preserve_paths].each do |attr_name|
|
251
|
+
# file_attr = Specification::DSL.attributes.values.find{|attr| attr.name == attr_name }
|
252
|
+
if !file_accessor.spec_consumer.send(attr_name).empty? && file_accessor.send(attr_name).empty?
|
253
|
+
error "The `#{attr_name}` pattern did not match any file."
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
unless file_accessor.license || spec.license && ( spec.license[:type] == 'Public Domain' || spec.license[:text] )
|
258
|
+
warning "Unable to find a license file"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
#-------------------------------------------------------------------------#
|
263
|
+
|
264
|
+
private
|
265
|
+
|
266
|
+
# !@group Result Helpers
|
267
|
+
|
268
|
+
def error(message)
|
269
|
+
add_result(:error, message)
|
270
|
+
end
|
271
|
+
|
272
|
+
def warning(message)
|
273
|
+
add_result(:warning, message)
|
274
|
+
end
|
275
|
+
|
276
|
+
def note(message)
|
277
|
+
add_result(:note, message)
|
278
|
+
end
|
279
|
+
|
280
|
+
def add_result(type, message)
|
281
|
+
result = results.find { |r| r.type == type && r.message == message }
|
282
|
+
unless result
|
283
|
+
result = Specification::Linter::Result.new(type, message)
|
284
|
+
results << result
|
285
|
+
end
|
286
|
+
result.platforms << consumer.platform_name if consumer
|
287
|
+
end
|
288
|
+
|
289
|
+
#-------------------------------------------------------------------------#
|
290
|
+
|
291
|
+
private
|
292
|
+
|
293
|
+
# !@group Helpers
|
294
|
+
|
295
|
+
# @return [Podfile] a podfile that requires the specification on the
|
296
|
+
# current platform.
|
297
|
+
#
|
298
|
+
# @note The generated podfile takes into account whether the linter is
|
299
|
+
# in local mode.
|
300
|
+
#
|
301
|
+
def podfile_from_spec(platform_name, deployment_target)
|
302
|
+
name = spec.name
|
303
|
+
podspec = file.realpath
|
304
|
+
local = local?
|
305
|
+
podfile = Pod::Podfile.new do
|
306
|
+
platform(platform_name, deployment_target)
|
307
|
+
if (local)
|
308
|
+
pod name, :local => podspec.dirname.to_s
|
309
|
+
else
|
310
|
+
pod name, :podspec => podspec.to_s
|
311
|
+
end
|
312
|
+
end
|
313
|
+
podfile
|
314
|
+
end
|
315
|
+
|
316
|
+
# Parse the xcode build output to identify the lines which are relevant
|
317
|
+
# to the linter.
|
318
|
+
#
|
319
|
+
# @param [String] output the output generated by the xcodebuild tool.
|
320
|
+
#
|
321
|
+
# @note The indentation and the temporary path is stripped form the
|
322
|
+
# lines.
|
323
|
+
#
|
324
|
+
# @return [Array<String>] the lines that are relevant to the linter.
|
325
|
+
#
|
326
|
+
def parse_xcodebuild_output(output)
|
327
|
+
lines = output.split("\n")
|
328
|
+
selected_lines = lines.select do |l|
|
329
|
+
l.include?('error: ') &&
|
330
|
+
(l !~ /errors? generated\./) && (l !~ /error: \(null\)/) ||
|
331
|
+
l.include?('warning: ') && (l !~ /warnings? generated\./) ||
|
332
|
+
l.include?('note: ') && (l !~ /expanded from macro/)
|
333
|
+
end
|
334
|
+
selected_lines.map do |l|
|
335
|
+
new = l.gsub(/\/tmp\/CocoaPods\/Lint\/Pods\//,'')
|
336
|
+
new.gsub!(/^ */,' ')
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# @return [String] Executes xcodebuild in the current working directory and
|
341
|
+
# returns its output (bot STDOUT and STDERR).
|
342
|
+
#
|
343
|
+
def xcodebuild
|
344
|
+
`xcodebuild clean build 2>&1`
|
345
|
+
end
|
346
|
+
|
347
|
+
#-------------------------------------------------------------------------#
|
348
|
+
|
349
|
+
end
|
350
|
+
end
|