glob 0.1.0 → 0.2.0

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: fde0d275a3a9a027d30178a5975f94d947c9fa50a184349365d7e2f7cf0c33f8
4
- data.tar.gz: d69da7126314e270b9be1ed063a75027fe38e9a899633eb5dfe6ad2be974728e
3
+ metadata.gz: 1e44b2144da5a2fe785364209c7b4bce46a0e19768fe287b41cc8d8a7283e215
4
+ data.tar.gz: 774e63f4cafa984899b85599200de72785c7c2fa44a80c30ed11923495501ed6
5
5
  SHA512:
6
- metadata.gz: b2d6c9bcd1926c173326a2f10bc7fddaf2adeb906cf784ddc2d41484f3396481571df1af8ee08aa383a883f5f40da949e3bfbd6ba2fe0d9b1ea6f7ae080e6c2a
7
- data.tar.gz: a87b5a59497738eff53ff8e8c8765b645e849e1f2c39981ef3fde1eaef7d70dec34c9e762157c4a08308d5c37e5d18f7d5465106a8bfc5e778c3c014d5c4328e
6
+ metadata.gz: b52d46a9740468309250ceaadaae156db7b99eb5709a64bc36a66211a49ed37a4f7beeecce000fb4075c488651075e2f462291792b5629b441580902772d4818
7
+ data.tar.gz: 91046b7420418420fd507a9f09cc44f6dc50080011c81a5491af01276cecda296f6155ae4321156c294c6365be9fded1cbbb0a32e59e454857e24f923aef9f71
@@ -9,3 +9,7 @@ Metrics/BlockLength:
9
9
  Exclude:
10
10
  - test/**/*_test.rb
11
11
  - glob.gemspec
12
+
13
+ Metrics/ClassLength:
14
+ Exclude:
15
+ - test/**/*_test.rb
@@ -2,4 +2,9 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Allow rejecting patterns like `!*.activerecord`.
6
+ - New API.
7
+
8
+ ## v0.1.0
9
+
5
10
  - Initial release
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- glob (0.0.0)
4
+ glob (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.0)
10
+ docile (1.3.2)
10
11
  jaro_winkler (1.5.4)
12
+ json (2.3.0)
11
13
  minitest (5.13.0)
12
14
  minitest-utils (0.4.6)
13
15
  minitest
@@ -25,6 +27,11 @@ GEM
25
27
  unicode-display_width (>= 1.4.0, < 1.7)
26
28
  rubocop-fnando (0.0.3)
27
29
  ruby-progressbar (1.10.1)
30
+ simplecov (0.17.1)
31
+ docile (~> 1.1)
32
+ json (>= 1.8, < 3)
33
+ simplecov-html (~> 0.10.0)
34
+ simplecov-html (0.10.2)
28
35
  unicode-display_width (1.6.0)
29
36
 
30
37
  PLATFORMS
@@ -38,6 +45,7 @@ DEPENDENCIES
38
45
  rake
39
46
  rubocop
40
47
  rubocop-fnando
48
+ simplecov
41
49
 
42
50
  BUNDLED WITH
43
51
  2.0.2
