globs 0.0.2 → 0.0.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/globs/version.rb +1 -1
- data/lib/globs.rb +97 -29
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 853fae28b48ce579ade6a922bb4198169c88e156fe9bde5a789b42a57073630c
|
|
4
|
+
data.tar.gz: fd6666c02bb0277079692af6112c13e6b073c452cd1b2cc77c8f509ba2031fd5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52b355fa6f04a5cb23a702875dd7c609304ab9728ee515a9fb0618db272a72cd6046b9d5a86b5981877424faa23c185e1b4c0f9b8ce5737cdadd5909f2a9f932
|
|
7
|
+
data.tar.gz: 7451f0ef91f72265744d3e424fa27659a50287eccc0bcacf0aeb102bdaff39a9ffe3704ed338a0bfb16160808cb43e5f9cd653ad52e966c4211c5b47695c1a6b
|
data/Gemfile.lock
CHANGED
data/lib/globs/version.rb
CHANGED
data/lib/globs.rb
CHANGED
|
@@ -3,20 +3,32 @@ require "globs/version"
|
|
|
3
3
|
# Container for Globs methods, currently only static as the public api
|
|
4
4
|
# footprint is relatively small.
|
|
5
5
|
#
|
|
6
|
-
# It should be noted that I'll be exceptionally verbose in the comments
|
|
7
|
-
# of this code as it's an interesting usecase for learning to combine
|
|
8
|
-
# map, flat_map, and reduce for permutation-type generators.
|
|
9
|
-
#
|
|
10
|
-
# More than likely I'll write a tutorial on how the code works later and
|
|
11
|
-
# link to it in these comments for the exceptionally curious. It'd be roughly
|
|
12
|
-
# a 2.5 / 5 for difficulty.
|
|
13
|
-
#
|
|
14
6
|
# @author baweaver
|
|
15
7
|
# @since 0.0.1
|
|
16
8
|
#
|
|
17
9
|
module Globs
|
|
18
10
|
extend self
|
|
19
11
|
|
|
12
|
+
# Opening brace of a Glob expression
|
|
13
|
+
OPENING_BRACE = /\{/
|
|
14
|
+
|
|
15
|
+
# Closing brace of a Glob expression
|
|
16
|
+
CLOSING_BRACE = /\}/
|
|
17
|
+
|
|
18
|
+
# StringScanner is not 0 indexed. Offset for index.
|
|
19
|
+
SCANNER_INDEX_OFFSET = 1
|
|
20
|
+
|
|
21
|
+
# We don't want to include the brace in our final set, so offset the index
|
|
22
|
+
# to compensate
|
|
23
|
+
BRACE_POSITION_OFFSET = 1
|
|
24
|
+
|
|
25
|
+
# Full positional offset for the braces and scanner's non-zero index
|
|
26
|
+
POSITION_OFFSET = SCANNER_INDEX_OFFSET + BRACE_POSITION_OFFSET
|
|
27
|
+
|
|
28
|
+
# End of the string position, used to clarify difference between
|
|
29
|
+
# explicit EOS and positional offsets
|
|
30
|
+
END_OF_STRING = -1
|
|
31
|
+
|
|
20
32
|
# Shorthand for `puts expand(str)` for outputting to STDOUT for
|
|
21
33
|
# unix-like piping.
|
|
22
34
|
#
|
|
@@ -36,6 +48,9 @@ module Globs
|
|
|
36
48
|
#
|
|
37
49
|
# @since 0.0.1
|
|
38
50
|
#
|
|
51
|
+
# @note
|
|
52
|
+
# Modified to use StringScanner in 0.0.3 for more accurate tokenization
|
|
53
|
+
#
|
|
39
54
|
# @example
|
|
40
55
|
#
|
|
41
56
|
# ```
|
|
@@ -43,38 +58,91 @@ module Globs
|
|
|
43
58
|
# => ["test.a.1.com", "test.a.2.com", "test.b.1.com", "test.b.2.com"]
|
|
44
59
|
# ```
|
|
45
60
|
#
|
|
46
|
-
# @note
|
|
47
|
-
# While this _could_ be made into a tokenization type process for speed
|
|
48
|
-
# reasons there's very little reason to do so immediately. The current
|
|
49
|
-
# implementation is far more proof of concept than anything.
|
|
50
|
-
#
|
|
51
|
-
# If speed needs to happen to arise from usage, PRs are welcome to
|
|
52
|
-
# optimize this method, but the public api should remain the same.
|
|
53
|
-
#
|
|
54
61
|
# @param string [String]
|
|
55
62
|
# Glob-like string to be expanded
|
|
56
63
|
#
|
|
57
64
|
# @return [Array[String]]
|
|
58
65
|
# All expansions of the glob-like string
|
|
59
66
|
def expand(string)
|
|
60
|
-
string
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
scanner = StringScanner.new(string)
|
|
68
|
+
results = ['']
|
|
69
|
+
|
|
70
|
+
until scanner.eos?
|
|
71
|
+
beginning = scanner.pos
|
|
72
|
+
start, finish = next_expression_positions!(scanner)
|
|
73
|
+
|
|
74
|
+
# There are no further expressions in the string if the start position is
|
|
75
|
+
# negative.
|
|
76
|
+
#
|
|
77
|
+
# Proceed to move the scanner's cursor to the end of the string and take
|
|
78
|
+
# the rest of the string to append to the current result items.
|
|
79
|
+
if start.negative?
|
|
80
|
+
scanner.pos = string.size
|
|
81
|
+
|
|
82
|
+
non_glob_str = string[beginning..END_OF_STRING]
|
|
83
|
+
expressions = ['']
|
|
84
|
+
else
|
|
85
|
+
non_glob_str = string[beginning..(start - POSITION_OFFSET)]
|
|
86
|
+
expressions = interpret_expression(string[start..finish])
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
resulting_expressions = expressions.map { |exp| non_glob_str + exp }
|
|
90
|
+
|
|
91
|
+
results = results.flat_map { |res|
|
|
92
|
+
resulting_expressions.map { |exp| res + exp }
|
|
65
93
|
}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
results
|
|
66
97
|
end
|
|
67
98
|
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
99
|
+
# Finds the beginning and end of the next expression set in the string. If
|
|
100
|
+
# an expression set is not found, it will return END_OF_STRING for either
|
|
101
|
+
# of the positions being absent.
|
|
102
|
+
#
|
|
103
|
+
# @since 0.0.3
|
|
71
104
|
#
|
|
72
|
-
# @
|
|
73
|
-
#
|
|
105
|
+
# @mutates
|
|
106
|
+
#
|
|
107
|
+
# @note
|
|
108
|
+
# This will mutate the given StringScanner and cause it to move its
|
|
109
|
+
# associated cursor to the end of the last-found expression.
|
|
110
|
+
#
|
|
111
|
+
# If an expression is not found, it will register the last known beginning
|
|
112
|
+
# position, as `scan_until` will simply return nil and not change the
|
|
113
|
+
# cursor position if something is not found.
|
|
114
|
+
#
|
|
115
|
+
# @param scanner [StringScanner]
|
|
116
|
+
# Current StringScanner being used to tokenize and scan the glob expression
|
|
117
|
+
# string
|
|
118
|
+
#
|
|
119
|
+
# @return [Array[Integer, Integer]]
|
|
120
|
+
# Starting and ending positions of the next expression, excluding braces
|
|
121
|
+
private def next_expression_positions!(scanner)
|
|
122
|
+
return [END_OF_STRING, END_OF_STRING] unless scanner.scan_until(OPENING_BRACE)
|
|
123
|
+
start = scanner.pos
|
|
124
|
+
|
|
125
|
+
return [start, END_OF_STRING] unless scanner.scan_until(CLOSING_BRACE)
|
|
126
|
+
finish = scanner.pos
|
|
127
|
+
|
|
128
|
+
[start, finish - POSITION_OFFSET]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Interprets a glob expression to extract permutatable items from it.
|
|
132
|
+
#
|
|
133
|
+
# @since 0.0.3
|
|
134
|
+
#
|
|
135
|
+
# @param string [String]
|
|
136
|
+
# String to interpret as a glob expression
|
|
74
137
|
#
|
|
75
138
|
# @return [Array[String]]
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
|
|
139
|
+
# Collection of permutable strings to iterate over when constructing a
|
|
140
|
+
# final glob set
|
|
141
|
+
private def interpret_expression(string)
|
|
142
|
+
string
|
|
143
|
+
.split(/, */)
|
|
144
|
+
.flat_map { |exp|
|
|
145
|
+
exp.include?('..') ? Range.new(*exp.split('..')).to_a : exp
|
|
146
|
+
}
|
|
79
147
|
end
|
|
80
148
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: globs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brandon Weaver
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-01-
|
|
11
|
+
date: 2019-01-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|