glob 0.3.1 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: daa19b4757ede88d7bc2ff99732f6e0a42b33608fbbef748c21c18f73a01538c
4
- data.tar.gz: c8ee66c99f7ce11218ff7fc4031ad0a53e8fe7afb9eaa0de8b9220be92c88690
3
+ metadata.gz: 0a7c2fc46f05a01010dc0b3d6541528e3ec339103adcdda5621265cbd10c0b77
4
+ data.tar.gz: c335a9778db574f36d1a3c0da2119f42ddec83b91e2d7024b4d265122149e493
5
5
  SHA512:
6
- metadata.gz: 56d9f2f4ba26236f4ce29c51a806c6a158c5576222ab2ccc7d801423a6be0ae759ef2b8db21f465d03de2f97aac4b2b7de0a21dcc9d35ceaa74397e720783014
7
- data.tar.gz: 8ebc481895cc295261e1914b690ccd4b3807419564c833e258a9efccabf8f2ead910e599007e663227821ca7d03ced3dae9dc491608c832f8e0886956dce579a
6
+ metadata.gz: 756f0564e9e192ce4c975bfdfcd299acffceab70f47b4e34c49d3180cc0887e6933a0b87ee3583ac37fadd3401e420b0e43f7e8776f072b8ae91e154b51b3adc
7
+ data.tar.gz: ba1fe966b7cfef2f0d8d78e417132ea1b60466b4732002519bd398822115fe8751e7d8525050cee72be3f4375320861240510a2fb75deb4eb3ba7aa7bd605f71
@@ -19,12 +19,12 @@ jobs:
19
19
  strategy:
20
20
  fail-fast: false
21
21
  matrix:
22
- ruby: ["2.7", "3.0", "3.1"]
22
+ ruby: ["3.0", "3.1", "3.2", "3.3"]
23
23
  gemfile:
24
24
  - Gemfile
25
25
 
26
26
  steps:
27
- - uses: actions/checkout@v3
27
+ - uses: actions/checkout@v4
28
28
 
29
29
  - uses: actions/cache@v3
30
30
  with:
data/CHANGELOG.md CHANGED
@@ -11,6 +11,15 @@ Prefix your message with one of the following:
11
11
  - [Security] in case of vulnerabilities.
12
12
  -->
13
13
 
14
+ ## v0.4.1 - 2024-01-03
15
+
16
+ - [Fixed] Fix partial matching when not using `*`.
17
+
18
+ ## v0.4.0 - 2022-12-05
19
+
20
+ - [Changed] `Glob::Query` has been renamed to `Glob::Object`.
21
+ - [Added] Allow adding new keys with `glob.set(path, value)`.
22
+
14
23
  ## v0.3.1 - 2022-09-01
15
24
 
16
25
  - [Fixed] Handle keys with dots properly by using `\\.` as a escape sequence.
data/README.md CHANGED
@@ -72,7 +72,7 @@ glob.to_h
72
72
 
73
73
  Notice that the return result will have symbolized keys.
74
74
 
75
- If the contains dots, then the result will use `\\.` as the escape sequence.
75
+ If the key contain dots, then the result will use `\\.` as the escape sequence.
76
76
  Similarly, you need to escape keys with dots when filtering results.
77
77
 
78
78
  ```ruby
@@ -104,6 +104,29 @@ glob.to_h
104
104
  #=> {:formats=>{:".rb"=>"Ruby"}}
105
105
  ```
106
106
 
107
+ You can set new keys by using `.set(path, value)`:
108
+
109
+ ```ruby
110
+ glob = Glob.new
111
+ glob << "*"
112
+ glob.set "a.b.c", "hello"
113
+
114
+ glob.to_h
115
+ #=> {:a=>{:b=>{:c=>"hello"}}}
116
+
117
+ glob.paths
118
+ #=> ["a.b.c"]
119
+
120
+ # The non-hash value will be replaced in case the new path overlaps it
121
+ glob.set "a.b.c.d.e", "hello"
122
+
123
+ glob.to_h
124
+ #=> {:a=>{:b=>{:c=>{:d=>{:e=>"hello"}}}}}
125
+
126
+ glob.paths
127
+ #=> ["a.b.c.d.e"]
128
+ ```
129
+
107
130
  ## Maintainer
