qonfig 0.11.0 → 0.12.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/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +24 -0
- data/CHANGELOG.md +15 -0
- data/README.md +25 -2
- data/bin/rspec +55 -0
- data/gemfiles/with_external_deps.gemfile +8 -0
- data/gemfiles/without_external_deps.gemfile +5 -0
- data/lib/qonfig/data_set.rb +2 -0
- data/lib/qonfig/dsl.rb +1 -1
- data/lib/qonfig/{exceptions.rb → errors.rb} +10 -0
- data/lib/qonfig/plugins/access_mixin.rb +12 -0
- data/lib/qonfig/plugins/toml/commands/expose_toml.rb +146 -0
- data/lib/qonfig/plugins/toml/commands/load_from_toml.rb +49 -0
- data/lib/qonfig/plugins/toml/data_set.rb +19 -0
- data/lib/qonfig/plugins/toml/dsl.rb +27 -0
- data/lib/qonfig/plugins/toml/loaders/toml.rb +24 -0
- data/lib/qonfig/plugins/toml/tomlrb_fixes.rb +92 -0
- data/lib/qonfig/plugins/toml/uploaders/toml.rb +25 -0
- data/lib/qonfig/plugins/toml.rb +26 -0
- data/lib/qonfig/plugins.rb +1 -0
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +4 -1
- data/qonfig.gemspec +1 -1
- metadata +16 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62b74a92c4c74b79f222e029726296a63b51ba3a57886a00911a34ffbcbced25
|
4
|
+
data.tar.gz: 33fa91631b6554dec3547c9c31faddf805bc4a56becbe7042e1942c19c493f16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 152acb89e834fccaaed1b4bfae379f8263d795b2e4e7b7913f6a2b98fd1bfebf984dec1c82a3568ddc08a3e16fdec2be7783f1f583ef09a3dc6b1386f9afb18f
|
7
|
+
data.tar.gz: c468d5a5c289dc8b4b7b337e62314dbbf9d388b5dd6df1248a14e957a97be9937d7f24c47aa8634ffe415dbd092ed4f3c5b447036770b171fb6d87454eceb4e8
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -3,11 +3,35 @@ matrix:
|
|
3
3
|
fast_finish: true
|
4
4
|
include:
|
5
5
|
- rvm: 2.3.8
|
6
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
7
|
+
env: TEST_PLUGINS=true
|
6
8
|
- rvm: 2.4.6
|
9
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
10
|
+
env: TEST_PLUGINS=true
|
7
11
|
- rvm: 2.5.5
|
12
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
13
|
+
env: TEST_PLUGINS=true
|
8
14
|
- rvm: 2.6.3
|
15
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
16
|
+
env: TEST_PLUGINS=true
|
9
17
|
- rvm: ruby-head
|
18
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
19
|
+
env: TEST_PLUGINS=true
|
10
20
|
- rvm: jruby-head
|
21
|
+
gemfile: gemfiles/with_external_deps.gemfile
|
22
|
+
env: TEST_PLUGINS=true
|
23
|
+
- rvm: 2.3.8
|
24
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
25
|
+
- rvm: 2.4.6
|
26
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
27
|
+
- rvm: 2.5.5
|
28
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
29
|
+
- rvm: 2.6.3
|
30
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
31
|
+
- rvm: ruby-head
|
32
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
33
|
+
- rvm: jruby-head
|
34
|
+
gemfile: gemfiles/without_external_deps.gemfile
|
11
35
|
allow_failures:
|
12
36
|
- rvm: ruby-head
|
13
37
|
- rvm: jruby-head
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.12.0] - 2019-07-19
|
5
|
+
### Added
|
6
|
+
- Support for **TOML** (`.toml`) format
|
7
|
+
- realized as a plugin (`Qonfig.plugin(:toml)`);
|
8
|
+
- provides `#save_to_toml`, `#load_from_toml`, `#expose_toml` methods and works in `#*_yaml`-like manner);
|
9
|
+
- Custom `bin/rspec` command:
|
10
|
+
- `bin/rspec -n` - run tests without plugin tests;
|
11
|
+
- `bin/rspec -w` - run all tests;
|
12
|
+
- Added more convinient aliases for `Qonfig::DataSet` instances:
|
13
|
+
- `#save_to_yaml` => `#dump_to_yaml`;
|
14
|
+
- `#save_to_json` => `#dump_to_json`;
|
15
|
+
- `#save_to_toml` => `#dump_to_toml`;
|
16
|
+
### Changed
|
17
|
+
- Actualized development dependencies;
|
18
|
+
|
4
19
|
## [0.11.0] - 2019-05-15
|
5
20
|
### Added
|
6
21
|
- `#save_to_json` - save configurations to a json file (uses native `::JSON.generate` under the hood);
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ require 'qonfig'
|
|
39
39
|
- [Save to YAML file](#save-to-yaml-file) (`save_to_yaml`)
|
40
40
|
- [Smart Mixin](#smart-mixin) (`Qonfig::Configurable`)
|
41
41
|
- [Plugins](#plugins)
|
42
|
-
|
42
|
+
- [toml](#plugin-toml) (provides `load_from_toml`, `save_to_toml`, `expose_toml`)
|
43
43
|
---
|
44
44
|
|
45
45
|
### Definition and Access
|
@@ -819,7 +819,7 @@ config.save_to_json(path: 'config.json')
|
|
819
819
|
}
|
820
820
|
```
|
821
821
|
|
822
|
-
#### With value preprocessing
|
822
|
+
#### With value preprocessing and custom options
|
823
823
|
|
824
824
|
```ruby
|
825
825
|
class AppConfig < Qonfig::DataSet
|
@@ -1044,6 +1044,29 @@ Qonfig.plugin(:plugin_name) # or Qonfig.plugin('plugin_name')
|
|
1044
1044
|
|
1045
1045
|
---
|
1046
1046
|
|
1047
|
+
### Plugins: toml
|
1048
|
+
|
1049
|
+
- adds support for `toml` format ([specification](https://github.com/toml-lang/toml));
|
1050
|
+
- depends on `toml-rb` gem;
|
1051
|
+
- provides `load_from_toml` (works in `load_from_yaml` manner [doc](#load-from-yaml-file));
|
1052
|
+
- provides `save_to_toml` (works in `save_to_yaml` manner [doc](#save-to-yaml-file)) (`toml-rb` has no native options);
|
1053
|
+
- provides `expose_toml` (works in `expose_yaml` manner [doc](#expose-yaml));
|
1054
|
+
|
1055
|
+
```ruby
|
1056
|
+
require 'toml-rb'
|
1057
|
+
Qonfig.plugin(:toml)
|
1058
|
+
# and use :)
|
1059
|
+
```
|
1060
|
+
---
|
1061
|
+
|
1062
|
+
## Roadmap
|
1063
|
+
|
1064
|
+
- support for TOML format;
|
1065
|
+
- explicit "settings" object;
|
1066
|
+
- validation layer;
|
1067
|
+
- distributed configuration server;
|
1068
|
+
- support for Rails-like secrets;
|
1069
|
+
|
1047
1070
|
## Contributing
|
1048
1071
|
|
1049
1072
|
- Fork it ( https://github.com/0exp/qonfig/fork )
|
data/bin/rspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
module QonfigSpecRunner
|
8
|
+
extend self
|
9
|
+
|
10
|
+
expand_gemfile_path = lambda do |gemfile_name|
|
11
|
+
File.expand_path(File.join('..', 'gemfiles', gemfile_name), __dir__)
|
12
|
+
end
|
13
|
+
|
14
|
+
GEMFILES = {
|
15
|
+
with_external_deps: expand_gemfile_path.call('with_external_deps.gemfile'),
|
16
|
+
without_external_deps: expand_gemfile_path.call('without_external_deps.gemfile')
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def run!
|
20
|
+
OptionParser.new do |opts|
|
21
|
+
opts.banner = 'Usage: bin/rspec [options]'
|
22
|
+
|
23
|
+
opts.on(
|
24
|
+
'-w', '--with-plugins',
|
25
|
+
'Run tests with test for plugins'
|
26
|
+
) { run_with_specs_for_plugins! }
|
27
|
+
|
28
|
+
opts.on(
|
29
|
+
'-n', '--without-plugins',
|
30
|
+
'Run tests without tests for plugins'
|
31
|
+
) { run_without_specs_for_plugins! }
|
32
|
+
end.parse!
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def run_with_specs_for_plugins!
|
38
|
+
ENV['TEST_PLUGINS'] = 'true'
|
39
|
+
ENV['BUNDLE_GEMFILE'] = GEMFILES[:with_external_deps]
|
40
|
+
run_tests!
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_without_specs_for_plugins!
|
44
|
+
ENV['BUNDLE_GEMFILE'] = GEMFILES[:without_external_deps]
|
45
|
+
run_tests!
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_tests!
|
49
|
+
require 'rubygems'
|
50
|
+
require 'bundler/setup'
|
51
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
QonfigSpecRunner.run!
|
data/lib/qonfig/data_set.rb
CHANGED
@@ -101,6 +101,7 @@ class Qonfig::DataSet
|
|
101
101
|
Qonfig::Uploaders::JSON.upload(settings, path: path, options: options, &value_processor)
|
102
102
|
end
|
103
103
|
end
|
104
|
+
alias_method :dump_to_json, :save_to_json
|
104
105
|
|
105
106
|
# @option path [String]
|
106
107
|
# @option symbolize_keys [Boolean]
|
@@ -125,6 +126,7 @@ class Qonfig::DataSet
|
|
125
126
|
)
|
126
127
|
end
|
127
128
|
end
|
129
|
+
alias_method :dump_to_yaml, :save_to_yaml
|
128
130
|
|
129
131
|
# @param key [String, Symbol]
|
130
132
|
# @return [Object]
|
data/lib/qonfig/dsl.rb
CHANGED
@@ -9,6 +9,10 @@ module Qonfig
|
|
9
9
|
# @since 0.1.0
|
10
10
|
ArgumentError = Class.new(ArgumentError)
|
11
11
|
|
12
|
+
# @api public
|
13
|
+
# @since 0.12.0
|
14
|
+
PluginError = Class.new(Error)
|
15
|
+
|
12
16
|
# @api public
|
13
17
|
# @since 0.11.0
|
14
18
|
IncorrectHashTransformationError = Class.new(ArgumentError)
|
@@ -98,4 +102,10 @@ module Qonfig
|
|
98
102
|
# @api public
|
99
103
|
# @since 0.7.0
|
100
104
|
ExposeError = Class.new(Error)
|
105
|
+
|
106
|
+
# @see Qonfig::Plugin::TOMLFormat
|
107
|
+
#
|
108
|
+
# @api public
|
109
|
+
# @since 0.12.0
|
110
|
+
UnresolvedPluginDependencyError = Class.new(PluginError)
|
101
111
|
end
|
@@ -23,4 +23,16 @@ module Qonfig::Plugins::AccessMixin
|
|
23
23
|
def plugins
|
24
24
|
Qonfig::Plugins.names
|
25
25
|
end
|
26
|
+
|
27
|
+
# @param plugin_name [String, Symbol]
|
28
|
+
# @param plugin_klass [Class<Qonfig::Plugins::Abstract>]
|
29
|
+
# @return [void]
|
30
|
+
#
|
31
|
+
# @see Qonfig::Plugins
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
# @since 0.12.0
|
35
|
+
def register_plugin(plugin_name, plugin_klass)
|
36
|
+
Qonfig::Plugins.register_plugin(plugin_name, plugin_klass)
|
37
|
+
end
|
26
38
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::Commands::ExposeTOML < Qonfig::Commands::Base
|
6
|
+
# @return [Hash]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.12.0
|
10
|
+
EXPOSERS = { file_name: :file_name, env_key: :env_key }.freeze
|
11
|
+
|
12
|
+
# @return [Hash]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
# @since 0.12.0
|
16
|
+
EMPTY_TOML_DATA = {}.freeze
|
17
|
+
|
18
|
+
# @return [String]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
# @since 0.12.0
|
22
|
+
attr_reader :file_path
|
23
|
+
|
24
|
+
# @return [Boolean]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.12.0
|
28
|
+
attr_reader :strict
|
29
|
+
|
30
|
+
# @return [Symbol]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.12.0
|
34
|
+
attr_reader :via
|
35
|
+
|
36
|
+
# @return [Symbol, String]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.12.0
|
40
|
+
attr_reader :env
|
41
|
+
|
42
|
+
# @param file_path [String]
|
43
|
+
# @option strict [Boolean]
|
44
|
+
# @option via [Symbol]
|
45
|
+
# @option env [String, Symbol]
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
# @since 0.12.0
|
49
|
+
def initialize(file_path, strict: true, via:, env:)
|
50
|
+
unless env.is_a?(Symbol) || env.is_a?(String) || env.is_a?(Numeric)
|
51
|
+
raise Qonfig::ArgumentError, ':env should be a string or a symbol'
|
52
|
+
end
|
53
|
+
|
54
|
+
raise Qonfig::ArgumentError, ':env should be provided' if env.to_s.empty?
|
55
|
+
raise Qonfig::ArgumentError, 'used :via is unsupported' unless EXPOSERS.key?(via)
|
56
|
+
|
57
|
+
@file_path = file_path
|
58
|
+
@strict = strict
|
59
|
+
@via = via
|
60
|
+
@env = env
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param settings [Qonfig::Settings]
|
64
|
+
# @return [void]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
# @since 0.12.0
|
68
|
+
def call(settings)
|
69
|
+
case via
|
70
|
+
when EXPOSERS[:file_name]
|
71
|
+
expose_file_name!(settings)
|
72
|
+
when EXPOSERS[:env_key]
|
73
|
+
expose_env_key!(settings)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# @param settings [Qonfig::Settings]
|
80
|
+
# @return [void]
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
# @since 0.12.0
|
84
|
+
# rubocop:disable Metrics/AbcSize
|
85
|
+
def expose_file_name!(settings)
|
86
|
+
# NOTE: transform file name (insert environment name into the file name)
|
87
|
+
# from: path/to/file/file_name.file_extension
|
88
|
+
# to: path/to/file/file_name.env_name.file_extension
|
89
|
+
|
90
|
+
pathname = Pathname.new(file_path)
|
91
|
+
dirname = pathname.dirname
|
92
|
+
extname = pathname.extname.to_s
|
93
|
+
basename = pathname.basename.to_s.sub!(extname, '')
|
94
|
+
envname = [env.to_s, extname].reject(&:empty?).join('')
|
95
|
+
envfile = [basename, envname].reject(&:empty?).join('.')
|
96
|
+
realfile = dirname.join(envfile).to_s
|
97
|
+
|
98
|
+
toml_data = load_toml_data(realfile)
|
99
|
+
toml_based_settings = build_data_set_class(toml_data).new.settings
|
100
|
+
|
101
|
+
settings.__append_settings__(toml_based_settings)
|
102
|
+
end
|
103
|
+
# rubocop:enable Metrics/AbcSize
|
104
|
+
|
105
|
+
# @param settings [Qonfig::Settings]
|
106
|
+
# @return [void]
|
107
|
+
#
|
108
|
+
# @raise [Qonfig::ExposeError]
|
109
|
+
#
|
110
|
+
# @api private
|
111
|
+
# @since 0.12.0
|
112
|
+
# rubocop:disable Metrics/AbcSize
|
113
|
+
def expose_env_key!(settings)
|
114
|
+
toml_data = load_toml_data(file_path)
|
115
|
+
toml_data_slice = toml_data[env] || toml_data[env.to_s] || toml_data[env.to_sym]
|
116
|
+
toml_data_slice = EMPTY_TOML_DATA.dup if toml_data_slice.nil? && !strict
|
117
|
+
|
118
|
+
raise(
|
119
|
+
Qonfig::ExposeError,
|
120
|
+
"#{file_path} file does not contain settings with <#{env}> environment key!"
|
121
|
+
) unless toml_data_slice
|
122
|
+
|
123
|
+
toml_based_settings = build_data_set_class(toml_data_slice).new.settings
|
124
|
+
|
125
|
+
settings.__append_settings__(toml_based_settings)
|
126
|
+
end
|
127
|
+
# rubocop:enable Metrics/AbcSize
|
128
|
+
|
129
|
+
# @param file_path [String]
|
130
|
+
# @return [Hash]
|
131
|
+
#
|
132
|
+
# @api private
|
133
|
+
# @since 0.12.0
|
134
|
+
def load_toml_data(file_path)
|
135
|
+
Qonfig::Loaders::TOML.load_file(file_path, fail_on_unexist: strict)
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param toml_data [Hash]
|
139
|
+
# @return [Class<Qonfig::DataSet>]
|
140
|
+
#
|
141
|
+
# @api private
|
142
|
+
# @since 0.12.0
|
143
|
+
def build_data_set_class(toml_data)
|
144
|
+
Qonfig::DataSet::ClassBuilder.build_from_hash(toml_data)
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::Commands::LoadFromTOML < Qonfig::Commands::Base
|
6
|
+
# @return [String]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.12.0
|
10
|
+
attr_reader :file_path
|
11
|
+
|
12
|
+
# @return [Boolean]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
# @since 0.12.0
|
16
|
+
attr_reader :strict
|
17
|
+
|
18
|
+
# @param file_path [String]
|
19
|
+
# @option strict [Boolean]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.12.0
|
23
|
+
def initialize(file_path, strict: true)
|
24
|
+
@file_path = file_path
|
25
|
+
@strict = strict
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param settings [Qonfig::Settings]
|
29
|
+
# @return [void]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
# @since 0.12.0
|
33
|
+
def call(settings)
|
34
|
+
toml_data = Qonfig::Loaders::TOML.load_file(file_path, fail_on_unexist: strict)
|
35
|
+
toml_based_settings = build_data_set_class(toml_data).new.settings
|
36
|
+
settings.__append_settings__(toml_based_settings)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @param toml_data [Hash]
|
42
|
+
# @return [Class<Qonfig::DataSet>]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.12.0
|
46
|
+
def build_data_set_class(toml_data)
|
47
|
+
Qonfig::DataSet::ClassBuilder.build_from_hash(toml_data)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api public
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::DataSet
|
6
|
+
# @option path [String]
|
7
|
+
# @option options [Hash<Symbol,Any>] Nothing, just for compatability and consistency
|
8
|
+
# @param value_processor [Block]
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
# @since 0.12.0
|
13
|
+
def save_to_toml(path:, options: Qonfig::Uploaders::TOML::DEFAULT_OPTIONS, &value_processor)
|
14
|
+
thread_safe_access do
|
15
|
+
Qonfig::Uploaders::TOML.upload(settings, path: path, options: options, &value_processor)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias_method :dump_to_toml, :save_to_toml
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
module Qonfig::DSL
|
6
|
+
# @param file_path [String]
|
7
|
+
# @option strict [Boolean]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
# @since 0.12.0
|
12
|
+
def load_from_toml(file_path, strict: true)
|
13
|
+
commands << Qonfig::Commands::LoadFromTOML.new(file_path, strict: strict)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param file_path [String]
|
17
|
+
# @option strict [Boolean]
|
18
|
+
# @option via [Symbol]
|
19
|
+
# @option env [Symbol, String]
|
20
|
+
# @return [void]
|
21
|
+
#
|
22
|
+
# @api public
|
23
|
+
# @since 0.12.0
|
24
|
+
def expose_toml(file_path, strict: true, via:, env:)
|
25
|
+
commands << Qonfig::Commands::ExposeTOML.new(file_path, strict: strict, via: via, env: env)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::Loaders::TOML < Qonfig::Loaders::Basic
|
6
|
+
class << self
|
7
|
+
# @param data [String]
|
8
|
+
# @return [Object]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.12.0
|
12
|
+
def load(data)
|
13
|
+
::TomlRB.parse(ERB.new(data).result)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Object]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.12.0
|
20
|
+
def load_empty_data
|
21
|
+
::TomlRB.parse('')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# NOTE:
|
4
|
+
# - dumper sorts settins keys as a collection of string or symbols only
|
5
|
+
# - settings values like { a: 1, 'b' => 2 } will fail on comparison errors (Symbol with String)
|
6
|
+
# - problem is located in TomlRB::Dumper#sort_pairs(hash) method
|
7
|
+
# - problem code: `hash.keys.sort.map` (failed on `.sort` part)
|
8
|
+
# - we can patch this code by explicit `.map(&:to_s)` before `.sort`
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.12.0
|
12
|
+
module TomlRB::Dumper::SortFixPatch
|
13
|
+
private
|
14
|
+
|
15
|
+
# NOTE: target method for our fix
|
16
|
+
def sort_pairs(hash)
|
17
|
+
nested_pairs = []
|
18
|
+
simple_pairs = []
|
19
|
+
table_array_pairs = []
|
20
|
+
|
21
|
+
# NOTE: our fix (original code: `hash.keys.sort`) (for details see notes above)
|
22
|
+
fixed_keys_sort(hash).each do |key|
|
23
|
+
val = hash[key]
|
24
|
+
element = [key, val]
|
25
|
+
|
26
|
+
if val.is_a? Hash
|
27
|
+
nested_pairs << element
|
28
|
+
elsif val.is_a?(Array) && val.first.is_a?(Hash)
|
29
|
+
table_array_pairs << element
|
30
|
+
else
|
31
|
+
simple_pairs << element
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
[simple_pairs, nested_pairs, table_array_pairs]
|
36
|
+
end
|
37
|
+
|
38
|
+
# NOTE: our fix (for detales see notes above)
|
39
|
+
def fixed_keys_sort(hash)
|
40
|
+
hash.keys.sort_by(&:to_s)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# NOTE:
|
45
|
+
# - dumper uses ultra primitive way to conver objects to toml format
|
46
|
+
# - dumper represents nil values as a simple strings without quots,
|
47
|
+
# but should not represent them at all
|
48
|
+
# - dumper can not validate invalid structures
|
49
|
+
# (for example: [1, [2,3], nil] (invalid, cuz arrays should contain values of one type))
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
# @since 0.12.0
|
53
|
+
module TomlRB::Dumper::ObjectConverterFix
|
54
|
+
private
|
55
|
+
|
56
|
+
# NOTE: target method for our fix
|
57
|
+
def dump_simple_pairs(simple_pairs)
|
58
|
+
simple_pairs.each do |key, val|
|
59
|
+
key = quote_key(key) unless bare_key? key
|
60
|
+
# NOTE: our fix (original code: `@toml_str << "#{key} = #{to_toml(val)}\n"`)
|
61
|
+
fixed_toml_value_append(key, val)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# NOTE: our fix
|
66
|
+
def fixed_toml_value_append(key, val)
|
67
|
+
@toml_str << "#{key} = #{fixed_to_toml(val)}\n" unless val.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
# NOTE our fix
|
71
|
+
def fixed_to_toml(object)
|
72
|
+
# NOTE: original code of #toml(obj):
|
73
|
+
# if object.is_a? Time
|
74
|
+
# object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
75
|
+
# else
|
76
|
+
# object.inspect
|
77
|
+
# end
|
78
|
+
|
79
|
+
case object
|
80
|
+
when Time, DateTime, Date
|
81
|
+
object.strftime('%Y-%m-%dT%H:%M:%SZ')
|
82
|
+
else
|
83
|
+
# NOTE: validate result value via value parsing before dump
|
84
|
+
object.inspect.tap { |value| ::TomlRB.parse("sample = #{value}") }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @since 0.12.0
|
90
|
+
TomlRB::Dumper.prepend(TomlRB::Dumper::SortFixPatch)
|
91
|
+
# @since 0.12.0
|
92
|
+
TomlRB::Dumper.prepend(TomlRB::Dumper::ObjectConverterFix)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::Uploaders::TOML < Qonfig::Uploaders::File
|
6
|
+
class << self
|
7
|
+
# @param settings [Qonfig::Settings]
|
8
|
+
# @param options [Hash<Symbol,Any>]
|
9
|
+
# @param value_processor [Block]
|
10
|
+
# @return [String]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.12.0
|
14
|
+
def represent_settings(settings, options, &value_processor)
|
15
|
+
settings_hash =
|
16
|
+
if block_given?
|
17
|
+
settings.__to_hash__(transform_value: value_processor)
|
18
|
+
else
|
19
|
+
settings.__to_hash__
|
20
|
+
end
|
21
|
+
|
22
|
+
::TomlRB.dump(settings_hash)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.12.0
|
5
|
+
class Qonfig::Plugins::TOML < Qonfig::Plugins::Abstract
|
6
|
+
class << self
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.12.0
|
11
|
+
def load!
|
12
|
+
raise(
|
13
|
+
Qonfig::UnresolvedPluginDependencyError,
|
14
|
+
'::TomlRB does not exist or "toml-rb" gem is not loaded'
|
15
|
+
) unless const_defined?('::TomlRB')
|
16
|
+
|
17
|
+
require_relative 'toml/tomlrb_fixes'
|
18
|
+
require_relative 'toml/loaders/toml'
|
19
|
+
require_relative 'toml/uploaders/toml'
|
20
|
+
require_relative 'toml/commands/load_from_toml'
|
21
|
+
require_relative 'toml/commands/expose_toml'
|
22
|
+
require_relative 'toml/data_set'
|
23
|
+
require_relative 'toml/dsl'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/qonfig/plugins.rb
CHANGED
data/lib/qonfig/version.rb
CHANGED
data/lib/qonfig.rb
CHANGED
@@ -5,7 +5,7 @@ require 'json'
|
|
5
5
|
require 'erb'
|
6
6
|
|
7
7
|
module Qonfig
|
8
|
-
require_relative 'qonfig/
|
8
|
+
require_relative 'qonfig/errors'
|
9
9
|
require_relative 'qonfig/loaders'
|
10
10
|
require_relative 'qonfig/uploaders'
|
11
11
|
require_relative 'qonfig/commands'
|
@@ -19,4 +19,7 @@ module Qonfig
|
|
19
19
|
# @api public
|
20
20
|
# @since 0.4.0
|
21
21
|
extend Plugins::AccessMixin
|
22
|
+
|
23
|
+
# @since 0.12.0
|
24
|
+
register_plugin('toml', Qonfig::Plugins::TOML)
|
22
25
|
end
|
data/qonfig.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
32
32
|
spec.add_development_dependency 'simplecov', '~> 0.16'
|
33
33
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
34
|
-
spec.add_development_dependency 'armitage-rubocop', '~> 0.
|
34
|
+
spec.add_development_dependency 'armitage-rubocop', '~> 0.73'
|
35
35
|
|
36
36
|
spec.add_development_dependency 'bundler'
|
37
37
|
spec.add_development_dependency 'rake'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qonfig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coveralls
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.73'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
68
|
+
version: '0.73'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,7 +129,10 @@ files:
|
|
129
129
|
- README.md
|
130
130
|
- Rakefile
|
131
131
|
- bin/console
|
132
|
+
- bin/rspec
|
132
133
|
- bin/setup
|
134
|
+
- gemfiles/with_external_deps.gemfile
|
135
|
+
- gemfiles/without_external_deps.gemfile
|
133
136
|
- lib/qonfig.rb
|
134
137
|
- lib/qonfig/command_set.rb
|
135
138
|
- lib/qonfig/commands.rb
|
@@ -148,7 +151,7 @@ files:
|
|
148
151
|
- lib/qonfig/data_set/class_builder.rb
|
149
152
|
- lib/qonfig/data_set/validator.rb
|
150
153
|
- lib/qonfig/dsl.rb
|
151
|
-
- lib/qonfig/
|
154
|
+
- lib/qonfig/errors.rb
|
152
155
|
- lib/qonfig/loaders.rb
|
153
156
|
- lib/qonfig/loaders/basic.rb
|
154
157
|
- lib/qonfig/loaders/json.rb
|
@@ -157,6 +160,14 @@ files:
|
|
157
160
|
- lib/qonfig/plugins/abstract.rb
|
158
161
|
- lib/qonfig/plugins/access_mixin.rb
|
159
162
|
- lib/qonfig/plugins/registry.rb
|
163
|
+
- lib/qonfig/plugins/toml.rb
|
164
|
+
- lib/qonfig/plugins/toml/commands/expose_toml.rb
|
165
|
+
- lib/qonfig/plugins/toml/commands/load_from_toml.rb
|
166
|
+
- lib/qonfig/plugins/toml/data_set.rb
|
167
|
+
- lib/qonfig/plugins/toml/dsl.rb
|
168
|
+
- lib/qonfig/plugins/toml/loaders/toml.rb
|
169
|
+
- lib/qonfig/plugins/toml/tomlrb_fixes.rb
|
170
|
+
- lib/qonfig/plugins/toml/uploaders/toml.rb
|
160
171
|
- lib/qonfig/settings.rb
|
161
172
|
- lib/qonfig/settings/builder.rb
|
162
173
|
- lib/qonfig/settings/key_guard.rb
|