key_tree 0.5.2 → 0.8.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 +4 -4
- data/.github/workflows/ruby.yml +37 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +15 -4
- data/CHANGELOG.md +222 -0
- data/Gemfile +4 -8
- data/README.md +6 -1
- data/Rakefile +2 -0
- data/bin/console +5 -4
- data/bin/setup +0 -1
- data/key_tree.gemspec +20 -7
- data/lib/key_tree.rb +70 -70
- data/lib/key_tree/forest.rb +58 -26
- data/lib/key_tree/loader.rb +19 -16
- data/lib/key_tree/loader/nil.rb +2 -0
- data/lib/key_tree/meta_data.rb +3 -1
- data/lib/key_tree/path.rb +32 -40
- data/lib/key_tree/refine/deep_hash.rb +157 -0
- data/lib/key_tree/refinements.rb +40 -0
- data/lib/key_tree/tree.rb +101 -74
- data/lib/key_tree/version.rb +8 -4
- data/ruby-keytree.sublime-project +8 -0
- metadata +110 -21
- data/.travis.yml +0 -5
- data/RELEASE_NOTES.md +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efcddf672d03cea0d0be86a2bf3dd9fdd64b072410a941622172dda485e41455
|
4
|
+
data.tar.gz: 361648de4ff9c43340b149716bc8beb1ff46960ee48e5dc0b00717c60b017c53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28cda54bf66db156d0c723613f94b94a6535947821dbfc896f00a5f2c8861f8680bc5a23fb6198b97c804ddf8ee0d25654b73e45b174c7319059187fc1394b0e
|
7
|
+
data.tar.gz: d0cb7b5c81e267909a7d861d8f1961e0e94e13a839e16aad13f736626d8be6953db87804d2d99ca7af5395a048d164ef0fd8e981cbf891d05af2c2b964186acb
|
@@ -0,0 +1,37 @@
|
|
1
|
+
%YAML 1.1
|
2
|
+
---
|
3
|
+
# This workflow uses actions that are not certified by GitHub.
|
4
|
+
# They are provided by a third-party and are governed by
|
5
|
+
# separate terms of service, privacy policy, and support
|
6
|
+
# documentation.
|
7
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
8
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
9
|
+
|
10
|
+
name: Ruby
|
11
|
+
|
12
|
+
on:
|
13
|
+
push:
|
14
|
+
pull_request:
|
15
|
+
branches: [ main ]
|
16
|
+
|
17
|
+
jobs:
|
18
|
+
test:
|
19
|
+
|
20
|
+
runs-on: ubuntu-latest
|
21
|
+
strategy:
|
22
|
+
matrix:
|
23
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
24
|
+
|
25
|
+
steps:
|
26
|
+
- uses: actions/checkout@v2
|
27
|
+
- name: Set up Ruby
|
28
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
29
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
30
|
+
# uses: ruby/setup-ruby@v1
|
31
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
32
|
+
with:
|
33
|
+
ruby-version: ${{ matrix.ruby-version }}
|
34
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
35
|
+
- name: Run tests
|
36
|
+
run: bundle exec rake
|
37
|
+
...
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
%YAML 1.1
|
2
|
+
---
|
3
|
+
AllCops:
|
4
|
+
TargetRubyVersion: 2.6
|
5
|
+
NewCops: enable
|
6
|
+
|
1
7
|
Metrics/BlockLength:
|
2
8
|
Exclude:
|
3
9
|
- 'spec/*_spec.rb'
|
@@ -6,7 +12,12 @@ Style/BlockDelimiters:
|
|
6
12
|
Exclude:
|
7
13
|
- 'spec/*_spec.rb'
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
Style/HashEachMethods:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
Style/HashTransformKeys:
|
19
|
+
Enabled: true
|
20
|
+
|
21
|
+
Style/HashTransformValues:
|
22
|
+
Enabled: true
|
23
|
+
...
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
Older releases uses an ad-hoc release notes format, and follow at the end.
|
8
|
+
|
9
|
+
|
10
|
+
## [Unreleased]
|
11
|
+
|
12
|
+
|
13
|
+
## [0.8.0]
|
14
|
+
|
15
|
+
This release bumps minimum Ruby version to 2.6, and adds support for Ruby version 3.
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- Supports Ruby version 3.
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Updated dependencies.
|
24
|
+
|
25
|
+
|
26
|
+
## [0.7.0] - 2019-07-16
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
|
30
|
+
- Removed leftover private methods from `KeyTree::Forest`, `#tree_with_key`
|
31
|
+
and `#trees_with_key`
|
32
|
+
- Removed `KeyTree::Tree#fetch_default` method and simplified `#[]`
|
33
|
+
|
34
|
+
|
35
|
+
[Unreleased]: https://github.com/notCalle/PROJECT/compare/v0.8.0..HEAD
|
36
|
+
[0.8.0]: https://github.com/notCalle/PROJECT/compare/v0.7.0..v0.8.0
|
37
|
+
[0.7.0]: https://github.com/notCalle/PROJECT/compare/v0.6.1..v0.7.0
|
38
|
+
[0.6.1]: https://github.com/notCalle/PROJECT/releases/tag/v0.6.1
|
39
|
+
|
40
|
+
|
41
|
+
# Release Notes
|
42
|
+
|
43
|
+
## v0.6.1 – 2018-05-31
|
44
|
+
|
45
|
+
### New methods
|
46
|
+
|
47
|
+
* `KeyTree::Tree#fetch_default(key, default) { block }`
|
48
|
+
|
49
|
+
* Using `KeyTree::Refine::DeepHash`
|
50
|
+
* `Hash#deep_key_pathify`
|
51
|
+
|
52
|
+
### Bug fixes
|
53
|
+
|
54
|
+
Default processing for forests was broken.
|
55
|
+
|
56
|
+
* 7ff646ff Fix Forest#fetch default vs KeyError processing
|
57
|
+
* 62f6fd73 Add default aware fetch method
|
58
|
+
* 00f0b163 Manage deep_fetch KeyError generation on our own
|
59
|
+
|
60
|
+
#### Handle incoming key pathish keys
|
61
|
+
|
62
|
+
When a `Hash` had keys that looked like key paths, they were not correctly
|
63
|
+
converted to nested hashes with symbol keys.
|
64
|
+
|
65
|
+
* c23df1dd Change key transform for incoming hashes
|
66
|
+
* 09b526c8 Add new hash refinement for key_path-ification
|
67
|
+
|
68
|
+
## v0.6.0 – 2018-05-30
|
69
|
+
|
70
|
+
### Major changes
|
71
|
+
|
72
|
+
* Updated to Ruby ~> 2.3
|
73
|
+
* Added refinements module for `to_key_*` conversions in core classes
|
74
|
+
* `KeyTree::Tree` rewritten from scratch, to use a refinements
|
75
|
+
to an internal `Hash` structure instead of subclassing `Hash`
|
76
|
+
|
77
|
+
### New methods
|
78
|
+
|
79
|
+
* `KeyTree::Forest#key_paths`
|
80
|
+
* `KeyTree::Forest#to_key_forest`
|
81
|
+
* `KeyTree::Forest#to_key_wood`
|
82
|
+
* `KeyTree::Path#===`
|
83
|
+
* `KeyTree::Path#to_key_path`
|
84
|
+
* `KeyTree::Tree#delete(key_path)`
|
85
|
+
* `KeyTree::Tree#delete!(key_path)`
|
86
|
+
* `KeyTree::Tree#store(key_path, new_value)`
|
87
|
+
* `KeyTree::Tree#store!(key_path, new_value)`
|
88
|
+
* `KeyTree::Tree#to_key_tree`
|
89
|
+
* `KeyTree::Tree#to_key_wood`
|
90
|
+
|
91
|
+
* Using `KeyTree::Refinements`
|
92
|
+
* `Array#to_key_forest`
|
93
|
+
* `Array#to_key_path`
|
94
|
+
* `Array#to_key_wood`
|
95
|
+
* `Hash#to_key_tree`
|
96
|
+
* `Hash#to_key_wood`
|
97
|
+
* `String#to_key_path`
|
98
|
+
* `Symbol#to_key_path`
|
99
|
+
|
100
|
+
* Using `KeyTree::Refine::DeepHash`
|
101
|
+
* `Hash#deep`
|
102
|
+
* `Hash#deep_delete(key_path)`
|
103
|
+
* `Hash#deep_fetch(key_path, default, &default_proc)`
|
104
|
+
* `Hash#deep_merge(other)`
|
105
|
+
* `Hash#deep_merge!(other)`
|
106
|
+
* `Hash#deep_store(key_path, new_value)`
|
107
|
+
* `Hash#deep_transform_keys(&block)`
|
108
|
+
* `Hash#deep_transform_keys!(&block)`
|
109
|
+
|
110
|
+
### Removed methods
|
111
|
+
|
112
|
+
* `KeyTree::Tree` no longer inherits `Hash`, but most of the
|
113
|
+
inherited methods didn't work properly anyway
|
114
|
+
|
115
|
+
## v0.5.3 – 2018-05-25
|
116
|
+
|
117
|
+
### Bug fixes
|
118
|
+
|
119
|
+
#### Fix forest default values
|
120
|
+
Previous release broke default value propagation for forests.
|
121
|
+
|
122
|
+
* c0eccde4 Update forest specs vs default values
|
123
|
+
* 35367fd1 Consider Tree default values for Forest#[]
|
124
|
+
* 7e10dda5 Add method to find trees with default values
|
125
|
+
* 57a320ac Revert "Use proper method to retreive values from trees"
|
126
|
+
* 8173775d Make tree_with_key methods private
|
127
|
+
|
128
|
+
## v0.5.2 – 2018-05-19
|
129
|
+
|
130
|
+
### Bug fixes
|
131
|
+
|
132
|
+
#### Conform to Hash#fetch API
|
133
|
+
`Tree#fetch` confused its block argument with `#default_proc`, but they
|
134
|
+
have different arguments, so that didn't work out well.
|
135
|
+
|
136
|
+
* 0bd0a6e8 Use proper method to retreive values from trees
|
137
|
+
* 14128a6a Conform to Hash#fetch API
|
138
|
+
|
139
|
+
## v0.5.1 – 2018-05-19
|
140
|
+
|
141
|
+
### New methods
|
142
|
+
|
143
|
+
* `KeyTree::Tree#default_key?(key)`
|
144
|
+
* `KeyTree::Tree#format(fmtstr)`
|
145
|
+
* `KeyTree::Tree#to_h(string_keys: false)`
|
146
|
+
* `KeyTree::Tree#to_json`
|
147
|
+
* `KeyTree::Tree#to_yaml`
|
148
|
+
|
149
|
+
### Bug fixes
|
150
|
+
|
151
|
+
#### Make forests aware of default values in trees
|
152
|
+
|
153
|
+
Ensure that forests pick up default values from a tree.
|
154
|
+
|
155
|
+
* ebd1cb06 Return trees and forests untouched
|
156
|
+
* 3451a430 Propagate default_proc in fetch
|
157
|
+
* e121a4c4 Consider trees to have a key if #default_key?
|
158
|
+
* 50bc56ec Detect if a default_proc yields a key value
|
159
|
+
|
160
|
+
### New features
|
161
|
+
|
162
|
+
#### Key tree content exporters
|
163
|
+
|
164
|
+
Support for exporting the contents of a key tree to Hash, JSON, and YAML.
|
165
|
+
Also includes a convenience string formatter, that fills format strings
|
166
|
+
with values from a `Tree`.
|
167
|
+
|
168
|
+
* 9b5f05f0 Make exported hash key format selectable
|
169
|
+
* e3434d7e Add custom format method
|
170
|
+
* fa6a9b16 Serialize the contents of a tree to json or yaml
|
171
|
+
* 3fc6466b Convert a tree back into nested hashes
|
172
|
+
* e5aecd8b Split symbols into key paths
|
173
|
+
|
174
|
+
## v0.5.0 – 2018-04-17
|
175
|
+
|
176
|
+
### Changed methods
|
177
|
+
|
178
|
+
* `KeyTree.load(type, serialization, prefix: nil)`
|
179
|
+
* `KeyTree::Forest#[key] { |key, original, incoming| }`
|
180
|
+
* `KeyTree::Forest#fetch(key) { |key, original, incoming| }`
|
181
|
+
* `KeyTree::Forest#flatten { |key, original, incoming| }`
|
182
|
+
* `KeyTree::Tree#merge { |key, original, incoming| }`
|
183
|
+
* `KeyTree::Tree#merge! { |key, original, incoming| }`
|
184
|
+
|
185
|
+
### New methods
|
186
|
+
|
187
|
+
* `KeyTree::Loader.fallback(loader)`
|
188
|
+
|
189
|
+
### New features
|
190
|
+
|
191
|
+
#### Merge value selection
|
192
|
+
Improve merge related methods in `KeyTree::Tree`, and `KeyTree::Forest`
|
193
|
+
to take a `Hash#merge` style block argument, to allow control of the result when a key i present on both sides of a merge operation.
|
194
|
+
|
195
|
+
* 083b25c Add merge value selector to Forest#[]
|
196
|
+
* e813e55 Add merge value selection to Forest#fetch
|
197
|
+
* 581bc82 Add method to get list of trees with key
|
198
|
+
* 0f66f03 Pass merge value selector via Forest#flatten
|
199
|
+
* df9b80e Pass any merge selection block to super
|
200
|
+
|
201
|
+
#### Key prefix for file loading
|
202
|
+
When a key file has a name like `prefix@name.ext`, the `prefix` part will be prepended to all keys loaded from the file.
|
203
|
+
|
204
|
+
* fbe333a Changed call syntax for KeyTree.load
|
205
|
+
* 595902c Load keytree with prefix from files with @ in name
|
206
|
+
* d23a7e1 Allow prepending a prefix when loading keys
|
207
|
+
|
208
|
+
#### Fallback for KeyTree loaders
|
209
|
+
Allow a fallback class for handling loading of file types where no loader is specified, e.g. to ignore all files with unrecognized extension for `KeyTree.load_all`.
|
210
|
+
|
211
|
+
* a9d096c Add tree loader fallback
|
212
|
+
|
213
|
+
### Bug fixes
|
214
|
+
|
215
|
+
#### Proper breadth first flattening
|
216
|
+
|
217
|
+
* ff327f2 Use tree enumarator for Forest#key? and #prefix?
|
218
|
+
* 74fa15d Rewrite Forest#[]
|
219
|
+
* 177de08 Use tree enumerator in Forest#[]
|
220
|
+
* d161fe1 Use tree enumerator in Forest#flatten
|
221
|
+
* b0c94df Add breadth-first enumerator for trees
|
222
|
+
* 3468f28 Remove forest vs tree sorting nonsense
|
data/Gemfile
CHANGED
@@ -1,12 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
5
|
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
rescue LoadError
|
8
|
-
gem 'git-version-bump', '~> 0.15'
|
9
|
-
else
|
10
|
-
# Specify your gem's dependencies in key_tree.gemspec
|
11
|
-
gemspec
|
12
|
-
end
|
7
|
+
# Specify your gem's dependencies in key_tree.gemspec
|
8
|
+
gemspec
|
data/README.md
CHANGED
@@ -1,10 +1,15 @@
|
|
1
|
-
[](https://badge.fury.io/rb/key_tree)
|
1
|
+
[](https://badge.fury.io/rb/key_tree)
|
2
|
+
[](https://codeclimate.com/github/notCalle/ruby-keytree/maintainability)
|
3
|
+
[](https://codecov.io/gh/notCalle/ruby-keytree)
|
4
|
+
[](https://github.com/notCalle/ruby-keytree/actions/workflows/ruby.yml)
|
2
5
|
|
3
6
|
# KeyTree
|
4
7
|
|
5
8
|
KeyTree manages trees of hashes, and (possibly nested) forests of such trees,
|
6
9
|
allowing access to values by key path.
|
7
10
|
|
11
|
+
See the [changelog](CHANGELOG.md) for recent changes.
|
12
|
+
|
8
13
|
## Installation
|
9
14
|
|
10
15
|
Add this line to your application's Gemfile:
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'bundler/setup'
|
4
5
|
require 'key_tree'
|
@@ -7,8 +8,8 @@ require 'key_tree'
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
8
9
|
|
9
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
|
11
|
-
|
11
|
+
require 'pry'
|
12
|
+
Pry.start
|
12
13
|
|
13
|
-
require 'irb'
|
14
|
-
IRB.start(__FILE__)
|
14
|
+
# require 'irb'
|
15
|
+
# IRB.start(__FILE__)
|
data/bin/setup
CHANGED
data/key_tree.gemspec
CHANGED
@@ -1,17 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
4
6
|
require 'key_tree/version'
|
5
7
|
|
8
|
+
dev_deps = {
|
9
|
+
'bundler' => '~> 2.2',
|
10
|
+
'codecov' => '~> 0.5.0',
|
11
|
+
'pry' => '~> 0.14.0',
|
12
|
+
'rake' => '~> 13.0',
|
13
|
+
'rspec' => '~> 3.10',
|
14
|
+
'rubocop' => '~> 1.15',
|
15
|
+
'rubocop-rake' => '~> 0.5.1',
|
16
|
+
'rubocop-rspec' => '~> 2.3',
|
17
|
+
'ruby-prof' => '>= 1.4',
|
18
|
+
'simplecov' => '~> 0.21.0'
|
19
|
+
}
|
20
|
+
|
6
21
|
Gem::Specification.new do |spec|
|
7
22
|
spec.name = 'key_tree'
|
8
23
|
spec.version = KeyTree::VERSION
|
9
|
-
spec.date = KeyTree::DATE
|
10
24
|
spec.authors = ['Calle Englund']
|
11
25
|
spec.email = ['calle@discord.bofh.se']
|
12
26
|
|
13
27
|
spec.summary = 'Manage trees of keys'
|
14
|
-
spec.description = spec.summary
|
15
28
|
spec.homepage = 'https://github.com/notcalle/ruby-keytree'
|
16
29
|
spec.license = 'MIT'
|
17
30
|
|
@@ -22,10 +35,10 @@ Gem::Specification.new do |spec|
|
|
22
35
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
36
|
spec.require_paths = ['lib']
|
24
37
|
|
25
|
-
spec.
|
38
|
+
spec.platform = Gem::Platform::RUBY
|
39
|
+
spec.required_ruby_version = '>= 2.6', '< 4.0'
|
40
|
+
|
41
|
+
spec.add_dependency 'git-version-bump', '~> 0.17.0'
|
26
42
|
|
27
|
-
|
28
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
-
spec.add_development_dependency 'rubocop', '~> 0.52'
|
43
|
+
dev_deps.each { |d| spec.add_development_dependency(*d) }
|
31
44
|
end
|
data/lib/key_tree.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require 'key_tree/forest'
|
4
4
|
require 'key_tree/loader'
|
5
|
+
require 'key_tree/refinements'
|
6
|
+
require 'key_tree/tree'
|
5
7
|
|
6
8
|
# Manage a tree of keys
|
7
9
|
#
|
@@ -13,86 +15,84 @@ require 'key_tree/loader'
|
|
13
15
|
# -> 2
|
14
16
|
#
|
15
17
|
module KeyTree
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
Tree[contents]
|
22
|
-
when Array
|
23
|
-
Forest[*contents]
|
24
|
-
else
|
25
|
-
raise ArgumentError, "can't load #{contents.class} into a KeyTree"
|
18
|
+
using Refinements
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def [](contents = {})
|
22
|
+
contents.to_key_wood
|
26
23
|
end
|
27
|
-
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
25
|
+
# Load a KeyTree from some external serialization
|
26
|
+
#
|
27
|
+
# load +type+: +serialization+
|
28
|
+
# load +key_prefix+, +type+: +serialization+
|
29
|
+
#
|
30
|
+
# +type+ is upcased to form a class name that should provide a
|
31
|
+
# +.load+ class method (like YAML or JSON does).
|
32
|
+
#
|
33
|
+
# If a +key_prefix+ is given, it will be prepended to the loaded data.
|
34
|
+
#
|
35
|
+
# Examples:
|
36
|
+
# load(:yaml, "---\na: 1\n")
|
37
|
+
# => {"a" => 1}
|
38
|
+
#
|
39
|
+
# load(:yaml, "---\nb: 2\n", prefix: 'a')
|
40
|
+
# => {"a.b" => 2}
|
41
|
+
#
|
42
|
+
def load(type, serialization, prefix: nil)
|
43
|
+
type = type.to_sym unless type.nil?
|
44
|
+
loader = Loader[type]
|
45
|
+
contents = loader.load(serialization)
|
46
|
+
contents = { prefix => contents } unless prefix.nil?
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
contents.to_key_wood.with_meta_data do |meta_data|
|
49
|
+
meta_data << { load: { type: type, loader: loader } }
|
50
|
+
meta_data << { load: { prefix: prefix } } unless prefix.nil?
|
51
|
+
end
|
55
52
|
end
|
56
|
-
end
|
57
53
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
# Open an external file and load contents into a KeyTree
|
55
|
+
# When the file basename begins with 'prefix@', the prefix
|
56
|
+
# is prepended to all keys in the filee.
|
57
|
+
def open(file_name)
|
58
|
+
type = File.extname(file_name)[/[^.]+/]
|
59
|
+
prefix = File.basename(file_name)[/(.+)@/, 1]
|
64
60
|
|
65
|
-
|
66
|
-
|
61
|
+
keytree = File.open(file_name, mode: 'rb:utf-8') do |file|
|
62
|
+
load_from_file(file, type, prefix)
|
63
|
+
end
|
64
|
+
|
65
|
+
return keytree unless block_given?
|
66
|
+
|
67
|
+
yield keytree
|
67
68
|
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
# Open all files in a directory and load their contents into
|
71
|
+
# a Forest of Trees, optionally following symlinks, and recursing.
|
72
|
+
def open_all(dir_name, follow_links: false, recurse: false)
|
73
|
+
Dir.children(dir_name).reduce(KeyTree::Forest.new) do |result, file|
|
74
|
+
path = File.join(dir_name, file)
|
75
|
+
next result if File.symlink?(path) && !follow_links
|
72
76
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
next result << open(path) if stat.file?
|
82
|
-
# rubocop:enable Security/Open
|
83
|
-
next result unless recurse && stat.directory?
|
84
|
-
result << open_all(path, follow_links: follow_links, recurse: true)
|
77
|
+
stat = File.stat(path)
|
78
|
+
# rubocop:disable Security/Open
|
79
|
+
next result << open(path) if stat.file?
|
80
|
+
# rubocop:enable Security/Open
|
81
|
+
next result unless recurse && stat.directory?
|
82
|
+
|
83
|
+
result << open_all(path, follow_links: follow_links, recurse: true)
|
84
|
+
end
|
85
85
|
end
|
86
|
-
end
|
87
86
|
|
88
|
-
|
87
|
+
private
|
89
88
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
89
|
+
def load_from_file(file, type, prefix)
|
90
|
+
load(type, file.read, prefix: prefix).with_meta_data do |meta_data|
|
91
|
+
file_path = file.path
|
92
|
+
meta_data << { file: { path: file_path,
|
93
|
+
name: File.basename(file_path),
|
94
|
+
dir: File.dirname(file_path) } }
|
95
|
+
end
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|