108
131
 
109
132
  - [Nando Vieira](https://github.com/fnando)
data/glob.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./lib/glob/version"
3
+ require_relative "lib/glob/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "glob"
data/lib/glob/map.rb CHANGED
@@ -7,7 +7,6 @@ module Glob
7
7
  end
8
8
 
9
9
  def initialize(target)
10
- @keys = []
11
10
  @target = target
12
11
  end
13
12
 
data/lib/glob/matcher.rb CHANGED
@@ -10,8 +10,9 @@ module Glob
10
10
 
11
11
  pattern = Regexp.escape(path.gsub(/^!/, ""))
12
12
  .gsub(/(\\{.*?\\})/) {|match| process_group(match) }
13
- .gsub(/\\\*/, "[^.]+")
14
- @regex = Regexp.new("^#{pattern}")
13
+ .gsub("\\*", "[^.]+")
14
+ anchor = path.end_with?("*") ? "" : "$"
15
+ @regex = Regexp.new("^#{pattern}#{anchor}")
15
16
  end
16
17
 
17
18
  def match?(other)
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glob
4
- class Query
4
+ class Object
5
+ PATH_SPLIT_RE = /(?<!\\)\./.freeze
6
+
5
7
  attr_reader :matchers
6
8
 
7
9
  def initialize(target)
@@ -18,13 +20,20 @@ module Glob
18
20
  symbolized_target = SymbolizeKeys.call(@target)
19
21
 
20
22
  paths.each_with_object({}) do |path, buffer|
21
- segments = path.split(/(?<!\\)\./).map {|key| unescape(key).to_sym }
23
+ segments = path.split(PATH_SPLIT_RE).map {|key| unescape(key).to_sym }
22
24
  value = symbolized_target.dig(*segments)
23
25
  set_path_value(segments, buffer, value)
24
26
  end
25
27
  end
26
28
  alias to_hash to_h
27
29
 
30
+ def set(path, value)
31
+ set_path_value(path.split(PATH_SPLIT_RE), @target, value)
32
+ @map = Map.call(@target)
33
+
34
+ nil
35
+ end
36
+
28
37
  def paths
29
38
  matches = map.map do |path|
30
39
  results = matchers.select {|matcher| matcher.match?(path) } # rubocop:disable Style/SelectByRegexp
@@ -42,15 +51,18 @@ module Glob
42
51
  end
43
52
 
44
53
  private def unescape(key)
45
- key.to_s.gsub(/\\\./, ".")
54
+ key.to_s.gsub("\\.", ".")
46
55
  end
47
56
 
48
57
  private def set_path_value(segments, target, value)
58
+ segments = segments.dup.map(&:to_sym)
59
+
49
60
  while (segment = segments.shift)
50
61
  if segments.empty?
51
62
  target[segment] = value
52
63
  else
53
64
  target[segment] ||= {}
65
+ target[segment] = {} unless target[segment].is_a?(Hash)
54
66
  target = target[segment]
55
67
  end
56
68
  end
data/lib/glob/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glob
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.1"
5
5
  end
data/lib/glob.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "glob/map"
4
- require "glob/query"
5
- require "glob/matcher"
6
- require "glob/symbolize_keys"
7
- require "glob/version"
3
+ require_relative "glob/map"
4
+ require_relative "glob/object"
5
+ require_relative "glob/matcher"
6
+ require_relative "glob/symbolize_keys"
7
+ require_relative "glob/version"
8
8
 
9
9
  module Glob
10
10
  def self.filter(target, paths = ["*"])
@@ -13,7 +13,7 @@ module Glob
13
13
  glob.to_h
14
14
  end
15
15
 
16
- def self.new(target)
17
- Query.new(target)
16
+ def self.new(target = {})
17
+ Object.new(target)
18
18
  end
19
19
  end
data/test/glob_test.rb CHANGED
@@ -3,6 +3,17 @@
3
3
  require "test_helper"
4
4
 
5
5
  class GlobTest < Minitest::Test
6
+ test "with partial matching" do
7
+ glob = Glob.new(
8
+ en: {editor: "editor", edit: "edit"},
9
+ pt: {editor: "editor", edit: "edit"}
10
+ )
11
+
12
+ glob << "*.edit"
13
+
14
+ assert_equal ["en.edit", "pt.edit"], glob.paths
15
+ end
16
+
6
17
  test "with rejecting filter" do
7
18
  glob = Glob.new(
8
19
  en: {
@@ -240,4 +251,40 @@ class GlobTest < Minitest::Test
240
251
  assert_equal ({node: {"more.keys.with.dots": "more dots"}}),
241
252
  Glob.filter(data, ["node.more\\.keys\\.with\\.dots"])
242
253
  end
254
+
255
+ test "sorts set when setting new keys" do
256
+ data = {d: "d", a: "a", b: "b"}
257
+
258
+ glob = Glob.new(data)
259
+ glob << "*"
260
+
261
+ assert_equal({a: "a", b: "b", d: "d"}, glob.to_h)
262
+
263
+ glob.set("c", "c")
264
+ glob.set("e.b1.b2.b3", "e---b")
265
+ glob.set("e.a1.a2.a3", "e---a")
266
+
267
+ expected = {
268
+ a: "a", b: "b", c: "c", d: "d",
269
+ e: {a1: {a2: {a3: "e---a"}}, b1: {b2: {b3: "e---b"}}}
270
+ }
271
+
272
+ assert_equal(expected, glob.to_h)
273
+ assert_equal ["a", "b", "c", "d", "e.a1.a2.a3", "e.b1.b2.b3"], glob.paths
274
+ end
275
+
276
+ test "replaces existing node when setting a new path" do
277
+ glob = Glob.new(a: 1, b: {b1: {b2: 2}})
278
+ glob << "*"
279
+ glob.set("a.a1.a2", 4)
280
+ glob.set("b.b1.b2.b3", {b4: 5})
281
+
282
+ expected = {
283
+ a: {a1: {a2: 4}},
284
+ b: {b1: {b2: {b3: {b4: 5}}}}
285
+ }
286
+
287
+ assert_equal expected, glob.to_h
288
+ assert_equal ["a.a1.a2", "b.b1.b2.b3.b4"], glob.paths
289
+ end
243
290
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-01 00:00:00.000000000 Z
11
+ date: 2024-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -138,7 +138,7 @@ files:
138
138
  - lib/glob.rb
139
139
  - lib/glob/map.rb
140
140
  - lib/glob/matcher.rb
141
- - lib/glob/query.rb
141
+ - lib/glob/object.rb
142
142
  - lib/glob/symbolize_keys.rb
143
143
  - lib/glob/version.rb
144
144
  - test/glob/map_test.rb
@@ -152,10 +152,10 @@ metadata:
152
152
  rubygems_mfa_required: 'true'
153
153
  homepage_uri: https://github.com/fnando/glob
154
154
  bug_tracker_uri: https://github.com/fnando/glob/issues
155
- source_code_uri: https://github.com/fnando/glob/tree/v0.3.1
156
- changelog_uri: https://github.com/fnando/glob/tree/v0.3.1/CHANGELOG.md
157
- documentation_uri: https://github.com/fnando/glob/tree/v0.3.1/README.md
158
- license_uri: https://github.com/fnando/glob/tree/v0.3.1/LICENSE.md
155
+ source_code_uri: https://github.com/fnando/glob/tree/v0.4.1
156
+ changelog_uri: https://github.com/fnando/glob/tree/v0.4.1/CHANGELOG.md
157
+ documentation_uri: https://github.com/fnando/glob/tree/v0.4.1/README.md
158
+ license_uri: https://github.com/fnando/glob/tree/v0.4.1/LICENSE.md
159
159
  post_install_message:
160
160
  rdoc_options: []
161
161
  require_paths:
@@ -171,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
173
  requirements: []
174
- rubygems_version: 3.3.7
174
+ rubygems_version: 3.4.19
175
175
  signing_key:
176
176
  specification_version: 4
177
177
  summary: Create a list of hash paths that match a given pattern. You can also generate