cocoapods-square-stable 0.19.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +1296 -0
- data/LICENSE +20 -0
- data/README.md +94 -0
- data/bin/pod +16 -0
- data/bin/sandbox-pod +120 -0
- data/lib/cocoapods.rb +77 -0
- data/lib/cocoapods/command.rb +116 -0
- data/lib/cocoapods/command/help.rb +23 -0
- data/lib/cocoapods/command/inter_process_communication.rb +178 -0
- data/lib/cocoapods/command/list.rb +77 -0
- data/lib/cocoapods/command/outdated.rb +56 -0
- data/lib/cocoapods/command/podfile_info.rb +91 -0
- data/lib/cocoapods/command/project.rb +88 -0
- data/lib/cocoapods/command/push.rb +172 -0
- data/lib/cocoapods/command/repo.rb +145 -0
- data/lib/cocoapods/command/search.rb +61 -0
- data/lib/cocoapods/command/setup.rb +134 -0
- data/lib/cocoapods/command/spec.rb +590 -0
- data/lib/cocoapods/config.rb +231 -0
- data/lib/cocoapods/downloader.rb +59 -0
- data/lib/cocoapods/executable.rb +118 -0
- data/lib/cocoapods/external_sources.rb +363 -0
- data/lib/cocoapods/file_list.rb +36 -0
- data/lib/cocoapods/gem_version.rb +7 -0
- data/lib/cocoapods/generator/acknowledgements.rb +107 -0
- data/lib/cocoapods/generator/acknowledgements/markdown.rb +40 -0
- data/lib/cocoapods/generator/acknowledgements/plist.rb +64 -0
- data/lib/cocoapods/generator/bridge_support.rb +22 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +54 -0
- data/lib/cocoapods/generator/dummy_source.rb +22 -0
- data/lib/cocoapods/generator/prefix_header.rb +82 -0
- data/lib/cocoapods/generator/target_environment_header.rb +86 -0
- data/lib/cocoapods/generator/xcconfig.rb +185 -0
- data/lib/cocoapods/hooks/installer_representation.rb +134 -0
- data/lib/cocoapods/hooks/library_representation.rb +94 -0
- data/lib/cocoapods/hooks/pod_representation.rb +74 -0
- data/lib/cocoapods/installer.rb +571 -0
- data/lib/cocoapods/installer/analyzer.rb +559 -0
- data/lib/cocoapods/installer/analyzer/sandbox_analyzer.rb +253 -0
- data/lib/cocoapods/installer/file_references_installer.rb +179 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +248 -0
- data/lib/cocoapods/installer/target_installer.rb +379 -0
- data/lib/cocoapods/installer/user_project_integrator.rb +180 -0
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +224 -0
- data/lib/cocoapods/library.rb +202 -0
- data/lib/cocoapods/open_uri.rb +24 -0
- data/lib/cocoapods/project.rb +209 -0
- data/lib/cocoapods/resolver.rb +212 -0
- data/lib/cocoapods/sandbox.rb +343 -0
- data/lib/cocoapods/sandbox/file_accessor.rb +217 -0
- data/lib/cocoapods/sandbox/headers_store.rb +96 -0
- data/lib/cocoapods/sandbox/path_list.rb +208 -0
- data/lib/cocoapods/sources_manager.rb +276 -0
- data/lib/cocoapods/user_interface.rb +304 -0
- data/lib/cocoapods/user_interface/error_report.rb +101 -0
- data/lib/cocoapods/validator.rb +350 -0
- metadata +238 -0
@@ -0,0 +1,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
|