cocoapods-square-stable 0.19.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1296 -0
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/bin/pod +16 -0
- data/bin/sandbox-pod +120 -0
- data/lib/cocoapods.rb +77 -0
- data/lib/cocoapods/command.rb +116 -0
- data/lib/cocoapods/command/help.rb +23 -0
- data/lib/cocoapods/command/inter_process_communication.rb +178 -0
- data/lib/cocoapods/command/list.rb +77 -0
- data/lib/cocoapods/command/outdated.rb +56 -0
- data/lib/cocoapods/command/podfile_info.rb +91 -0
- data/lib/cocoapods/command/project.rb +88 -0
- data/lib/cocoapods/command/push.rb +172 -0
- data/lib/cocoapods/command/repo.rb +145 -0
- data/lib/cocoapods/command/search.rb +61 -0
- data/lib/cocoapods/command/setup.rb +134 -0
- data/lib/cocoapods/command/spec.rb +590 -0
- data/lib/cocoapods/config.rb +231 -0
- data/lib/cocoapods/downloader.rb +59 -0
- data/lib/cocoapods/executable.rb +118 -0
- data/lib/cocoapods/external_sources.rb +363 -0
- data/lib/cocoapods/file_list.rb +36 -0
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +40 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +64 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +54 -0
- data/lib/cocoapods/generator/dummy_source.rb +22 -0
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_environment_header.rb +86 -0
- data/lib/cocoapods/generator/xcconfig.rb +185 -0
- data/lib/cocoapods/hooks/installer_representation.rb +134 -0
- data/lib/cocoapods/hooks/library_representation.rb +94 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +571 -0
- data/lib/cocoapods/installer/analyzer.rb +559 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +248 -0
- data/lib/cocoapods/installer/target_installer.rb +379 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +180 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +224 -0
- data/lib/cocoapods/library.rb +202 -0
- data/lib/cocoapods/open_uri.rb +24 -0
- data/lib/cocoapods/project.rb +209 -0
- data/lib/cocoapods/resolver.rb +212 -0
- data/lib/cocoapods/sandbox.rb +343 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +217 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +208 -0
- data/lib/cocoapods/sources_manager.rb +276 -0
- data/lib/cocoapods/user_interface.rb +304 -0
- data/lib/cocoapods/user_interface/error_report.rb +101 -0
- data/lib/cocoapods/validator.rb +350 -0
- metadata +238 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
|
4
|
+
# Resolves the file patterns of a specification against its root directory,
|
5
|
+
# taking into account any exclude pattern and the default extensions to use
|
6
|
+
# for directories.
|
7
|
+
#
|
8
|
+
# @note The FileAccessor always returns absolute paths.
|
9
|
+
#
|
10
|
+
class FileAccessor
|
11
|
+
|
12
|
+
HEADER_EXTENSIONS = Xcodeproj::Constants::HEADER_FILES_EXTENSIONS
|
13
|
+
|
14
|
+
# @return [Sandbox::PathList] the directory where the source of the Pod
|
15
|
+
# is located.
|
16
|
+
#
|
17
|
+
attr_reader :path_list
|
18
|
+
|
19
|
+
# @return [Specification::Consumer] the consumer of the specification for
|
20
|
+
# which the file patterns should be resolved.
|
21
|
+
#
|
22
|
+
attr_reader :spec_consumer
|
23
|
+
|
24
|
+
# @param [Sandbox::PathList] path_list @see path_list
|
25
|
+
# @param [Specification::Consumer] spec_consumer @see spec_consumer
|
26
|
+
#
|
27
|
+
def initialize(path_list, spec_consumer)
|
28
|
+
@path_list = path_list
|
29
|
+
@spec_consumer = spec_consumer
|
30
|
+
|
31
|
+
unless @spec_consumer
|
32
|
+
raise Informative, "Attempt to initialize File Accessor without a specification consumer."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Pathname] the directory which contains the files of the Pod.
|
37
|
+
#
|
38
|
+
def root
|
39
|
+
path_list.root
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Specification] the specification.
|
43
|
+
#
|
44
|
+
def spec
|
45
|
+
spec_consumer.spec
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Specification] the platform used to consume the specification.
|
49
|
+
#
|
50
|
+
def platform_name
|
51
|
+
spec_consumer.platform_name
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String] A string suitable for debugging.
|
55
|
+
#
|
56
|
+
def inspect
|
57
|
+
"<#{self.class} spec=#{spec.name} platform=#{platform_name} root=#{path_list.root}>"
|
58
|
+
end
|
59
|
+
|
60
|
+
#-----------------------------------------------------------------------#
|
61
|
+
|
62
|
+
public
|
63
|
+
|
64
|
+
# @!group Paths
|
65
|
+
|
66
|
+
# @return [Array<Pathname>] the source files of the specification.
|
67
|
+
#
|
68
|
+
def source_files
|
69
|
+
paths_for_attribute(:source_files)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Array<Pathname>] the headers of the specification.
|
73
|
+
#
|
74
|
+
def headers
|
75
|
+
extensions = HEADER_EXTENSIONS
|
76
|
+
source_files.select { |f| extensions.include?(f.extname) }
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [Array<Pathname>] the public headers of the specification.
|
80
|
+
#
|
81
|
+
def public_headers
|
82
|
+
public_headers = paths_for_attribute(:public_header_files)
|
83
|
+
private_headers = paths_for_attribute(:private_header_files)
|
84
|
+
if public_headers.nil? || public_headers.empty?
|
85
|
+
header_files = headers
|
86
|
+
else
|
87
|
+
header_files = public_headers
|
88
|
+
end
|
89
|
+
header_files - private_headers
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [Hash{ Symbol => Array<Pathname> }] the resources of the
|
93
|
+
# specification grouped by destination.
|
94
|
+
#
|
95
|
+
def resources
|
96
|
+
paths_for_attribute(:resources, true)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @return [Array<Pathname>] the files of the specification to preserve.
|
100
|
+
#
|
101
|
+
def preserve_paths
|
102
|
+
paths_for_attribute(:preserve_paths, true)
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Pathname] The of the prefix header file of the specification.
|
106
|
+
#
|
107
|
+
def prefix_header
|
108
|
+
if spec_consumer.prefix_header_file
|
109
|
+
path_list.root + spec_consumer.prefix_header_file
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [Pathname] The path of the auto-detected README file.
|
114
|
+
#
|
115
|
+
def readme
|
116
|
+
path_list.glob(%w[ readme{*,.*} ]).first
|
117
|
+
end
|
118
|
+
|
119
|
+
# @return [Pathname] The path of the license file as indicated in the
|
120
|
+
# specification or auto-detected.
|
121
|
+
#
|
122
|
+
def license
|
123
|
+
if spec_consumer.spec.root.license[:file]
|
124
|
+
path_list.root + spec_consumer.spec.root.license[:file]
|
125
|
+
else
|
126
|
+
path_list.glob(%w[ licen{c,s}e{*,.*} ]).first
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
#-----------------------------------------------------------------------#
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
# @!group Private helpers
|
135
|
+
|
136
|
+
# Returns the list of the paths founds in the file system for the
|
137
|
+
# attribute with given name. It takes into account any dir pattern and
|
138
|
+
# any file excluded in the specification.
|
139
|
+
#
|
140
|
+
# @param [Symbol] attribute
|
141
|
+
# the name of the attribute.
|
142
|
+
#
|
143
|
+
# @return [Array<Pathname>] the paths.
|
144
|
+
#
|
145
|
+
def paths_for_attribute(attribute, include_dirs = false)
|
146
|
+
file_patterns = spec_consumer.send(attribute)
|
147
|
+
options = {
|
148
|
+
:exclude_patterns => spec_consumer.exclude_files,
|
149
|
+
:dir_pattern => glob_for_attribute(attribute),
|
150
|
+
:include_dirs => include_dirs,
|
151
|
+
}
|
152
|
+
expanded_paths(file_patterns, options)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns the pattern to use to glob a directory for an attribute.
|
156
|
+
#
|
157
|
+
# @param [Symbol] attribute
|
158
|
+
# the name of the attribute
|
159
|
+
#
|
160
|
+
# @return [String] the glob pattern.
|
161
|
+
#
|
162
|
+
# @todo Move to the cocoapods-core so it appears in the docs?
|
163
|
+
#
|
164
|
+
def glob_for_attribute(attrbute)
|
165
|
+
globs = {
|
166
|
+
:source_files => '*.{h,hpp,hh,m,mm,c,cpp}'.freeze,
|
167
|
+
:public_header_files => "*.{#{ HEADER_EXTENSIONS * ',' }}".freeze,
|
168
|
+
}
|
169
|
+
globs[attrbute]
|
170
|
+
end
|
171
|
+
|
172
|
+
# Matches the given patterns to the file present in the root of the path
|
173
|
+
# list.
|
174
|
+
#
|
175
|
+
# @param [Array<String, FileList>] patterns
|
176
|
+
# The patterns to expand.
|
177
|
+
#
|
178
|
+
# @param [String] dir_pattern
|
179
|
+
# The pattern to add to directories.
|
180
|
+
#
|
181
|
+
# @param [Array<String>] exclude_patterns
|
182
|
+
# The exclude patterns to pass to the PathList.
|
183
|
+
#
|
184
|
+
# @raise [Informative] If the pod does not exists.
|
185
|
+
#
|
186
|
+
# @return [Array<Pathname>] A list of the paths.
|
187
|
+
#
|
188
|
+
# @todo Implement case insensitive search
|
189
|
+
#
|
190
|
+
def expanded_paths(patterns, options = {})
|
191
|
+
return [] if patterns.empty?
|
192
|
+
|
193
|
+
file_lists = patterns.select { |p| p.is_a?(FileList) }
|
194
|
+
glob_patterns = patterns - file_lists
|
195
|
+
|
196
|
+
result = []
|
197
|
+
result << path_list.glob(glob_patterns, options)
|
198
|
+
result << file_lists.map do |file_list|
|
199
|
+
file_list.prepend_patterns(path_list.root)
|
200
|
+
file_list.glob
|
201
|
+
end
|
202
|
+
|
203
|
+
unless file_lists.empty?
|
204
|
+
# TODO Restore warning in 0.17 proper
|
205
|
+
# UI.warn "[#{spec_consumer.spec.name}] The usage of Rake FileList is deprecated. Use `exclude_files`."
|
206
|
+
end
|
207
|
+
|
208
|
+
result.flatten.compact.uniq
|
209
|
+
end
|
210
|
+
|
211
|
+
#-----------------------------------------------------------------------#
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
|
4
|
+
# Provides support for managing a header directory. It also keeps track of
|
5
|
+
# the header search paths.
|
6
|
+
#
|
7
|
+
class HeadersStore
|
8
|
+
|
9
|
+
# @return [Pathname] the absolute path of this header directory.
|
10
|
+
#
|
11
|
+
def root
|
12
|
+
@sandbox.root + @relative_path
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Sandbox] the sandbox where this header directory is stored.
|
16
|
+
#
|
17
|
+
attr_reader :sandbox
|
18
|
+
|
19
|
+
# @param [Sandbox] @see sandbox
|
20
|
+
#
|
21
|
+
# @param [String] relative_path
|
22
|
+
# the relative path to the sandbox root and hence to the Pods
|
23
|
+
# project.
|
24
|
+
#
|
25
|
+
def initialize(sandbox, relative_path)
|
26
|
+
@sandbox = sandbox
|
27
|
+
@relative_path = relative_path
|
28
|
+
@search_paths = [relative_path]
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Array<String>] All the search paths of the header directory in
|
32
|
+
# xcconfig format. The paths are specified relative to the pods
|
33
|
+
# root with the `${PODS_ROOT}` variable.
|
34
|
+
#
|
35
|
+
def search_paths
|
36
|
+
@search_paths.uniq.map { |path| "${PODS_ROOT}/#{path}" }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Removes the directory as it is regenerated from scratch during each
|
40
|
+
# installation.
|
41
|
+
#
|
42
|
+
# @return [void]
|
43
|
+
#
|
44
|
+
def implode!
|
45
|
+
root.rmtree if root.exist?
|
46
|
+
end
|
47
|
+
|
48
|
+
#-----------------------------------------------------------------------#
|
49
|
+
|
50
|
+
public
|
51
|
+
|
52
|
+
# @!group Adding headers
|
53
|
+
|
54
|
+
# Adds a header to the directory.
|
55
|
+
#
|
56
|
+
# @param [Pathname] namespace_path
|
57
|
+
# the path where the header file should be stored relative to the
|
58
|
+
# headers directory.
|
59
|
+
#
|
60
|
+
# @param [Pathname] relative_header_path
|
61
|
+
# the path of the header file relative to the sandbox.
|
62
|
+
#
|
63
|
+
# @note This method adds the files to the search paths.
|
64
|
+
#
|
65
|
+
# @return [Pathname]
|
66
|
+
#
|
67
|
+
def add_files(namespace, relative_header_paths)
|
68
|
+
add_search_path(namespace)
|
69
|
+
namespaced_path = root + namespace
|
70
|
+
namespaced_path.mkpath unless File.exist?(namespaced_path)
|
71
|
+
|
72
|
+
relative_header_paths.map do |relative_header_path|
|
73
|
+
source = (@sandbox.root + relative_header_path).relative_path_from(namespaced_path)
|
74
|
+
Dir.chdir(namespaced_path) do
|
75
|
+
FileUtils.ln_sf(source, relative_header_path.basename)
|
76
|
+
end
|
77
|
+
namespaced_path + relative_header_path.basename
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Adds an header search path to the sandbox.
|
82
|
+
#
|
83
|
+
# @param [Pathname] path
|
84
|
+
# the path tho add.
|
85
|
+
#
|
86
|
+
# @return [void]
|
87
|
+
#
|
88
|
+
def add_search_path(path)
|
89
|
+
@search_paths << Pathname.new(@relative_path) + path
|
90
|
+
end
|
91
|
+
|
92
|
+
#-----------------------------------------------------------------------#
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
|
4
|
+
# The PathList class is designed to perform multiple glob matches against
|
5
|
+
# a given directory. Basically, it generates a list of all the children
|
6
|
+
# paths and matches the globs patterns against them, resulting in just one
|
7
|
+
# access to the file system.
|
8
|
+
#
|
9
|
+
# @note A PathList once it has generated the list of the paths this is
|
10
|
+
# updated only if explicitly requested by calling
|
11
|
+
# {#read_file_system}
|
12
|
+
#
|
13
|
+
class PathList
|
14
|
+
|
15
|
+
# @return [Pathname] The root of the list whose files and directories
|
16
|
+
# are used to perform the matching operations.
|
17
|
+
#
|
18
|
+
attr_accessor :root
|
19
|
+
|
20
|
+
# @param [Pathname] root The root of the PathList.
|
21
|
+
#
|
22
|
+
def initialize(root)
|
23
|
+
@root = root
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Array<String>] The list of absolute the path of all the files
|
27
|
+
# contained in {root}.
|
28
|
+
#
|
29
|
+
def files
|
30
|
+
read_file_system unless @files
|
31
|
+
@files
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Array<String>] The list of absolute the path of all the
|
35
|
+
# directories contained in {root}.
|
36
|
+
#
|
37
|
+
def dirs
|
38
|
+
read_file_system unless @dirs
|
39
|
+
@dirs
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [void] Reads the file system and populates the files and paths
|
43
|
+
# lists.
|
44
|
+
#
|
45
|
+
def read_file_system
|
46
|
+
unless root.exist?
|
47
|
+
raise Informative, "Attempt to read non existent folder `#{root}`."
|
48
|
+
end
|
49
|
+
root_length = root.to_s.length+1
|
50
|
+
escaped_root = escape_path_for_glob(root)
|
51
|
+
paths = Dir.glob(escaped_root + "**/*", File::FNM_DOTMATCH)
|
52
|
+
absolute_dirs = paths.select { |path| File.directory?(path) }
|
53
|
+
relative_dirs = absolute_dirs.map { |p| p[root_length..-1] }
|
54
|
+
absolute_paths = paths.reject { |p| p == "#{root}/." || p == "#{root}/.." }
|
55
|
+
relative_paths = absolute_paths.map { |p| p[root_length..-1] }
|
56
|
+
@files = relative_paths - relative_dirs
|
57
|
+
@dirs = relative_dirs.map { |d| d.gsub(/\/\.\.?$/,'') }.reject { |d| d == '.' || d == '..' } .uniq
|
58
|
+
end
|
59
|
+
|
60
|
+
#-----------------------------------------------------------------------#
|
61
|
+
|
62
|
+
public
|
63
|
+
|
64
|
+
# @!group Globbing
|
65
|
+
|
66
|
+
# @return [Array<Pathname>] Similar to {glob} but returns the absolute
|
67
|
+
# paths.
|
68
|
+
#
|
69
|
+
def glob(patterns, options = {})
|
70
|
+
relative_glob(patterns, options).map {|p| root + p }
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Array<Pathname>] The list of relative paths that are case
|
74
|
+
# insensitively matched by a given pattern. This method emulates
|
75
|
+
# {Dir#glob} with the {File::FNM_CASEFOLD} option.
|
76
|
+
#
|
77
|
+
# @param [String,Array<String>] patterns
|
78
|
+
# A single {Dir#glob} like pattern, or a list of patterns.
|
79
|
+
#
|
80
|
+
# @param [String] dir_pattern
|
81
|
+
# An optional pattern to append to a pattern, if it is the path
|
82
|
+
# to a directory.
|
83
|
+
#
|
84
|
+
def relative_glob(patterns, options = {})
|
85
|
+
return [] if patterns.empty?
|
86
|
+
|
87
|
+
dir_pattern = options[:dir_pattern]
|
88
|
+
exclude_patterns = options[:exclude_patterns]
|
89
|
+
include_dirs = options[:include_dirs]
|
90
|
+
|
91
|
+
if include_dirs
|
92
|
+
full_list = files + dirs
|
93
|
+
else
|
94
|
+
full_list = files
|
95
|
+
end
|
96
|
+
|
97
|
+
list = Array(patterns).map do |pattern|
|
98
|
+
if pattern.is_a?(String)
|
99
|
+
if directory?(pattern) && dir_pattern
|
100
|
+
pattern += '/' unless pattern.end_with?('/')
|
101
|
+
pattern += dir_pattern
|
102
|
+
end
|
103
|
+
expanded_patterns = dir_glob_equivalent_patterns(pattern)
|
104
|
+
full_list.select do |path|
|
105
|
+
expanded_patterns.any? do |p|
|
106
|
+
if p.respond_to? 'force_encoding'
|
107
|
+
p.force_encoding('UTF-8')
|
108
|
+
path.force_encoding('UTF-8')
|
109
|
+
end
|
110
|
+
File.fnmatch(p, path, File::FNM_CASEFOLD | File::FNM_PATHNAME)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
else
|
114
|
+
full_list.select { |path| path.match(pattern) }
|
115
|
+
end
|
116
|
+
end.flatten
|
117
|
+
|
118
|
+
list = list.map { |path| Pathname.new(path) }
|
119
|
+
if exclude_patterns
|
120
|
+
exclude_options = { :dir_pattern => '**/*', :include_dirs => include_dirs }
|
121
|
+
list -= relative_glob(exclude_patterns, exclude_options)
|
122
|
+
end
|
123
|
+
list
|
124
|
+
end
|
125
|
+
|
126
|
+
#-----------------------------------------------------------------------#
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# @!group Private helpers
|
131
|
+
|
132
|
+
# @return [Bool] Wether a path is a directory. The result of this method
|
133
|
+
# computed without accessing the file system and is case
|
134
|
+
# insensitive.
|
135
|
+
#
|
136
|
+
# @param [String, Pathname] sub_path The path that could be a directory.
|
137
|
+
#
|
138
|
+
def directory?(sub_path)
|
139
|
+
sub_path = sub_path.to_s.downcase.sub(/\/$/, '')
|
140
|
+
dirs.any? { |dir| dir.downcase == sub_path }
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Array<String>] An array of patterns converted from a
|
144
|
+
# {Dir.glob} pattern to patterns that {File.fnmatch} can handle.
|
145
|
+
# This is used by the {#relative_glob} method to emulate
|
146
|
+
# {Dir.glob}.
|
147
|
+
#
|
148
|
+
# The expansion provides support for:
|
149
|
+
#
|
150
|
+
# - Literals
|
151
|
+
#
|
152
|
+
# dir_glob_equivalent_patterns('{file1,file2}.{h,m}')
|
153
|
+
# => ["file1.h", "file1.m", "file2.h", "file2.m"]
|
154
|
+
#
|
155
|
+
# - Matching the direct children of a directory with `**`
|
156
|
+
#
|
157
|
+
# dir_glob_equivalent_patterns('Classes/**/file.m')
|
158
|
+
# => ["Classes/**/file.m", "Classes/file.m"]
|
159
|
+
#
|
160
|
+
# @param [String] pattern A {Dir#glob} like pattern.
|
161
|
+
#
|
162
|
+
def dir_glob_equivalent_patterns(pattern)
|
163
|
+
pattern = pattern.gsub('/**/', '{/**/,/}')
|
164
|
+
values_by_set = {}
|
165
|
+
pattern.scan(/\{[^}]*\}/) do |set|
|
166
|
+
values = set.gsub(/[{}]/, '').split(',')
|
167
|
+
values_by_set[set] = values
|
168
|
+
end
|
169
|
+
|
170
|
+
if values_by_set.empty?
|
171
|
+
[ pattern ]
|
172
|
+
else
|
173
|
+
patterns = [ pattern ]
|
174
|
+
values_by_set.each do |set, values|
|
175
|
+
patterns = patterns.map do |old_pattern|
|
176
|
+
values.map do |value|
|
177
|
+
old_pattern.gsub(set, value)
|
178
|
+
end
|
179
|
+
end.flatten
|
180
|
+
end
|
181
|
+
patterns
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Escapes the glob metacharacters from a given path so it can used in
|
186
|
+
# Dir#glob and similar methods.
|
187
|
+
#
|
188
|
+
# @note See CocoaPods/CocoaPods#862.
|
189
|
+
#
|
190
|
+
# @param [String, Pathname] path
|
191
|
+
# The path to escape.
|
192
|
+
#
|
193
|
+
# @return [Pathname] The escaped path.
|
194
|
+
#
|
195
|
+
def escape_path_for_glob(path)
|
196
|
+
result = path.to_s
|
197
|
+
characters_to_escape = ['[', ']', '{', '}', '?', '*']
|
198
|
+
characters_to_escape.each do |character|
|
199
|
+
result.gsub!(character, "\\#{character}" )
|
200
|
+
end
|
201
|
+
Pathname.new(result)
|
202
|
+
end
|
203
|
+
|
204
|
+
#-----------------------------------------------------------------------#
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|