xcocoapods 1.5.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 +6303 -0
- data/LICENSE +28 -0
- data/README.md +80 -0
- data/bin/pod +56 -0
- data/bin/sandbox-pod +168 -0
- data/lib/cocoapods.rb +73 -0
- data/lib/cocoapods/command.rb +175 -0
- data/lib/cocoapods/command/cache.rb +28 -0
- data/lib/cocoapods/command/cache/clean.rb +90 -0
- data/lib/cocoapods/command/cache/list.rb +69 -0
- data/lib/cocoapods/command/env.rb +66 -0
- data/lib/cocoapods/command/init.rb +128 -0
- data/lib/cocoapods/command/install.rb +45 -0
- data/lib/cocoapods/command/ipc.rb +19 -0
- data/lib/cocoapods/command/ipc/list.rb +40 -0
- data/lib/cocoapods/command/ipc/podfile.rb +31 -0
- data/lib/cocoapods/command/ipc/podfile_json.rb +30 -0
- data/lib/cocoapods/command/ipc/repl.rb +51 -0
- data/lib/cocoapods/command/ipc/spec.rb +29 -0
- data/lib/cocoapods/command/ipc/update_search_index.rb +24 -0
- data/lib/cocoapods/command/lib.rb +11 -0
- data/lib/cocoapods/command/lib/create.rb +105 -0
- data/lib/cocoapods/command/lib/lint.rb +121 -0
- data/lib/cocoapods/command/list.rb +39 -0
- data/lib/cocoapods/command/options/project_directory.rb +36 -0
- data/lib/cocoapods/command/options/repo_update.rb +34 -0
- data/lib/cocoapods/command/outdated.rb +140 -0
- data/lib/cocoapods/command/repo.rb +29 -0
- data/lib/cocoapods/command/repo/add.rb +103 -0
- data/lib/cocoapods/command/repo/lint.rb +82 -0
- data/lib/cocoapods/command/repo/list.rb +93 -0
- data/lib/cocoapods/command/repo/push.rb +281 -0
- data/lib/cocoapods/command/repo/remove.rb +36 -0
- data/lib/cocoapods/command/repo/update.rb +28 -0
- data/lib/cocoapods/command/setup.rb +103 -0
- data/lib/cocoapods/command/spec.rb +112 -0
- data/lib/cocoapods/command/spec/cat.rb +51 -0
- data/lib/cocoapods/command/spec/create.rb +283 -0
- data/lib/cocoapods/command/spec/edit.rb +87 -0
- data/lib/cocoapods/command/spec/env_spec.rb +53 -0
- data/lib/cocoapods/command/spec/lint.rb +137 -0
- data/lib/cocoapods/command/spec/which.rb +43 -0
- data/lib/cocoapods/command/update.rb +101 -0
- data/lib/cocoapods/config.rb +347 -0
- data/lib/cocoapods/core_overrides.rb +1 -0
- data/lib/cocoapods/downloader.rb +190 -0
- data/lib/cocoapods/downloader/cache.rb +233 -0
- data/lib/cocoapods/downloader/request.rb +86 -0
- data/lib/cocoapods/downloader/response.rb +16 -0
- data/lib/cocoapods/executable.rb +222 -0
- data/lib/cocoapods/external_sources.rb +57 -0
- data/lib/cocoapods/external_sources/abstract_external_source.rb +205 -0
- data/lib/cocoapods/external_sources/downloader_source.rb +30 -0
- data/lib/cocoapods/external_sources/path_source.rb +55 -0
- data/lib/cocoapods/external_sources/podspec_source.rb +54 -0
- data/lib/cocoapods/gem_version.rb +5 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +44 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +94 -0
- data/lib/cocoapods/generator/app_target_helper.rb +244 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/constant.rb +19 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +230 -0
- data/lib/cocoapods/generator/dummy_source.rb +31 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +215 -0
- data/lib/cocoapods/generator/header.rb +103 -0
- data/lib/cocoapods/generator/info_plist_file.rb +116 -0
- data/lib/cocoapods/generator/module_map.rb +99 -0
- data/lib/cocoapods/generator/prefix_header.rb +60 -0
- data/lib/cocoapods/generator/umbrella_header.rb +46 -0
- data/lib/cocoapods/hooks_manager.rb +132 -0
- data/lib/cocoapods/installer.rb +703 -0
- data/lib/cocoapods/installer/analyzer.rb +972 -0
- data/lib/cocoapods/installer/analyzer/analysis_result.rb +87 -0
- data/lib/cocoapods/installer/analyzer/locking_dependency_analyzer.rb +98 -0
- data/lib/cocoapods/installer/analyzer/pod_variant.rb +67 -0
- data/lib/cocoapods/installer/analyzer/pod_variant_set.rb +157 -0
- data/lib/cocoapods/installer/analyzer/podfile_dependency_cache.rb +54 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +240 -0
- data/lib/cocoapods/installer/analyzer/specs_state.rb +84 -0
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +53 -0
- data/lib/cocoapods/installer/analyzer/target_inspector.rb +260 -0
- data/lib/cocoapods/installer/installation_options.rb +158 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +202 -0
- data/lib/cocoapods/installer/pod_source_preparer.rb +77 -0
- data/lib/cocoapods/installer/podfile_validator.rb +139 -0
- data/lib/cocoapods/installer/post_install_hooks_context.rb +132 -0
- data/lib/cocoapods/installer/pre_install_hooks_context.rb +51 -0
- data/lib/cocoapods/installer/source_provider_hooks_context.rb +34 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +250 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +463 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator/xcconfig_integrator.rb +146 -0
- data/lib/cocoapods/installer/xcode.rb +8 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +416 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +181 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/app_host_installer.rb +84 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +334 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +777 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +116 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +86 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +256 -0
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer_helper.rb +68 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +147 -0
- data/lib/cocoapods/open-uri.rb +33 -0
- data/lib/cocoapods/project.rb +414 -0
- data/lib/cocoapods/resolver.rb +585 -0
- data/lib/cocoapods/resolver/lazy_specification.rb +79 -0
- data/lib/cocoapods/sandbox.rb +404 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +444 -0
- data/lib/cocoapods/sandbox/headers_store.rb +146 -0
- data/lib/cocoapods/sandbox/path_list.rb +220 -0
- data/lib/cocoapods/sandbox/pod_dir_cleaner.rb +85 -0
- data/lib/cocoapods/sandbox/podspec_finder.rb +23 -0
- data/lib/cocoapods/sources_manager.rb +157 -0
- data/lib/cocoapods/target.rb +261 -0
- data/lib/cocoapods/target/aggregate_target.rb +338 -0
- data/lib/cocoapods/target/build_settings.rb +1075 -0
- data/lib/cocoapods/target/pod_target.rb +559 -0
- data/lib/cocoapods/user_interface.rb +459 -0
- data/lib/cocoapods/user_interface/error_report.rb +187 -0
- data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
- data/lib/cocoapods/validator.rb +981 -0
- metadata +533 -0
@@ -0,0 +1,220 @@
|
|
1
|
+
require 'active_support/multibyte/unicode'
|
2
|
+
require 'find'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Sandbox
|
6
|
+
# The PathList class is designed to perform multiple glob matches against
|
7
|
+
# a given directory. Basically, it generates a list of all the children
|
8
|
+
# paths and matches the globs patterns against them, resulting in just one
|
9
|
+
# access to the file system.
|
10
|
+
#
|
11
|
+
# @note A PathList once it has generated the list of the paths this is
|
12
|
+
# updated only if explicitly requested by calling
|
13
|
+
# {#read_file_system}
|
14
|
+
#
|
15
|
+
class PathList
|
16
|
+
# @return [Pathname] The root of the list whose files and directories
|
17
|
+
# are used to perform the matching operations.
|
18
|
+
#
|
19
|
+
attr_reader :root
|
20
|
+
|
21
|
+
# Initialize a new instance
|
22
|
+
#
|
23
|
+
# @param [Pathname] root @see #root
|
24
|
+
#
|
25
|
+
def initialize(root)
|
26
|
+
root_dir = ActiveSupport::Multibyte::Unicode.normalize(root.to_s)
|
27
|
+
@root = Pathname.new(root_dir)
|
28
|
+
@glob_cache = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Array<String>] The list of absolute the path of all the files
|
32
|
+
# contained in {root}.
|
33
|
+
#
|
34
|
+
def files
|
35
|
+
read_file_system unless @files
|
36
|
+
@files
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array<String>] The list of absolute the path of all the
|
40
|
+
# directories contained in {root}.
|
41
|
+
#
|
42
|
+
def dirs
|
43
|
+
read_file_system unless @dirs
|
44
|
+
@dirs
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [void] Reads the file system and populates the files and paths
|
48
|
+
# lists.
|
49
|
+
#
|
50
|
+
def read_file_system
|
51
|
+
unless root.exist?
|
52
|
+
raise Informative, "Attempt to read non existent folder `#{root}`."
|
53
|
+
end
|
54
|
+
|
55
|
+
dirs = []
|
56
|
+
files = []
|
57
|
+
root_length = root.cleanpath.to_s.length + File::SEPARATOR.length
|
58
|
+
Find.find(root.to_s) do |f|
|
59
|
+
directory = File.directory?(f)
|
60
|
+
f = f.slice(root_length, f.length - root_length)
|
61
|
+
next if f.nil?
|
62
|
+
|
63
|
+
(directory ? dirs : files) << f
|
64
|
+
end
|
65
|
+
|
66
|
+
dirs.sort_by!(&:upcase)
|
67
|
+
files.sort_by!(&:upcase)
|
68
|
+
|
69
|
+
@dirs = dirs
|
70
|
+
@files = files
|
71
|
+
@glob_cache = {}
|
72
|
+
end
|
73
|
+
|
74
|
+
#-----------------------------------------------------------------------#
|
75
|
+
|
76
|
+
public
|
77
|
+
|
78
|
+
# @!group Globbing
|
79
|
+
|
80
|
+
# Similar to {glob} but returns the absolute paths.
|
81
|
+
#
|
82
|
+
# @param [String,Array<String>] patterns
|
83
|
+
# @see #relative_glob
|
84
|
+
#
|
85
|
+
# @param [Hash] options
|
86
|
+
# @see #relative_glob
|
87
|
+
#
|
88
|
+
# @return [Array<Pathname>]
|
89
|
+
#
|
90
|
+
def glob(patterns, options = {})
|
91
|
+
cache_key = options.merge(:patterns => patterns)
|
92
|
+
@glob_cache[cache_key] ||= relative_glob(patterns, options).map { |p| root.join(p) }
|
93
|
+
end
|
94
|
+
|
95
|
+
# The list of relative paths that are case insensitively matched by a
|
96
|
+
# given pattern. This method emulates {Dir#glob} with the
|
97
|
+
# {File::FNM_CASEFOLD} option.
|
98
|
+
#
|
99
|
+
# @param [String,Array<String>] patterns
|
100
|
+
# A single {Dir#glob} like pattern, or a list of patterns.
|
101
|
+
#
|
102
|
+
# @param [Hash] options
|
103
|
+
#
|
104
|
+
# @option options [String] :dir_pattern
|
105
|
+
# An optional pattern to append to a pattern, if it is the path
|
106
|
+
# to a directory.
|
107
|
+
#
|
108
|
+
# @option options [Array<String>] :exclude_patterns
|
109
|
+
# Exclude specific paths given by those patterns.
|
110
|
+
#
|
111
|
+
# @option options [Array<String>] :include_dirs
|
112
|
+
# Additional paths to take into account for matching.
|
113
|
+
#
|
114
|
+
# @return [Array<Pathname>]
|
115
|
+
#
|
116
|
+
def relative_glob(patterns, options = {})
|
117
|
+
return [] if patterns.empty?
|
118
|
+
|
119
|
+
dir_pattern = options[:dir_pattern]
|
120
|
+
exclude_patterns = options[:exclude_patterns]
|
121
|
+
include_dirs = options[:include_dirs]
|
122
|
+
|
123
|
+
if include_dirs
|
124
|
+
full_list = files + dirs
|
125
|
+
else
|
126
|
+
full_list = files
|
127
|
+
end
|
128
|
+
patterns_array = Array(patterns)
|
129
|
+
exact_matches = (full_list & patterns_array).to_set
|
130
|
+
|
131
|
+
unless patterns_array.empty?
|
132
|
+
list = patterns_array.flat_map do |pattern|
|
133
|
+
if exact_matches.include?(pattern)
|
134
|
+
pattern
|
135
|
+
else
|
136
|
+
if directory?(pattern) && dir_pattern
|
137
|
+
pattern += '/' unless pattern.end_with?('/')
|
138
|
+
pattern += dir_pattern
|
139
|
+
end
|
140
|
+
expanded_patterns = dir_glob_equivalent_patterns(pattern)
|
141
|
+
full_list.select do |path|
|
142
|
+
expanded_patterns.any? do |p|
|
143
|
+
File.fnmatch(p, path, File::FNM_CASEFOLD | File::FNM_PATHNAME)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
list = list.map { |path| Pathname.new(path) }
|
151
|
+
if exclude_patterns
|
152
|
+
exclude_options = { :dir_pattern => '**/*', :include_dirs => include_dirs }
|
153
|
+
list -= relative_glob(exclude_patterns, exclude_options)
|
154
|
+
end
|
155
|
+
list
|
156
|
+
end
|
157
|
+
|
158
|
+
#-----------------------------------------------------------------------#
|
159
|
+
|
160
|
+
private
|
161
|
+
|
162
|
+
# @!group Private helpers
|
163
|
+
|
164
|
+
# @return [Bool] Wether a path is a directory. The result of this method
|
165
|
+
# computed without accessing the file system and is case
|
166
|
+
# insensitive.
|
167
|
+
#
|
168
|
+
# @param [String, Pathname] sub_path The path that could be a directory.
|
169
|
+
#
|
170
|
+
def directory?(sub_path)
|
171
|
+
sub_path = sub_path.to_s.downcase.sub(/\/$/, '')
|
172
|
+
dirs.any? { |dir| dir.downcase == sub_path }
|
173
|
+
end
|
174
|
+
|
175
|
+
# @return [Array<String>] An array of patterns converted from a
|
176
|
+
# {Dir.glob} pattern to patterns that {File.fnmatch} can handle.
|
177
|
+
# This is used by the {#relative_glob} method to emulate
|
178
|
+
# {Dir.glob}.
|
179
|
+
#
|
180
|
+
# The expansion provides support for:
|
181
|
+
#
|
182
|
+
# - Literals
|
183
|
+
#
|
184
|
+
# dir_glob_equivalent_patterns('{file1,file2}.{h,m}')
|
185
|
+
# => ["file1.h", "file1.m", "file2.h", "file2.m"]
|
186
|
+
#
|
187
|
+
# - Matching the direct children of a directory with `**`
|
188
|
+
#
|
189
|
+
# dir_glob_equivalent_patterns('Classes/**/file.m')
|
190
|
+
# => ["Classes/**/file.m", "Classes/file.m"]
|
191
|
+
#
|
192
|
+
# @param [String] pattern A {Dir#glob} like pattern.
|
193
|
+
#
|
194
|
+
def dir_glob_equivalent_patterns(pattern)
|
195
|
+
pattern = pattern.gsub('/**/', '{/**/,/}')
|
196
|
+
values_by_set = {}
|
197
|
+
pattern.scan(/\{[^}]*\}/) do |set|
|
198
|
+
values = set.gsub(/[{}]/, '').split(',')
|
199
|
+
values_by_set[set] = values
|
200
|
+
end
|
201
|
+
|
202
|
+
if values_by_set.empty?
|
203
|
+
[pattern]
|
204
|
+
else
|
205
|
+
patterns = [pattern]
|
206
|
+
values_by_set.each do |set, values|
|
207
|
+
patterns = patterns.flat_map do |old_pattern|
|
208
|
+
values.map do |value|
|
209
|
+
old_pattern.gsub(set, value)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
patterns
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
#-----------------------------------------------------------------------#
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
class PodDirCleaner
|
4
|
+
attr_reader :root
|
5
|
+
attr_reader :specs_by_platform
|
6
|
+
|
7
|
+
def initialize(root, specs_by_platform)
|
8
|
+
@root = root
|
9
|
+
@specs_by_platform = specs_by_platform
|
10
|
+
end
|
11
|
+
|
12
|
+
# Removes all the files not needed for the installation according to the
|
13
|
+
# specs by platform.
|
14
|
+
#
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
def clean!
|
18
|
+
clean_paths.each { |path| FileUtils.rm_rf(path) } if root.exist?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @return [Array<Sandbox::FileAccessor>] the file accessors for all the
|
24
|
+
# specifications on their respective platform.
|
25
|
+
#
|
26
|
+
def file_accessors
|
27
|
+
@file_accessors ||= specs_by_platform.flat_map do |platform, specs|
|
28
|
+
specs.flat_map { |spec| Sandbox::FileAccessor.new(path_list, spec.consumer(platform)) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Sandbox::PathList] The path list for this Pod.
|
33
|
+
#
|
34
|
+
def path_list
|
35
|
+
@path_list ||= Sandbox::PathList.new(root)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Finds the absolute paths, including hidden ones, of the files
|
39
|
+
# that are not used by the pod and thus can be safely deleted.
|
40
|
+
#
|
41
|
+
# @note Implementation detail: Don't use `Dir#glob` as there is an
|
42
|
+
# unexplained issue (#568, #572 and #602).
|
43
|
+
#
|
44
|
+
# @todo The paths are down-cased for the comparison as issues similar
|
45
|
+
# to #602 lead the files not being matched and so cleaning all
|
46
|
+
# the files. This solution might create side effects.
|
47
|
+
#
|
48
|
+
# @return [Array<Strings>] The paths that can be deleted.
|
49
|
+
#
|
50
|
+
def clean_paths
|
51
|
+
cached_used = used_files
|
52
|
+
glob_options = File::FNM_DOTMATCH | File::FNM_CASEFOLD
|
53
|
+
files = Pathname.glob(root + '**/*', glob_options).map(&:to_s)
|
54
|
+
|
55
|
+
files.reject do |candidate|
|
56
|
+
candidate = candidate.downcase
|
57
|
+
candidate.end_with?('.', '..') || cached_used.any? do |path|
|
58
|
+
path = path.downcase
|
59
|
+
path.include?(candidate) || candidate.include?(path)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Array<String>] The absolute path of all the files used by the
|
65
|
+
# specifications (according to their platform) of this Pod.
|
66
|
+
#
|
67
|
+
def used_files
|
68
|
+
files = [
|
69
|
+
file_accessors.map(&:vendored_frameworks),
|
70
|
+
file_accessors.map(&:vendored_libraries),
|
71
|
+
file_accessors.map(&:resource_bundle_files),
|
72
|
+
file_accessors.map(&:license),
|
73
|
+
file_accessors.map(&:prefix_header),
|
74
|
+
file_accessors.map(&:preserve_paths),
|
75
|
+
file_accessors.map(&:readme),
|
76
|
+
file_accessors.map(&:resources),
|
77
|
+
file_accessors.map(&:source_files),
|
78
|
+
file_accessors.map(&:module_map),
|
79
|
+
]
|
80
|
+
|
81
|
+
files.flatten.compact.map(&:to_s).uniq
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
class PodspecFinder
|
4
|
+
attr_reader :root
|
5
|
+
|
6
|
+
def initialize(root)
|
7
|
+
@root = root
|
8
|
+
end
|
9
|
+
|
10
|
+
def podspecs
|
11
|
+
return @specs_by_name if @specs_by_name
|
12
|
+
@specs_by_name = {}
|
13
|
+
spec_files = Pathname.glob(root + '{,*}.podspec{,.json}')
|
14
|
+
spec_files.sort_by { |p| -p.to_path.split(File::SEPARATOR).size }.each do |file|
|
15
|
+
spec = Specification.from_file(file)
|
16
|
+
spec.validate_cocoapods_version
|
17
|
+
@specs_by_name[spec.name] = spec
|
18
|
+
end
|
19
|
+
@specs_by_name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'cocoapods-core/source'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Source
|
6
|
+
class Manager
|
7
|
+
# Returns the source whose {Source#url} is equal to `url`, adding the repo
|
8
|
+
# in a manner similarly to `pod repo add` if it is not found.
|
9
|
+
#
|
10
|
+
# @raise If no source with the given `url` could be created,
|
11
|
+
#
|
12
|
+
# @return [Source] The source whose {Source#url} is equal to `url`,
|
13
|
+
#
|
14
|
+
# @param [String] url
|
15
|
+
# The URL of the source.
|
16
|
+
#
|
17
|
+
def find_or_create_source_with_url(url)
|
18
|
+
unless source = source_with_url(url)
|
19
|
+
name = name_for_url(url)
|
20
|
+
# Hack to ensure that `repo add` output is shown.
|
21
|
+
previous_title_level = UI.title_level
|
22
|
+
UI.title_level = 0
|
23
|
+
begin
|
24
|
+
if name =~ /^master(-\d+)?$/
|
25
|
+
Command::Setup.parse([]).run
|
26
|
+
else
|
27
|
+
Command::Repo::Add.parse([name, url]).run
|
28
|
+
end
|
29
|
+
rescue Informative => e
|
30
|
+
message = "Unable to add a source with url `#{url}` " \
|
31
|
+
"named `#{name}`.\n"
|
32
|
+
message << "(#{e})\n" if Config.instance.verbose?
|
33
|
+
message << 'You can try adding it manually in ' \
|
34
|
+
"`#{Config.instance.repos_dir}` or via `pod repo add`."
|
35
|
+
raise Informative, message
|
36
|
+
ensure
|
37
|
+
UI.title_level = previous_title_level
|
38
|
+
end
|
39
|
+
source = source_with_url(url)
|
40
|
+
end
|
41
|
+
|
42
|
+
raise "Unable to create a source with URL #{url}" unless source
|
43
|
+
|
44
|
+
source
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the source whose {Source#name} or {Source#url} is equal to the
|
48
|
+
# given `name_or_url`.
|
49
|
+
#
|
50
|
+
# @return [Source] The source whose {Source#name} or {Source#url} is equal to the
|
51
|
+
# given `name_or_url`.
|
52
|
+
#
|
53
|
+
# @param [String] name_or_url
|
54
|
+
# The name or the URL of the source.
|
55
|
+
#
|
56
|
+
def source_with_name_or_url(name_or_url)
|
57
|
+
all.find { |s| s.name == name_or_url } ||
|
58
|
+
find_or_create_source_with_url(name_or_url)
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Pathname] The path where the search index should be stored.
|
62
|
+
#
|
63
|
+
def search_index_path
|
64
|
+
@search_index_path ||= Config.instance.search_index_file
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!group Updating Sources
|
68
|
+
|
69
|
+
# Updates the local clone of the spec-repo with the given name or of all
|
70
|
+
# the git repos if the name is omitted.
|
71
|
+
#
|
72
|
+
# @param [String] source_name
|
73
|
+
#
|
74
|
+
# @param [Bool] show_output
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
#
|
78
|
+
def update(source_name = nil, show_output = false)
|
79
|
+
if source_name
|
80
|
+
sources = [git_source_named(source_name)]
|
81
|
+
else
|
82
|
+
sources = git_sources
|
83
|
+
end
|
84
|
+
|
85
|
+
changed_spec_paths = {}
|
86
|
+
sources.each do |source|
|
87
|
+
UI.section "Updating spec repo `#{source.name}`" do
|
88
|
+
changed_source_paths = source.update(show_output)
|
89
|
+
changed_spec_paths[source] = changed_source_paths if changed_source_paths.count > 0
|
90
|
+
source.verify_compatibility!
|
91
|
+
end
|
92
|
+
end
|
93
|
+
# Perform search index update operation in background.
|
94
|
+
update_search_index_if_needed_in_background(changed_spec_paths)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
extend Executable
|
99
|
+
executable :git
|
100
|
+
|
101
|
+
def git(args, include_error: false)
|
102
|
+
Executable.capture_command('git', args, :capture => include_error ? :merge : :out).first.strip
|
103
|
+
end
|
104
|
+
|
105
|
+
def update_git_repo(show_output = false)
|
106
|
+
Config.instance.with_changes(:verbose => show_output) do
|
107
|
+
args = %W(-C #{repo} fetch origin)
|
108
|
+
args.push('--progress') if show_output
|
109
|
+
git!(args)
|
110
|
+
current_branch = git!(%W(-C #{repo} rev-parse --abbrev-ref HEAD)).strip
|
111
|
+
git!(%W(-C #{repo} reset --hard origin/#{current_branch}))
|
112
|
+
end
|
113
|
+
rescue
|
114
|
+
raise Informative, 'CocoaPods was not able to update the ' \
|
115
|
+
"`#{name}` repo. If this is an unexpected issue " \
|
116
|
+
'and persists you can inspect it running ' \
|
117
|
+
'`pod repo update --verbose`'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class MasterSource
|
122
|
+
def update_git_repo(show_output = false)
|
123
|
+
if repo.join('.git', 'shallow').file?
|
124
|
+
UI.info "Performing a deep fetch of the `#{name}` specs repo to improve future performance" do
|
125
|
+
git!(%W(-C #{repo} fetch --unshallow))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
super
|
129
|
+
end
|
130
|
+
|
131
|
+
def verify_compatibility!
|
132
|
+
super
|
133
|
+
latest_cocoapods_version = metadata.latest_cocoapods_version && Gem::Version.create(metadata.latest_cocoapods_version)
|
134
|
+
return unless Config.instance.new_version_message? &&
|
135
|
+
latest_cocoapods_version &&
|
136
|
+
latest_cocoapods_version > Gem::Version.new(Pod::VERSION)
|
137
|
+
|
138
|
+
rc = latest_cocoapods_version.prerelease?
|
139
|
+
install_message = !Pathname(__FILE__).dirname.writable? ? 'sudo ' : ''
|
140
|
+
install_message << 'gem install cocoapods'
|
141
|
+
install_message << ' --pre' if rc
|
142
|
+
message = [
|
143
|
+
'',
|
144
|
+
"CocoaPods #{latest_cocoapods_version} is available.".green,
|
145
|
+
"To update use: `#{install_message}`".green,
|
146
|
+
("[!] This is a test version we'd love you to try.".yellow if rc),
|
147
|
+
'',
|
148
|
+
'For more information, see https://blog.cocoapods.org ' \
|
149
|
+
'and the CHANGELOG for this version at ' \
|
150
|
+
"https://github.com/CocoaPods/CocoaPods/releases/tag/#{latest_cocoapods_version}".green,
|
151
|
+
'',
|
152
|
+
'',
|
153
|
+
].compact.join("\n")
|
154
|
+
UI.puts(message)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|