key_tree 0.5.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/key_tree.svg)](https://badge.fury.io/rb/key_tree)
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/key_tree.svg)](https://badge.fury.io/rb/key_tree)
|
2
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/ac48756e80007e0cd6f9/maintainability)](https://codeclimate.com/github/notCalle/ruby-keytree/maintainability)
|
3
|
+
[![codecov](https://codecov.io/gh/notCalle/ruby-keytree/branch/master/graph/badge.svg)](https://codecov.io/gh/notCalle/ruby-keytree)
|
4
|
+
[![Ruby](https://github.com/notCalle/ruby-keytree/actions/workflows/ruby.yml/badge.svg)](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
|