cocoapods 0.16.4 → 0.17.0.rc1
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 +108 -0
- data/README.md +3 -3
- data/bin/pod +1 -1
- data/lib/cocoapods.rb +31 -31
- data/lib/cocoapods/command.rb +62 -107
- data/lib/cocoapods/command/inter_process_communication.rb +103 -0
- data/lib/cocoapods/command/list.rb +45 -44
- data/lib/cocoapods/command/outdated.rb +28 -25
- data/lib/cocoapods/command/project.rb +90 -0
- data/lib/cocoapods/command/push.rb +50 -32
- data/lib/cocoapods/command/repo.rb +125 -155
- data/lib/cocoapods/command/search.rb +23 -12
- data/lib/cocoapods/command/setup.rb +103 -64
- data/lib/cocoapods/command/spec.rb +329 -90
- data/lib/cocoapods/config.rb +197 -44
- data/lib/cocoapods/downloader.rb +47 -34
- data/lib/cocoapods/executable.rb +98 -41
- data/lib/cocoapods/external_sources.rb +325 -0
- data/lib/cocoapods/file_list.rb +8 -1
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +71 -7
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +10 -9
- data/lib/cocoapods/generator/acknowledgements/plist.rb +9 -8
- data/lib/cocoapods/generator/copy_resources_script.rb +2 -2
- data/lib/cocoapods/generator/documentation.rb +153 -37
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_header.rb +58 -0
- data/lib/cocoapods/generator/xcconfig.rb +130 -0
- data/lib/cocoapods/hooks/installer_representation.rb +123 -0
- data/lib/cocoapods/hooks/library_representation.rb +79 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +398 -147
- data/lib/cocoapods/installer/analyzer.rb +556 -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 +289 -0
- data/lib/cocoapods/installer/target_installer.rb +307 -112
- data/lib/cocoapods/installer/user_project_integrator.rb +140 -176
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +193 -0
- data/lib/cocoapods/library.rb +195 -0
- data/lib/cocoapods/open_uri.rb +16 -14
- data/lib/cocoapods/project.rb +175 -52
- data/lib/cocoapods/resolver.rb +151 -164
- data/lib/cocoapods/sandbox.rb +276 -54
- data/lib/cocoapods/sandbox/file_accessor.rb +210 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +178 -0
- data/lib/cocoapods/sources_manager.rb +218 -0
- data/lib/cocoapods/user_interface.rb +82 -18
- data/lib/cocoapods/{command → user_interface}/error_report.rb +5 -5
- data/lib/cocoapods/validator.rb +379 -0
- metadata +74 -55
- data/lib/cocoapods/command/install.rb +0 -55
- data/lib/cocoapods/command/linter.rb +0 -317
- data/lib/cocoapods/command/update.rb +0 -25
- data/lib/cocoapods/dependency.rb +0 -285
- data/lib/cocoapods/downloader/git.rb +0 -276
- data/lib/cocoapods/downloader/http.rb +0 -99
- data/lib/cocoapods/downloader/mercurial.rb +0 -26
- data/lib/cocoapods/downloader/subversion.rb +0 -42
- data/lib/cocoapods/local_pod.rb +0 -620
- data/lib/cocoapods/lockfile.rb +0 -274
- data/lib/cocoapods/platform.rb +0 -127
- data/lib/cocoapods/podfile.rb +0 -551
- data/lib/cocoapods/source.rb +0 -223
- data/lib/cocoapods/specification.rb +0 -579
- data/lib/cocoapods/specification/set.rb +0 -175
- data/lib/cocoapods/specification/statistics.rb +0 -112
- data/lib/cocoapods/user_interface/ui_pod.rb +0 -130
- data/lib/cocoapods/version.rb +0 -26
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'tempfile'
|
3
|
-
require 'zlib'
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
module Pod
|
7
|
-
class Downloader
|
8
|
-
class Http < Downloader
|
9
|
-
class UnsupportedFileTypeError < StandardError; end
|
10
|
-
|
11
|
-
executable :curl
|
12
|
-
executable :unzip
|
13
|
-
executable :tar
|
14
|
-
|
15
|
-
attr_accessor :filename, :download_path
|
16
|
-
def download
|
17
|
-
@filename = filename_with_type type
|
18
|
-
@download_path = target_path + @filename
|
19
|
-
UI.section(' > Downloading from HTTP', '', 3) do
|
20
|
-
download_file @download_path
|
21
|
-
extract_with_type @download_path, type
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def type
|
26
|
-
options[:type] || type_with_url(url)
|
27
|
-
end
|
28
|
-
|
29
|
-
def should_flatten?
|
30
|
-
if options.has_key? :flatten
|
31
|
-
options[:flatten] # spec file can always override
|
32
|
-
elsif [:tgz, :tar, :tbz].include? type
|
33
|
-
true # those archives flatten by default
|
34
|
-
else
|
35
|
-
false # all others (actually only .zip) default not to flatten
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def type_with_url(url)
|
41
|
-
if url =~ /.zip$/
|
42
|
-
:zip
|
43
|
-
elsif url =~ /.(tgz|tar\.gz)$/
|
44
|
-
:tgz
|
45
|
-
elsif url =~ /.tar$/
|
46
|
-
:tar
|
47
|
-
elsif url =~ /.(tbz|tar\.bz2)$/
|
48
|
-
:tbz
|
49
|
-
else
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def filename_with_type(type=:zip)
|
55
|
-
case type
|
56
|
-
when :zip
|
57
|
-
"file.zip"
|
58
|
-
when :tgz
|
59
|
-
"file.tgz"
|
60
|
-
when :tar
|
61
|
-
"file.tar"
|
62
|
-
when :tbz
|
63
|
-
"file.tbz"
|
64
|
-
else
|
65
|
-
raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def download_file(full_filename)
|
70
|
-
curl! "-L -o '#{full_filename}' '#{url}'"
|
71
|
-
end
|
72
|
-
|
73
|
-
def extract_with_type(full_filename, type=:zip)
|
74
|
-
case type
|
75
|
-
when :zip
|
76
|
-
unzip! "'#{full_filename}' -d '#{target_path}'"
|
77
|
-
when :tgz
|
78
|
-
tar! "xfz '#{full_filename}' -C '#{target_path}'"
|
79
|
-
when :tar
|
80
|
-
tar! "xf '#{full_filename}' -C '#{target_path}'"
|
81
|
-
when :tbz
|
82
|
-
tar! "xfj '#{full_filename}' -C '#{target_path}'"
|
83
|
-
else
|
84
|
-
raise UnsupportedFileTypeError.new "Unsupported file type: #{type}"
|
85
|
-
end
|
86
|
-
|
87
|
-
if should_flatten?
|
88
|
-
contents = target_path.children
|
89
|
-
contents.delete(full_filename)
|
90
|
-
entry = contents.first
|
91
|
-
if contents.count == 1 && entry.directory?
|
92
|
-
FileUtils.move(entry.children, target_path)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
class Downloader
|
3
|
-
class Mercurial < Downloader
|
4
|
-
executable :hg
|
5
|
-
|
6
|
-
def download
|
7
|
-
UI.section(' > Cloning mercurial repo', '', 3) do
|
8
|
-
if options[:revision]
|
9
|
-
download_revision
|
10
|
-
else
|
11
|
-
download_head
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def download_head
|
17
|
-
hg! "clone \"#{url}\" \"#{target_path}\""
|
18
|
-
end
|
19
|
-
|
20
|
-
def download_revision
|
21
|
-
hg! "clone \"#{url}\" --rev '#{options[:revision]}' \"#{target_path}\""
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
class Downloader
|
3
|
-
class Subversion < Downloader
|
4
|
-
executable :svn
|
5
|
-
|
6
|
-
def initialize(target_path, url, options)
|
7
|
-
@target_path, @url, @options = target_path, url, options
|
8
|
-
end
|
9
|
-
|
10
|
-
def download
|
11
|
-
UI.section(' > Exporting subversion repo', '', 3) do
|
12
|
-
svn! %|#{export_subcommand} "#{reference_url}" "#{target_path}"|
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def download_head
|
17
|
-
UI.section(' > Exporting subversion repo', '', 3) do
|
18
|
-
svn! %|#{export_subcommand} "#{trunk_url}" "#{target_path}"|
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def export_subcommand
|
23
|
-
result = 'export --non-interactive --trust-server-cert'
|
24
|
-
end
|
25
|
-
|
26
|
-
def reference_url
|
27
|
-
result = url.dup
|
28
|
-
result << '/' << options[:folder] if options[:folder]
|
29
|
-
result << '/tags/' << options[:tag] if options[:tag]
|
30
|
-
result << '" -r "' << options[:revision] if options[:revision]
|
31
|
-
result
|
32
|
-
end
|
33
|
-
|
34
|
-
def trunk_url
|
35
|
-
result = url.dup
|
36
|
-
result << '/' << options[:folder] if options[:folder]
|
37
|
-
result << '/trunk'
|
38
|
-
result
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/cocoapods/local_pod.rb
DELETED
@@ -1,620 +0,0 @@
|
|
1
|
-
module Pod
|
2
|
-
|
3
|
-
# A {LocalPod} interfaces one or more specifications belonging to one pod
|
4
|
-
# (a library) and their concrete instance in the file system.
|
5
|
-
#
|
6
|
-
# The {LocalPod} is responsible for orchestrating the activated
|
7
|
-
# specifications of a single pod. Specifically, it keeps track of the
|
8
|
-
# activated specifications and handles issues related to duplicates
|
9
|
-
# files.
|
10
|
-
# Inheritance logic belongs to the {Specification} class.
|
11
|
-
#
|
12
|
-
# The activated specifications are used to compute the paths that can be
|
13
|
-
# safely cleaned by the pod.
|
14
|
-
#
|
15
|
-
# @example
|
16
|
-
# pod = LocalPod.new 'RestKit/Networking'
|
17
|
-
# pod.add_specification 'RestKit/UI'
|
18
|
-
#
|
19
|
-
# @note
|
20
|
-
# Unless otherwise specified in the name of the method the {LocalPod}
|
21
|
-
# returns absolute paths.
|
22
|
-
#
|
23
|
-
class LocalPod
|
24
|
-
|
25
|
-
# @return [Specification] The specification that describes the pod.
|
26
|
-
#
|
27
|
-
attr_reader :top_specification
|
28
|
-
|
29
|
-
# @return [Specification] The activated specifications of the pod.
|
30
|
-
#
|
31
|
-
attr_reader :specifications
|
32
|
-
|
33
|
-
# @return [Sandbox] The sandbox where the pod is installed.
|
34
|
-
#
|
35
|
-
attr_reader :sandbox
|
36
|
-
|
37
|
-
# @return [Platform] The platform that will be used to build the pod.
|
38
|
-
#
|
39
|
-
attr_reader :platform
|
40
|
-
|
41
|
-
# @return [Boolean] Wether or not the pod has been downloaded in the
|
42
|
-
# current install process and still needs its docs
|
43
|
-
# generated and be cleaned.
|
44
|
-
#
|
45
|
-
attr_accessor :downloaded
|
46
|
-
alias_method :downloaded?, :downloaded
|
47
|
-
|
48
|
-
# @param [Specification] specification The first activated specification
|
49
|
-
# of the pod.
|
50
|
-
#
|
51
|
-
# @param [Sandbox] sandbox The sandbox where the files of the
|
52
|
-
# pod will be located.
|
53
|
-
#
|
54
|
-
# @param [Platform] platform The platform that will be used to
|
55
|
-
# build the pod.
|
56
|
-
#
|
57
|
-
# @todo The local pod should be initialized with all the activated
|
58
|
-
# specifications passed as an array, in order to be able to cache the
|
59
|
-
# computed values. In other words, it should be immutable.
|
60
|
-
#
|
61
|
-
def initialize(specification, sandbox, platform)
|
62
|
-
@top_specification, @sandbox, @platform = specification.top_level_parent, sandbox, platform
|
63
|
-
@top_specification.activate_platform(platform)
|
64
|
-
@specifications = [] << specification
|
65
|
-
end
|
66
|
-
|
67
|
-
# Initializes a local pod from the top specification of a podspec file.
|
68
|
-
#
|
69
|
-
# @return [LocalPod] A new local pod.
|
70
|
-
#
|
71
|
-
def self.from_podspec(podspec, sandbox, platform)
|
72
|
-
new(Specification.from_file(podspec), sandbox, platform)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Activates a specification or subspecs for the pod.
|
76
|
-
# Adding specifications is idempotent.
|
77
|
-
#
|
78
|
-
# @param {Specification} spec The specification to add to the pod.
|
79
|
-
#
|
80
|
-
# @raise {Informative} If the specification is not part of the same pod.
|
81
|
-
#
|
82
|
-
def add_specification(spec)
|
83
|
-
unless spec.top_level_parent == top_specification
|
84
|
-
raise Informative,
|
85
|
-
"[Local Pod] Attempt to add a specification from another pod"
|
86
|
-
end
|
87
|
-
spec.activate_platform(platform)
|
88
|
-
@specifications << spec unless @specifications.include?(spec)
|
89
|
-
end
|
90
|
-
|
91
|
-
# @return [Pathname] The root directory of the pod
|
92
|
-
#
|
93
|
-
def root
|
94
|
-
@sandbox.root + top_specification.name
|
95
|
-
end
|
96
|
-
|
97
|
-
# @return [String] A string representation of the pod which indicates if
|
98
|
-
# the pods comes from a local source or has a preferred
|
99
|
-
# dependency.
|
100
|
-
#
|
101
|
-
def to_s
|
102
|
-
s = top_specification.to_s
|
103
|
-
s << " defaulting to #{top_specification.preferred_dependency} subspec" if top_specification.preferred_dependency
|
104
|
-
s
|
105
|
-
end
|
106
|
-
|
107
|
-
# @return [String] The name of the Pod.
|
108
|
-
#
|
109
|
-
def name
|
110
|
-
top_specification.name
|
111
|
-
end
|
112
|
-
|
113
|
-
# @!group Installation
|
114
|
-
|
115
|
-
# Creates the root path of the pod.
|
116
|
-
#
|
117
|
-
# @return [void]
|
118
|
-
#
|
119
|
-
def create
|
120
|
-
root.mkpath unless exists?
|
121
|
-
end
|
122
|
-
|
123
|
-
# Whether the root path of the pod exists.
|
124
|
-
#
|
125
|
-
def exists?
|
126
|
-
root.exist?
|
127
|
-
end
|
128
|
-
|
129
|
-
# Executes a block in the root directory of the Pod.
|
130
|
-
#
|
131
|
-
# @return [void]
|
132
|
-
#
|
133
|
-
def chdir(&block)
|
134
|
-
create
|
135
|
-
Dir.chdir(root, &block)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Deletes the pod from the file system.
|
139
|
-
#
|
140
|
-
# @return [void]
|
141
|
-
#
|
142
|
-
def implode
|
143
|
-
root.rmtree if exists?
|
144
|
-
end
|
145
|
-
|
146
|
-
def local?
|
147
|
-
false
|
148
|
-
end
|
149
|
-
|
150
|
-
# @!group Cleaning
|
151
|
-
|
152
|
-
# Deletes any path that is not used by the pod.
|
153
|
-
#
|
154
|
-
# @return [void]
|
155
|
-
#
|
156
|
-
def clean!
|
157
|
-
clean_paths.each { |path| FileUtils.rm_rf(path) }
|
158
|
-
@cleaned = true
|
159
|
-
end
|
160
|
-
|
161
|
-
# Finds the absolute paths, including hidden ones, of the files
|
162
|
-
# that are not used by the pod and thus can be safely deleted.
|
163
|
-
#
|
164
|
-
# @return [Array<Strings>] The paths that can be deleted.
|
165
|
-
#
|
166
|
-
# @note Implementation detail: Don't use Dir#glob as there is an
|
167
|
-
# unexplained issue (#568, #572 and #602).
|
168
|
-
#
|
169
|
-
def clean_paths
|
170
|
-
cached_used = used_files
|
171
|
-
files = Pathname.glob(root + "**/*", File::FNM_DOTMATCH | File::FNM_CASEFOLD).map(&:to_s)
|
172
|
-
|
173
|
-
files.reject! do |candidate|
|
174
|
-
candidate.end_with?('.', '..') || cached_used.any? do |path|
|
175
|
-
path.include?(candidate) || candidate.include?(path)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
files
|
179
|
-
end
|
180
|
-
|
181
|
-
# @return [Array<String>] The absolute path of the files used by the pod.
|
182
|
-
#
|
183
|
-
def used_files
|
184
|
-
files = [ source_files, resource_files, preserve_files, readme_file, license_file, prefix_header_file ]
|
185
|
-
files.compact!
|
186
|
-
files.flatten!
|
187
|
-
files.map!{ |path| path.to_s }
|
188
|
-
files
|
189
|
-
end
|
190
|
-
|
191
|
-
# @!group Files
|
192
|
-
|
193
|
-
# @return [Pathname] Returns the relative path from the sandbox.
|
194
|
-
#
|
195
|
-
# @note If the two abosule paths don't share the same root directory an
|
196
|
-
# extra `../` is added to the result of {Pathname#relative_path_from}
|
197
|
-
#
|
198
|
-
# path = Pathname.new('/Users/dir')
|
199
|
-
# @sandbox
|
200
|
-
# #=> Pathname('/tmp/CocoaPods/Lint/Pods')
|
201
|
-
#
|
202
|
-
# p.relative_path_from(@sandbox
|
203
|
-
# #=> '../../../../Users/dir'
|
204
|
-
#
|
205
|
-
# relativize_from_sandbox(path)
|
206
|
-
# #=> '../../../../../Users/dir'
|
207
|
-
#
|
208
|
-
def relativize_from_sandbox(path)
|
209
|
-
result = path.relative_path_from(@sandbox.root)
|
210
|
-
result = Pathname.new('../') + result unless @sandbox.root.to_s.split('/')[1] == path.to_s.split('/')[1]
|
211
|
-
result
|
212
|
-
end
|
213
|
-
|
214
|
-
# @return [Array<Pathname>] The paths of the source files.
|
215
|
-
#
|
216
|
-
def source_files
|
217
|
-
source_files_by_spec.values.flatten
|
218
|
-
end
|
219
|
-
|
220
|
-
# @return [Array<Pathname>] The *relative* paths of the source files.
|
221
|
-
#
|
222
|
-
def relative_source_files
|
223
|
-
source_files.map{ |p| relativize_from_sandbox(p) }
|
224
|
-
end
|
225
|
-
|
226
|
-
def relative_source_files_by_spec
|
227
|
-
result = {}
|
228
|
-
source_files_by_spec.each do |spec, paths|
|
229
|
-
result[spec] = paths.map{ |p| relativize_from_sandbox(p) }
|
230
|
-
end
|
231
|
-
result
|
232
|
-
end
|
233
|
-
|
234
|
-
|
235
|
-
# Finds the source files that every activated {Specification} requires.
|
236
|
-
#
|
237
|
-
# @note If the same file is required by two specifications the one at the
|
238
|
-
# higher level in the inheritance chain wins.
|
239
|
-
#
|
240
|
-
# @return [Hash{Specification => Array<Pathname>}] The files grouped by
|
241
|
-
# {Specification}.
|
242
|
-
#
|
243
|
-
def source_files_by_spec
|
244
|
-
options = {:glob => '*.{h,hpp,hh,m,mm,c,cpp}'}
|
245
|
-
paths_by_spec(:source_files, options)
|
246
|
-
end
|
247
|
-
|
248
|
-
# @return [Array<Pathname>] The paths of the header files.
|
249
|
-
#
|
250
|
-
def header_files
|
251
|
-
header_files_by_spec.values.flatten
|
252
|
-
end
|
253
|
-
|
254
|
-
# @return [Array<Pathname>] The *relative* paths of the source files.
|
255
|
-
#
|
256
|
-
def relative_header_files
|
257
|
-
header_files.map{ |p| relativize_from_sandbox(p) }
|
258
|
-
end
|
259
|
-
|
260
|
-
# @return [Hash{Specification => Array<Pathname>}] The paths of the header
|
261
|
-
# files grouped by {Specification}.
|
262
|
-
#
|
263
|
-
def header_files_by_spec
|
264
|
-
result = {}
|
265
|
-
source_files_by_spec.each do |spec, paths|
|
266
|
-
headers = paths.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
|
267
|
-
result[spec] = headers unless headers.empty?
|
268
|
-
end
|
269
|
-
result
|
270
|
-
end
|
271
|
-
|
272
|
-
# @return [Hash{Specification => Array<Pathname>}] The paths of the header
|
273
|
-
# files grouped by {Specification} that should be copied in the public
|
274
|
-
# folder.
|
275
|
-
#
|
276
|
-
# If a spec does not match any public header it means that all the
|
277
|
-
# header files (i.e. the build ones) are intended to be public.
|
278
|
-
#
|
279
|
-
def public_header_files_by_spec
|
280
|
-
public_headers = paths_by_spec(:public_header_files, :glob => '*.{h,hpp,hh}')
|
281
|
-
build_headers = header_files_by_spec
|
282
|
-
|
283
|
-
result = {}
|
284
|
-
specifications.each do |spec|
|
285
|
-
if (public_h = public_headers[spec]) && !public_h.empty?
|
286
|
-
result[spec] = public_h
|
287
|
-
elsif (build_h = build_headers[spec]) && !build_h.empty?
|
288
|
-
result[spec] = build_h
|
289
|
-
end
|
290
|
-
end
|
291
|
-
result
|
292
|
-
end
|
293
|
-
|
294
|
-
# @return [Array<Pathname>] The paths of the resources.
|
295
|
-
#
|
296
|
-
def resource_files
|
297
|
-
paths_by_spec(:resources).values.flatten
|
298
|
-
end
|
299
|
-
|
300
|
-
# @return [Array<Pathname>] The *relative* paths of the resources.
|
301
|
-
#
|
302
|
-
def relative_resource_files
|
303
|
-
resource_files.map{ |p| relativize_from_sandbox(p) }
|
304
|
-
end
|
305
|
-
|
306
|
-
# @return [Pathname] The absolute path of the prefix header file
|
307
|
-
#
|
308
|
-
def prefix_header_file
|
309
|
-
root + top_specification.prefix_header_file if top_specification.prefix_header_file
|
310
|
-
end
|
311
|
-
|
312
|
-
# @return [Array<Pathname>] The absolute paths of the files of the pod
|
313
|
-
# that should be preserved.
|
314
|
-
#
|
315
|
-
def preserve_files
|
316
|
-
paths = paths_by_spec(:preserve_paths).values
|
317
|
-
paths += expanded_paths(%w[ *.podspec notice* NOTICE* CREDITS* ])
|
318
|
-
paths.compact!
|
319
|
-
paths.uniq!
|
320
|
-
paths
|
321
|
-
end
|
322
|
-
|
323
|
-
# @return [Pathname] The automatically detected absolute path of the README
|
324
|
-
# file.
|
325
|
-
#
|
326
|
-
def readme_file
|
327
|
-
expanded_paths(%w[ readme{*,.*} ]).first
|
328
|
-
end
|
329
|
-
|
330
|
-
# @return [Pathname] The absolute path of the license file from the
|
331
|
-
# specification or automatically detected.
|
332
|
-
#
|
333
|
-
def license_file
|
334
|
-
if top_specification.license && top_specification.license[:file]
|
335
|
-
root + top_specification.license[:file]
|
336
|
-
else
|
337
|
-
expanded_paths(%w[ licen{c,s}e{*,.*} ]).first
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
# @return [String] The text of the license of the pod from the
|
342
|
-
# specification or from the license file.
|
343
|
-
#
|
344
|
-
def license_text
|
345
|
-
if (license_hash = top_specification.license)
|
346
|
-
if (result = license_hash[:text])
|
347
|
-
result
|
348
|
-
elsif license_file
|
349
|
-
result = IO.read(license_file)
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
def xcconfig
|
355
|
-
specifications.map { |s| s.xcconfig }.reduce(:merge)
|
356
|
-
end
|
357
|
-
|
358
|
-
# Computes the paths of all the public headers of the pod including every
|
359
|
-
# subspec (activated or not).
|
360
|
-
# For this reason the pod must not be cleaned when calling this command.
|
361
|
-
#
|
362
|
-
# This method is used by {Generator::Documentation}.
|
363
|
-
#
|
364
|
-
# @raise [Informative] If the pod was cleaned.
|
365
|
-
#
|
366
|
-
# @return [Array<Pathname>] The path of all the public headers of the pod.
|
367
|
-
#
|
368
|
-
def documentation_headers
|
369
|
-
if @cleaned
|
370
|
-
raise Informative, "The pod is cleaned and cannot compute the " \
|
371
|
-
"header files, as some might have been deleted."
|
372
|
-
end
|
373
|
-
|
374
|
-
specs = [top_specification] + top_specification.recursive_subspecs
|
375
|
-
source_files = paths_by_spec(:source_files, { :glob => '*.{h}'}, specs)
|
376
|
-
public_headers = paths_by_spec(:public_header_files,{ :glob => '*.{h}'}, specs)
|
377
|
-
|
378
|
-
result = []
|
379
|
-
specs.each do |spec|
|
380
|
-
if (public_h = public_headers[spec]) && !public_h.empty?
|
381
|
-
result += public_h
|
382
|
-
elsif (source_f = source_files[spec]) && !source_f.empty?
|
383
|
-
build_h = source_f.select { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
|
384
|
-
result += build_h unless build_h.empty?
|
385
|
-
end
|
386
|
-
end
|
387
|
-
result
|
388
|
-
end
|
389
|
-
|
390
|
-
# @!group Xcodeproj integration
|
391
|
-
|
392
|
-
# Adds the file references, to the given `Pods.xcodeproj` project, for the
|
393
|
-
# source files of the pod. The file references are grouped by specification
|
394
|
-
# and stored in {#file_references_by_spec}.
|
395
|
-
#
|
396
|
-
# @note If the pod is locally sourced the file references are stored in the
|
397
|
-
# `Local Pods` group otherwise they are stored in the `Pods` group.
|
398
|
-
#
|
399
|
-
# @return [void]
|
400
|
-
#
|
401
|
-
def add_file_references_to_project(project)
|
402
|
-
@file_references_by_spec = {}
|
403
|
-
parent_group = local? ? project.local_pods : project.pods
|
404
|
-
|
405
|
-
relative_source_files_by_spec.each do |spec, paths|
|
406
|
-
group = project.add_spec_group(spec.name, parent_group)
|
407
|
-
file_references = []
|
408
|
-
paths.each do |path|
|
409
|
-
file_references << group.new_file(path)
|
410
|
-
end
|
411
|
-
@file_references_by_spec[spec] = file_references
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
# @return [Hash{Specification => Array<PBXFileReference>}] The file
|
416
|
-
# references of the pod in the `Pods.xcodeproj` project.
|
417
|
-
#
|
418
|
-
attr_reader :file_references_by_spec
|
419
|
-
|
420
|
-
# Adds a build file for each file reference to a given target taking into
|
421
|
-
# account the compiler flags of the corresponding specification.
|
422
|
-
#
|
423
|
-
# @raise If the {#add_file_references_to_project} was not called before of
|
424
|
-
# calling this method.
|
425
|
-
#
|
426
|
-
# @return [void]
|
427
|
-
#
|
428
|
-
def add_build_files_to_target(target)
|
429
|
-
unless file_references_by_spec
|
430
|
-
raise Informative, "Local Pod needs to add the file references to the " \
|
431
|
-
"project before adding the build files to the target."
|
432
|
-
end
|
433
|
-
file_references_by_spec.each do |spec, file_reference|
|
434
|
-
target.add_file_references(file_reference, spec.compiler_flags.strip)
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
# @return [void] Copies the pods headers to the sandbox.
|
439
|
-
#
|
440
|
-
def link_headers
|
441
|
-
@sandbox.build_headers.add_search_path(headers_sandbox)
|
442
|
-
@sandbox.public_headers.add_search_path(headers_sandbox)
|
443
|
-
|
444
|
-
header_mappings(header_files_by_spec).each do |namespaced_path, files|
|
445
|
-
@sandbox.build_headers.add_files(namespaced_path, files)
|
446
|
-
end
|
447
|
-
|
448
|
-
header_mappings(public_header_files_by_spec).each do |namespaced_path, files|
|
449
|
-
@sandbox.public_headers.add_files(namespaced_path, files)
|
450
|
-
end
|
451
|
-
end
|
452
|
-
|
453
|
-
# @return Whether the pod requires ARC.
|
454
|
-
#
|
455
|
-
# TODO: this should be not used anymore.
|
456
|
-
#
|
457
|
-
def requires_arc?
|
458
|
-
top_specification.requires_arc
|
459
|
-
end
|
460
|
-
|
461
|
-
private
|
462
|
-
|
463
|
-
# @return [Array<Pathname>] The implementation files
|
464
|
-
# (the files the need to compiled) of the pod.
|
465
|
-
#
|
466
|
-
def implementation_files
|
467
|
-
relative_source_files.reject { |f| f.extname == '.h' || f.extname == '.hpp' || f.extname == '.hh' }
|
468
|
-
end
|
469
|
-
|
470
|
-
# @return [Pathname] The path of the pod relative from the sandbox.
|
471
|
-
#
|
472
|
-
def relative_root
|
473
|
-
root.relative_path_from(@sandbox.root)
|
474
|
-
end
|
475
|
-
|
476
|
-
# @return Hash{Pathname => [Array<Pathname>]} A hash containing the headers
|
477
|
-
# folders as the keys and the the absolute paths of the header files
|
478
|
-
# as the values.
|
479
|
-
#
|
480
|
-
# @todo this is being overridden in the RestKit 0.9.4 spec, need to do
|
481
|
-
# something with that, and this method also still exists in Specification.
|
482
|
-
#
|
483
|
-
# @todo This is not overridden anymore in specification refactor and the
|
484
|
-
# code Pod::Specification#copy_header_mapping can be moved here.
|
485
|
-
def header_mappings(files_by_spec)
|
486
|
-
mappings = {}
|
487
|
-
files_by_spec.each do |spec, paths|
|
488
|
-
paths = paths - headers_excluded_from_search_paths
|
489
|
-
dir = spec.header_dir ? (headers_sandbox + spec.header_dir) : headers_sandbox
|
490
|
-
paths.each do |from|
|
491
|
-
from_relative = from.relative_path_from(root)
|
492
|
-
to = dir + spec.copy_header_mapping(from_relative)
|
493
|
-
(mappings[to.dirname] ||= []) << from
|
494
|
-
end
|
495
|
-
end
|
496
|
-
mappings
|
497
|
-
end
|
498
|
-
|
499
|
-
# @return <Pathname> The name of the folder where the headers of this pod
|
500
|
-
# will be namespaced.
|
501
|
-
#
|
502
|
-
def headers_sandbox
|
503
|
-
@headers_sandbox ||= Pathname.new(top_specification.name)
|
504
|
-
end
|
505
|
-
|
506
|
-
# @return [<Pathname>] The relative path of the headers that should not be
|
507
|
-
# included in the linker search paths.
|
508
|
-
#
|
509
|
-
def headers_excluded_from_search_paths
|
510
|
-
options = { :glob => '*.{h,hpp,hh}' }
|
511
|
-
paths = paths_by_spec(:exclude_header_search_paths, options)
|
512
|
-
paths.values.compact.uniq
|
513
|
-
end
|
514
|
-
|
515
|
-
# @!group Paths Patterns
|
516
|
-
|
517
|
-
# The paths obtained by resolving the patterns of an attribute
|
518
|
-
# groupped by spec.
|
519
|
-
#
|
520
|
-
# @param [Symbol] accessor The accessor to use to obtain the paths patterns.
|
521
|
-
# @param [Hash] options (see #expanded_paths)
|
522
|
-
#
|
523
|
-
def paths_by_spec(accessor, options = {}, specs = nil)
|
524
|
-
specs ||= specifications
|
525
|
-
paths_by_spec = {}
|
526
|
-
processed_paths = []
|
527
|
-
|
528
|
-
specs = specs.sort_by { |s| s.name.length }
|
529
|
-
specs.each do |spec|
|
530
|
-
paths = expanded_paths(spec.send(accessor), options)
|
531
|
-
unless paths.empty?
|
532
|
-
paths_by_spec[spec] = paths - processed_paths
|
533
|
-
processed_paths += paths
|
534
|
-
end
|
535
|
-
end
|
536
|
-
paths_by_spec
|
537
|
-
end
|
538
|
-
|
539
|
-
# Converts patterns of paths to the {Pathname} of the files present in the
|
540
|
-
# pod.
|
541
|
-
#
|
542
|
-
# @param [String, FileList, Array<String, Pathname>] patterns
|
543
|
-
# The patterns to expand.
|
544
|
-
# @param [Hash] options
|
545
|
-
# The options to used for expanding the paths patterns.
|
546
|
-
# @option options [String] :glob
|
547
|
-
# The pattern to use for globing directories.
|
548
|
-
#
|
549
|
-
# @raise [Informative] If the pod does not exists.
|
550
|
-
#
|
551
|
-
# @todo implement case insensitive search
|
552
|
-
#
|
553
|
-
# @return [Array<Pathname>] A list of the paths.
|
554
|
-
#
|
555
|
-
def expanded_paths(patterns, options = {})
|
556
|
-
unless exists?
|
557
|
-
raise Informative, "[Local Pod] Attempt to resolve paths for nonexistent pod.\n" \
|
558
|
-
"\tSpecifications: #{@specifications.inspect}\n" \
|
559
|
-
"\t Patterns: #{patterns.inspect}\n" \
|
560
|
-
"\t Options: #{options.inspect}"
|
561
|
-
end
|
562
|
-
|
563
|
-
return [] if patterns.empty?
|
564
|
-
patterns = [ patterns ] if patterns.is_a?(String)
|
565
|
-
file_lists = patterns.select { |p| p.is_a?(FileList) }
|
566
|
-
glob_patterns = patterns - file_lists
|
567
|
-
|
568
|
-
result = []
|
569
|
-
|
570
|
-
result << file_lists.map do |file_list|
|
571
|
-
file_list.prepend_patterns(root)
|
572
|
-
file_list.glob
|
573
|
-
end
|
574
|
-
|
575
|
-
result << glob_patterns.map do |pattern|
|
576
|
-
pattern = root + pattern
|
577
|
-
if pattern.directory? && options[:glob]
|
578
|
-
pattern += options[:glob]
|
579
|
-
end
|
580
|
-
Pathname.glob(pattern, File::FNM_CASEFOLD)
|
581
|
-
end.flatten
|
582
|
-
|
583
|
-
result.flatten.compact.uniq
|
584
|
-
end
|
585
|
-
|
586
|
-
# A {LocalSourcedPod} is a {LocalPod} that interacts with the files of
|
587
|
-
# a folder controlled by the users. As such this class does not alter
|
588
|
-
# in any way the contents of the folder.
|
589
|
-
#
|
590
|
-
class LocalSourcedPod < LocalPod
|
591
|
-
def downloaded?
|
592
|
-
true
|
593
|
-
end
|
594
|
-
|
595
|
-
def create
|
596
|
-
# No ops
|
597
|
-
end
|
598
|
-
|
599
|
-
def root
|
600
|
-
@root ||= Pathname.new(@top_specification.source[:local]).expand_path
|
601
|
-
end
|
602
|
-
|
603
|
-
def implode
|
604
|
-
# No ops
|
605
|
-
end
|
606
|
-
|
607
|
-
def clean!
|
608
|
-
# No ops
|
609
|
-
end
|
610
|
-
|
611
|
-
def to_s
|
612
|
-
super + " [LOCAL]"
|
613
|
-
end
|
614
|
-
|
615
|
-
def local?
|
616
|
-
true
|
617
|
-
end
|
618
|
-
end
|
619
|
-
end
|
620
|
-
end
|