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,16 @@
1
+ module Pod
2
+ module Downloader
3
+ # A response to a download request.
4
+ #
5
+ # @attr [Pathname] location
6
+ # the location where this downloaded pod is stored on disk.
7
+ #
8
+ # @attr [Specification] spec
9
+ # the specification that describes this downloaded pod.
10
+ #
11
+ # @attr [Hash<Symbol, String>] checkout_options
12
+ # the downloader parameters necessary to recreate this exact download.
13
+ #
14
+ Response = Struct.new(:location, :spec, :checkout_options)
15
+ end
16
+ end
@@ -0,0 +1,222 @@
1
+ module Pod
2
+ # Module which provides support for running executables.
3
+ #
4
+ # In a class it can be used as:
5
+ #
6
+ # extend Executable
7
+ # executable :git
8
+ #
9
+ # This will create two methods `git` and `git!` both accept a command but
10
+ # the later will raise on non successful executions. The methods return the
11
+ # output of the command.
12
+ #
13
+ module Executable
14
+ # Creates the methods for the executable with the given name.
15
+ #
16
+ # @param [Symbol] name
17
+ # the name of the executable.
18
+ #
19
+ # @return [void]
20
+ #
21
+ def executable(name)
22
+ define_method(name) do |*command|
23
+ Executable.execute_command(name, Array(command).flatten, false)
24
+ end
25
+
26
+ define_method(name.to_s + '!') do |*command|
27
+ Executable.execute_command(name, Array(command).flatten, true)
28
+ end
29
+ end
30
+
31
+ # Executes the given command displaying it if in verbose mode.
32
+ #
33
+ # @param [String] executable
34
+ # The binary to use.
35
+ #
36
+ # @param [Array<#to_s>] command
37
+ # The command to send to the binary.
38
+ #
39
+ # @param [Bool] raise_on_failure
40
+ # Whether it should raise if the command fails.
41
+ #
42
+ # @raise If the executable could not be located.
43
+ #
44
+ # @raise If the command fails and the `raise_on_failure` is set to true.
45
+ #
46
+ # @return [String] the output of the command (STDOUT and STDERR).
47
+ #
48
+ def self.execute_command(executable, command, raise_on_failure = true)
49
+ bin = which!(executable)
50
+
51
+ command = command.map(&:to_s)
52
+ full_command = "#{bin} #{command.join(' ')}"
53
+
54
+ if Config.instance.verbose?
55
+ UI.message("$ #{full_command}")
56
+ stdout = Indenter.new(STDOUT)
57
+ stderr = Indenter.new(STDERR)
58
+ else
59
+ stdout = Indenter.new
60
+ stderr = Indenter.new
61
+ end
62
+
63
+ status = popen3(bin, command, stdout, stderr)
64
+ stdout = stdout.join
65
+ stderr = stderr.join
66
+ output = stdout + stderr
67
+ unless status.success?
68
+ if raise_on_failure
69
+ raise Informative, "#{full_command}\n\n#{output}"
70
+ else
71
+ UI.message("[!] Failed: #{full_command}".red)
72
+ end
73
+ end
74
+
75
+ output
76
+ end
77
+
78
+ # Returns the absolute path to the binary with the given name on the current
79
+ # `PATH`, or `nil` if none is found.
80
+ #
81
+ # @param [String] program
82
+ # The name of the program being searched for.
83
+ #
84
+ # @return [String,Nil] The absolute path to the given program, or `nil` if
85
+ # it wasn't found in the current `PATH`.
86
+ #
87
+ def self.which(program)
88
+ program = program.to_s
89
+ paths = ENV.fetch('PATH') { '' }.split(File::PATH_SEPARATOR)
90
+ paths.unshift('./')
91
+ paths.uniq!
92
+ paths.each do |path|
93
+ bin = File.expand_path(program, path)
94
+ if File.file?(bin) && File.executable?(bin)
95
+ return bin
96
+ end
97
+ end
98
+ nil
99
+ end
100
+
101
+ # Returns the absolute path to the binary with the given name on the current
102
+ # `PATH`, or raises if none is found.
103
+ #
104
+ # @param [String] program
105
+ # The name of the program being searched for.
106
+ #
107
+ # @return [String] The absolute path to the given program.
108
+ #
109
+ def self.which!(program)
110
+ which(program).tap do |bin|
111
+ raise Informative, "Unable to locate the executable `#{program}`" unless bin
112
+ end
113
+ end
114
+
115
+ # Runs the given command, capturing the desired output.
116
+ #
117
+ # @param [String] bin
118
+ # The binary to use.
119
+ #
120
+ # @param [Array<#to_s>] command
121
+ # The command to send to the binary.
122
+ #
123
+ # @param [Symbol] capture
124
+ # Whether it should raise if the command fails.
125
+ #
126
+ # @raise If the executable could not be located.
127
+ #
128
+ # @return [(String, Process::Status)]
129
+ # The desired captured output from the command, and the status from
130
+ # running the command.
131
+ #
132
+ def self.capture_command(executable, command, capture: :merge)
133
+ bin = which!(executable)
134
+
135
+ require 'open3'
136
+ command = command.map(&:to_s)
137
+ case capture
138
+ when :merge then Open3.capture2e(bin, *command)
139
+ when :both then Open3.capture3(bin, *command)
140
+ when :out then Open3.capture3(bin, *command).values_at(0, -1)
141
+ when :err then Open3.capture3(bin, *command).drop(1)
142
+ when :none then Open3.capture3(bin, *command).last
143
+ end
144
+ end
145
+
146
+ private
147
+
148
+ def self.popen3(bin, command, stdout, stderr)
149
+ require 'open3'
150
+ Open3.popen3(bin, *command) do |i, o, e, t|
151
+ reader(o, stdout)
152
+ reader(e, stderr)
153
+ i.close
154
+
155
+ status = t.value
156
+
157
+ o.flush
158
+ e.flush
159
+ sleep(0.01)
160
+
161
+ status
162
+ end
163
+ end
164
+
165
+ def self.reader(input, output)
166
+ Thread.new do
167
+ buf = ''
168
+ begin
169
+ loop do
170
+ buf << input.readpartial(4096)
171
+ loop do
172
+ string, separator, buf = buf.partition(/[\r\n]/)
173
+ if separator.empty?
174
+ buf = string
175
+ break
176
+ end
177
+ output << (string << separator)
178
+ end
179
+ end
180
+ rescue EOFError
181
+ output << (buf << $/) unless buf.empty?
182
+ end
183
+ end
184
+ end
185
+
186
+ #-------------------------------------------------------------------------#
187
+
188
+ # Helper class that allows to write to an {IO} instance taking into account
189
+ # the UI indentation level.
190
+ #
191
+ class Indenter < ::Array
192
+ # @return [Fixnum] The indentation level of the UI.
193
+ #
194
+ attr_reader :indent
195
+
196
+ # @return [IO] the {IO} to which the output should be printed.
197
+ #
198
+ attr_reader :io
199
+
200
+ # Init a new Indenter
201
+ #
202
+ # @param [IO] io @see io
203
+ #
204
+ def initialize(io = nil)
205
+ @io = io
206
+ @indent = ' ' * UI.indentation_level
207
+ end
208
+
209
+ # Stores a portion of the output and prints it to the {IO} instance.
210
+ #
211
+ # @param [String] value
212
+ # the output to print.
213
+ #
214
+ # @return [void]
215
+ #
216
+ def <<(value)
217
+ super
218
+ io << "#{indent}#{value}" if io
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,57 @@
1
+ require 'cocoapods/external_sources/abstract_external_source'
2
+ require 'cocoapods/external_sources/downloader_source'
3
+ require 'cocoapods/external_sources/path_source'
4
+ require 'cocoapods/external_sources/podspec_source'
5
+
6
+ module Pod
7
+ # Provides support for initializing the correct concrete class of an external
8
+ # source.
9
+ #
10
+ module ExternalSources
11
+ # Instantiate a matching {AbstractExternalSource} for a given dependency.
12
+ #
13
+ # @param [Dependency] dependency
14
+ # the dependency
15
+ #
16
+ # @param [String] podfile_path
17
+ # @see AbstractExternalSource#podfile_path
18
+ #
19
+ # @param [Boolean] can_cache
20
+ # @see AbstractExternalSource#can_cache
21
+ #
22
+ # @return [AbstractExternalSource] an initialized instance of the concrete
23
+ # external source class associated with the option specified in the
24
+ # hash.
25
+ #
26
+ def self.from_dependency(dependency, podfile_path, can_cache)
27
+ from_params(dependency.external_source, dependency, podfile_path, can_cache)
28
+ end
29
+
30
+ def self.from_params(params, dependency, podfile_path, can_cache)
31
+ name = dependency.root_name
32
+ if klass = concrete_class_from_params(params)
33
+ klass.new(name, params, podfile_path, can_cache)
34
+ else
35
+ msg = "Unknown external source parameters for `#{name}`: `#{params}`"
36
+ raise Informative, msg
37
+ end
38
+ end
39
+
40
+ # Get the class to represent the defined source type of a dependency
41
+ #
42
+ # @param [Array<Symbol>] params
43
+ # the source params of the dependency
44
+ #
45
+ # @return [Class]
46
+ #
47
+ def self.concrete_class_from_params(params)
48
+ if params.key?(:podspec)
49
+ PodspecSource
50
+ elsif params.key?(:path)
51
+ PathSource
52
+ elsif Downloader.strategy_from_options(params)
53
+ DownloaderSource
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,205 @@
1
+ module Pod
2
+ module ExternalSources
3
+ # Abstract class that defines the common behaviour of external sources.
4
+ #
5
+ class AbstractExternalSource
6
+ # @return [String] the name of the Pod described by this external source.
7
+ #
8
+ attr_reader :name
9
+
10
+ # @return [Hash{Symbol => String}] the hash representation of the
11
+ # external source.
12
+ #
13
+ attr_reader :params
14
+
15
+ # @return [String] the path where the podfile is defined to resolve
16
+ # relative paths.
17
+ #
18
+ attr_reader :podfile_path
19
+
20
+ # @return [Boolean] Whether the source is allowed to touch the cache.
21
+ #
22
+ attr_reader :can_cache
23
+ alias_method :can_cache?, :can_cache
24
+
25
+ # Initialize a new instance
26
+ #
27
+ # @param [String] name @see #name
28
+ # @param [Hash] params @see #params
29
+ # @param [String] podfile_path @see #podfile_path
30
+ # @param [Boolean] can_cache @see #can_cache
31
+ #
32
+ def initialize(name, params, podfile_path, can_cache = true)
33
+ @name = name
34
+ @params = params
35
+ @podfile_path = podfile_path
36
+ @can_cache = can_cache
37
+ end
38
+
39
+ # @return [Bool] whether an external source source is equal to another
40
+ # according to the {#name} and to the {#params}.
41
+ #
42
+ def ==(other)
43
+ return false if other.nil?
44
+ name == other.name && params == other.params
45
+ end
46
+
47
+ public
48
+
49
+ # @!group Subclasses hooks
50
+
51
+ # Fetches the external source from the remote according to the params.
52
+ #
53
+ # @param [Sandbox] _sandbox
54
+ # the sandbox where the specification should be stored.
55
+ #
56
+ # @return [void]
57
+ #
58
+ def fetch(_sandbox)
59
+ raise 'Abstract method'
60
+ end
61
+
62
+ # @return [String] a string representation of the source suitable for UI.
63
+ #
64
+ def description
65
+ raise 'Abstract method'
66
+ end
67
+
68
+ protected
69
+
70
+ # Return the normalized path for a podspec for a relative declared path.
71
+ #
72
+ # @param [String] declared_path
73
+ # The path declared in the podfile.
74
+ #
75
+ # @return [String] The uri of the podspec appending the name of the file
76
+ # and expanding it if necessary.
77
+ #
78
+ # @note If the declared path is expanded only if the represents a path
79
+ # relative to the file system.
80
+ #
81
+ def normalized_podspec_path(declared_path)
82
+ extension = File.extname(declared_path)
83
+ if extension == '.podspec' || extension == '.json'
84
+ path_with_ext = declared_path
85
+ else
86
+ path_with_ext = "#{declared_path}/#{name}.podspec"
87
+ end
88
+ podfile_dir = File.dirname(podfile_path || '')
89
+ File.expand_path(path_with_ext, podfile_dir)
90
+ end
91
+
92
+ private
93
+
94
+ # @! Subclasses helpers
95
+
96
+ # Pre-downloads a Pod passing the options to the downloader and informing
97
+ # the sandbox.
98
+ #
99
+ # @param [Sandbox] sandbox
100
+ # The sandbox where the Pod should be downloaded.
101
+ #
102
+ # @note To prevent a double download of the repository the pod is
103
+ # marked as pre-downloaded indicating to the installer that only
104
+ # clean operations are needed.
105
+ #
106
+ # @todo The downloader configuration is the same of the
107
+ # #{PodSourceInstaller} and it needs to be kept in sync.
108
+ #
109
+ # @return [void]
110
+ #
111
+ def pre_download(sandbox)
112
+ title = "Pre-downloading: `#{name}` #{description}"
113
+ UI.titled_section(title, :verbose_prefix => '-> ') do
114
+ target = sandbox.pod_dir(name)
115
+ begin
116
+ download_result = Downloader.download(download_request, target, :can_cache => can_cache)
117
+ rescue Pod::DSLError => e
118
+ raise Informative, "Failed to load '#{name}' podspec: #{e.message}"
119
+ rescue => e
120
+ raise Informative, "Failed to download '#{name}': #{e.message}"
121
+ end
122
+
123
+ spec = download_result.spec
124
+ raise Informative, "Unable to find a specification for '#{name}'." unless spec
125
+
126
+ # since the podspec might be cleaned, we want the checksum to refer
127
+ # to the json in the sandbox
128
+ spec.defined_in_file = nil
129
+
130
+ store_podspec(sandbox, spec)
131
+ sandbox.store_pre_downloaded_pod(name)
132
+ sandbox.store_checkout_source(name, download_result.checkout_options)
133
+ end
134
+ end
135
+
136
+ def download_request
137
+ Downloader::Request.new(
138
+ :name => name,
139
+ :params => params,
140
+ )
141
+ end
142
+
143
+ # Stores the podspec in the sandbox and marks it as from an external
144
+ # source.
145
+ #
146
+ # @param [Sandbox] sandbox
147
+ # The sandbox where the specification should be stored.
148
+ #
149
+ # @param [Pathname, String, Specification] spec
150
+ # The path of the specification or its contents.
151
+ #
152
+ # @note All the concrete implementations of #{fetch} should invoke this
153
+ # method.
154
+ #
155
+ # @note The sandbox ensures that the podspec exists and that the names
156
+ # match.
157
+ #
158
+ # @return [void]
159
+ #
160
+ def store_podspec(sandbox, spec, json = false)
161
+ begin
162
+ spec = case spec
163
+ when Pathname
164
+ Specification.from_file(spec)
165
+ when String
166
+ path = "#{name}.podspec"
167
+ path << '.json' if json
168
+ Specification.from_string(spec, path).tap { |s| s.defined_in_file = nil }
169
+ when Specification
170
+ spec.dup
171
+ else
172
+ raise "Unknown spec type: #{spec}"
173
+ end
174
+ rescue Pod::DSLError => e
175
+ raise Informative, "Failed to load '#{name}' podspec: #{e.message}"
176
+ end
177
+
178
+ validate_podspec(spec)
179
+ sandbox.store_podspec(name, spec, true, true)
180
+ end
181
+
182
+ def validate_podspec(podspec)
183
+ defined_in_file = podspec.defined_in_file
184
+ podspec.defined_in_file = nil
185
+
186
+ validator = validator_for_podspec(podspec)
187
+ validator.quick = true
188
+ validator.allow_warnings = true
189
+ validator.ignore_public_only_results = true
190
+ Config.instance.with_changes(:silent => true) do
191
+ validator.validate
192
+ end
193
+ unless validator.validated?
194
+ raise Informative, "The `#{name}` pod failed to validate due to #{validator.failure_reason}:\n#{validator.results_message}"
195
+ end
196
+ ensure
197
+ podspec.defined_in_file = defined_in_file
198
+ end
199
+
200
+ def validator_for_podspec(podspec)
201
+ Validator.new(podspec, [], [])
202
+ end
203
+ end
204
+ end
205
+ end