cocoapods-square-stable 0.19.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.
- 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
|