data/README.md CHANGED
@@ -23,6 +23,13 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
+ There are two types of paths: `include` and `exclude`.
27
+
28
+ - The `include` path adds that node to the new hash.
29
+ - The `exclude` path is the one started by `!`, and will prevent that path from being added.
30
+
31
+ The latest rules have more precedence; that means that if you have the rule `*.messages.*`, then add a following rule as `!*.messages.bye`, all `*.messages.*` but `*.messages.bye` will be included.
32
+
26
33
  ```ruby
27
34
  glob = Glob.new(
28
35
  site: {
@@ -38,12 +45,12 @@ glob = Glob.new(
38
45
  }
39
46
  )
40
47
 
41
- result = glob.query("*.settings.*")
48
+ glob << "*.settings.*"
42
49
 
43
- result.paths
50
+ glob.paths
44
51
  #=> ["site.settings.name", "site.settings.url", "user.settings.name"]
45
52
 
46
- result.to_h
53
+ glob.to_h
47
54
  #=> {
48
55
  #=> site: {
49
56
  #=> settings: {
@@ -60,9 +67,6 @@ result.to_h
60
67
 
61
68
  Notice that the return result will have symbolized keys.
62
69
 
63
- If you're planning to do one-off searches, then you can use
64
- `Glob.query(target, paths)` instead.
65
-
66
70
  ## Development
67
71
 
68
72
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "glob"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "rake"
36
36
  spec.add_development_dependency "rubocop"
37
37
  spec.add_development_dependency "rubocop-fnando"
38
+ spec.add_development_dependency "simplecov"
38
39
  end
@@ -2,15 +2,18 @@
2
2
 
3
3
  require "glob/map"
4
4
  require "glob/query"
5
- require "glob/result"
5
+ require "glob/matcher"
6
+ require "glob/symbolize_keys"
6
7
  require "glob/version"
7
8
 
8
9
  module Glob
9
- def self.new(target)
10
- Query.new(target)
10
+ def self.filter(target, paths = ["*"])
11
+ glob = new(target)
12
+ paths.each {|path| glob.filter(path) }
13
+ glob.to_h
11
14
  end
12
15
 
13
- def self.query(target, query)
14
- Query.new(target).query(query)
16
+ def self.new(target)
17
+ Query.new(target)
15
18
  end
16
19
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glob
4
+ class Matcher
5
+ attr_reader :path, :regex
6
+
7
+ def initialize(path)
8
+ @path = path
9
+ @reject = path.start_with?("!")
10
+
11
+ pattern = Regexp.escape(path.gsub(/^!/, "")).gsub(/\\\*/, "[^.]+")
12
+ @regex = Regexp.new("^#{pattern}")
13
+ end
14
+
15
+ def match?(other)
16
+ other.match?(regex)
17
+ end
18
+
19
+ def include?
20
+ !reject?
21
+ end
22
+
23
+ def reject?
24
+ @reject
25
+ end
26
+ end
27
+ end
@@ -2,18 +2,54 @@
2
2
 
3
3
  module Glob
4
4
  class Query
5
+ attr_reader :matchers
6
+
5
7
  def initialize(target)
6
8
  @target = target
9
+ @matchers = []
10
+ end
11
+
12
+ def <<(path)
13
+ matchers << Matcher.new(path)
7
14
  end
15
+ alias filter <<
8
16
 
9
- def query(search)
10
- map = Map.call(@target)
11
- pattern = Regexp.escape(search).gsub(/\\\*/, "[^.]+")
12
- regex = Regexp.new("^#{pattern}")
17
+ def to_h
18
+ symbolized_target = SymbolizeKeys.call(@target)
19
+
20
+ paths.each_with_object({}) do |path, buffer|
21
+ segments = path.split(".").map(&:to_sym)
22
+ value = symbolized_target.dig(*segments)
23
+ set_path_value(segments, buffer, value)
24
+ end
25
+ end
26
+ alias to_hash to_h
13
27
 
14
- matches = map.select {|path| path.match?(regex) }
28
+ def paths
29
+ matches = map.map do |path|
30
+ results = matchers.select {|matcher| matcher.match?(path) }
31
+ [path, results]
32
+ end
33
+
34
+ matches
35
+ .select {|(_, results)| results.compact.last&.include? }
36
+ .map {|(path)| path }
37
+ .sort
38
+ end
39
+
40
+ private def map
41
+ @map ||= Map.call(@target)
42
+ end
15
43
 
16
- Result.new(paths: matches, target: @target)
44
+ private def set_path_value(segments, target, value)
45
+ while (segment = segments.shift)
46
+ if segments.empty?
47
+ target[segment] = value
48
+ else
49
+ target[segment] ||= {}
50
+ target = target[segment]
51
+ end
52
+ end
17
53
  end
18
54
  end
19
55
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Glob
4
+ module SymbolizeKeys
5
+ def self.call(target)
6
+ case target
7
+ when Hash
8
+ target.each_with_object({}) do |(key, value), buffer|
9
+ buffer[key.to_sym] = SymbolizeKeys.call(value)
10
+ end
11
+ when Array
12
+ target.map {|item| SymbolizeKeys.call(item) }
13
+ else
14
+ target
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Glob
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: Create a list of hash paths that match a given pattern. You can also
98
112
  generate a hash with only the matching paths.
99
113
  email:
@@ -114,11 +128,14 @@ files:
114
128
  - LICENSE.txt
115
129
  - README.md
116
130
  - Rakefile
131
+ - bin/console
132
+ - bin/setup
117
133
  - glob.gemspec
118
134
  - lib/glob.rb
119
135
  - lib/glob/map.rb
136
+ - lib/glob/matcher.rb
120
137
  - lib/glob/query.rb
121
- - lib/glob/result.rb
138
+ - lib/glob/symbolize_keys.rb
122
139
  - lib/glob/version.rb
123
140
  homepage: https://github.com/fnando/glob
124
141
  licenses:
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Glob
4
- class Result
5
- def initialize(target:, paths:)
6
- @target = target
7
- @paths = paths
8
- end
9
-
10
- def paths
11
- @paths.dup
12
- end
13
-
14
- def to_hash
15
- target = symbolize_keys(@target)
16
-
17
- @paths.each_with_object({}) do |path, buffer|
18
- segments = path.split(".").map(&:to_sym)
19
- value = target.dig(*segments)
20
- set_path_value(segments, buffer, value)
21
- end
22
- end
23
-
24
- def symbolize_keys(target)
25
- case target
26
- when Hash
27
- target.each_with_object({}) do |(key, value), buffer|
28
- buffer[key.to_sym] = symbolize_keys(value)
29
- end
30
- when Array
31
- target.map {|item| symbolize_keys(item) }
32
- else
33
- target
34
- end
35
- end
36
-
37
- def set_path_value(segments, target, value)
38
- while (segment = segments.shift)
39
- if segments.empty?
40
- target[segment] = value
41
- else
42
- target[segment] ||= {}
43
- target = target[segment]
44
- end
45
- end
46
- end
47
- end
48
- end