rbcli 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/rbcli/components/config/backend.rb +8 -6
- data/lib/rbcli/components/config/backends/env.rb +0 -4
- data/lib/rbcli/components/config/backends/json.rb +0 -1
- data/lib/rbcli/components/config/backends/null.rb +1 -5
- data/lib/rbcli/components/config/backends/toml.rb +0 -1
- data/lib/rbcli/components/config/component.rb +3 -8
- data/lib/rbcli/components/config/config.rb +24 -79
- data/lib/rbcli/components/config/template.rb.erb +3 -5
- data/lib/rbcli/components/parser/component.rb +1 -0
- data/lib/rbcli/components/parser/parser.rb +1 -0
- data/lib/rbcli/components/parser/template.rb.erb +1 -0
- data/lib/rbcli/util/hash_deep_symbolize.rb +24 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 748853fe49a1c814fa91a3afd45908e307640d9d3ff105cb5577a97ae6483b99
|
4
|
+
data.tar.gz: 9f5e6526fd0a900b768d1589b791e8b87913976d291124bac0cd3be6ea3297b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3428edc78581a3cc2230c6af2a0b6ddf5d9e1d9b8ef0933c38db0bb14b3adf5e95d61ec6a7c8fb896ef4af2403c8c64f189a05b212c9cdc428b2b989f28b9f69
|
7
|
+
data.tar.gz: 87bff9a24cfcf862335be93bfb09590b3b305c446166fe235c777928323431ef8c1b3649d9cd83f4e45e8260f41312f8b094af55f686b6c72a3dd0eec226d311
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
@@ -27,9 +27,10 @@ class Rbcli::UserConf::Backend
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def self.create filename, type: nil
|
30
|
-
type ||= self.types.map { |slug, check| [slug, check.call(filename)] }.
|
30
|
+
type ||= self.types.map { |slug, check| [slug, check.call(filename)] }.select { |slug, match| match }.first.first
|
31
31
|
type = type.to_s.downcase.to_sym
|
32
32
|
require_relative "backends/#{type.to_s}"
|
33
|
+
Rbcli.log.debug "Creating backend of type #{type} at #{filename}", "CONF"
|
33
34
|
@registered_types[type].new(filename, type)
|
34
35
|
end
|
35
36
|
|
@@ -43,7 +44,7 @@ class Rbcli::UserConf::Backend
|
|
43
44
|
attr_reader :type, :loaded
|
44
45
|
alias_method :loaded?, :loaded
|
45
46
|
|
46
|
-
# The defaults
|
47
|
+
# The `defaults` parameter is used on some backends which override this method
|
47
48
|
def load defaults: nil
|
48
49
|
begin
|
49
50
|
text = File.read(@path)
|
@@ -76,17 +77,18 @@ class Rbcli::UserConf::Backend
|
|
76
77
|
File.exist?(@path)
|
77
78
|
end
|
78
79
|
|
79
|
-
def annotate!
|
80
|
+
def annotate! banner
|
81
|
+
return true unless self.respond_to?(:inject_banner) || self.private_methods.include?(:inject_banner)
|
82
|
+
|
80
83
|
begin
|
81
84
|
text = File.read(@path)
|
82
85
|
rescue Errno::ENOENT => _
|
83
86
|
Rbcli.log.debug "Attempted to annotate #{@type} config file but did not find it at '#{@path}'", "CONF"
|
84
87
|
return nil
|
85
88
|
end
|
86
|
-
Rbcli.log.debug "Annotating #{@type} config file at '#{@path}'", "CONF"
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
+
Rbcli.log.debug "Annotating #{@type} config file at '#{@path}'", "CONF"
|
91
|
+
text = self.inject_banner(text, banner)
|
90
92
|
|
91
93
|
begin
|
92
94
|
File.write(@path, text)
|
@@ -21,13 +21,8 @@ module Rbcli::Configurate::Config
|
|
21
21
|
Rbcli::Warehouse.get(:config, :parsedopts).set_banner text
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.
|
25
|
-
|
26
|
-
Rbcli::Warehouse.get(:config, :parsedopts).
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.setting slug, default: nil #, helptext: nil
|
30
|
-
# raise Rbcli::ConfigurateError.new "A config group must be defined before declaring any config options" if @lastgroup.nil?
|
31
|
-
Rbcli::Warehouse.get(:config, :parsedopts).add_default(slug.to_sym, helptext: nil, group_path: @lastgroup, default: default)
|
24
|
+
def self.defaults hash
|
25
|
+
raise Rbcli::ConfigurateError.new "The default configuration must be a hash." unless hash.is_a?(Hash)
|
26
|
+
Rbcli::Warehouse.get(:config, :parsedopts).defaults = hash
|
32
27
|
end
|
33
28
|
end
|
@@ -10,76 +10,60 @@ require_relative 'backend'
|
|
10
10
|
class Rbcli::Config < Hash
|
11
11
|
def initialize location: nil, type: nil, schema_location: nil, create_if_not_exists: false, suppress_errors: false
|
12
12
|
location = [location] unless location.is_a?(Array)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
find_location.call(:exist?)
|
27
|
-
find_location.call(:savable?) if !defined?(@location) && create_if_not_exists
|
28
|
-
|
29
|
-
if (defined?(@location) && !@location.nil? && @location != :null) || type == :env
|
30
|
-
Rbcli.log.debug "Instantiated config of type '#{@storage.type}' at '#{@location}'", "CONF"
|
31
|
-
elsif location.nil? || location == :null || location == [nil]
|
32
|
-
Rbcli.log.debug "Instantiated null config; data will not be stored", "CONF"
|
33
|
-
@location = :null
|
34
|
-
@storage = Rbcli::UserConf::Backend.create(:null)
|
13
|
+
locations = location.map { |path| [path, Rbcli::UserConf::Backend.create(path, type: type)] }.reject { |path, storage| !(path.nil? || path == :null) && storage.type == 'NULL' }
|
14
|
+
existing_location = locations.select { |_path, storage| storage.exist? }.first
|
15
|
+
savable_location = locations.select { |_path, storage| storage.savable? }.first
|
16
|
+
if !existing_location.nil?
|
17
|
+
@location, @storage = existing_location
|
18
|
+
Rbcli.log.debug @location.nil? ? "Instantiated null config; data will not be stored" : "Found config of type '#{@storage.type}' at '#{@location}'", "CONF"
|
19
|
+
elsif !savable_location.nil? && create_if_not_exists
|
20
|
+
@location, @storage = savable_location
|
21
|
+
@should_create = true
|
22
|
+
Rbcli.log.debug "Ready to create new config of type '#{@storage.type}' at '#{@location}'", "CONF"
|
35
23
|
elsif suppress_errors
|
24
|
+
@location, @storage = :null, Rbcli::UserConf::Backend.create(:null)
|
36
25
|
Rbcli.log.debug "Location(s) could not be found and/or are not writeable. Instantiating null config and failing silently.", "CONF"
|
37
|
-
@location = :null
|
38
|
-
@storage = Rbcli::UserConf::Backend.create(:null)
|
39
26
|
else
|
40
27
|
Rbcli.log.fatal "Config file could not be loaded. Please verify that it exists at one of the following locations: #{location.join(", ")}", "CONF"
|
41
28
|
Rbcli::exit 2
|
42
29
|
end
|
43
|
-
|
44
|
-
@original_hash = {}
|
45
|
-
@declared_defaults = { groups: {}, options: {}, helptext: nil }
|
46
30
|
@suppress_errors = suppress_errors
|
47
|
-
@
|
31
|
+
@original_hash = {}
|
32
|
+
@defaults = {}
|
48
33
|
if schema_location
|
49
34
|
@schema = self.class.new(location: schema_location)
|
50
35
|
@schema.is_schema = true
|
51
36
|
end
|
52
37
|
end
|
53
38
|
|
54
|
-
attr_accessor :is_schema, :
|
39
|
+
attr_accessor :is_schema, :defaults
|
55
40
|
|
56
41
|
def set_banner text
|
57
|
-
@
|
42
|
+
@banner = text
|
58
43
|
end
|
59
44
|
|
60
|
-
def
|
61
|
-
|
45
|
+
def add_default slug, default: nil
|
46
|
+
@defaults[slug] = default
|
62
47
|
end
|
63
48
|
|
64
|
-
def
|
65
|
-
|
66
|
-
make_default slug, helptext: helptext, group_path: group_path, default: default, permitted: permitted, nested: @declared_defaults
|
49
|
+
def type
|
50
|
+
@storage.type.downcase.to_sym
|
67
51
|
end
|
68
52
|
|
69
53
|
def load!
|
70
54
|
if @should_create
|
71
55
|
Rbcli.log.add (@suppress_errors ? :debug : :info), "Config file #{@location} does not exist. Creating with default values.", "CONF"
|
72
|
-
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(defaults) : defaults)
|
56
|
+
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(@defaults) : @defaults)
|
73
57
|
self.save!
|
74
58
|
else
|
75
59
|
Rbcli.log.debug "Loading #{@is_schema ? 'schema' : 'config'} file", "CONF"
|
76
|
-
@original_hash = @storage.load(defaults:
|
60
|
+
@original_hash = @storage.load(defaults: @defaults)
|
77
61
|
if !@storage.loaded?
|
78
62
|
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Could not load #{@is_schema ? 'schema' : 'config'} file", "CONF"
|
79
|
-
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Using defaults", "CONF" unless
|
63
|
+
Rbcli.log.add (@suppress_errors ? :debug : :warn), "Using defaults", "CONF" unless @defaults.empty?
|
80
64
|
return false
|
81
65
|
else
|
82
|
-
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(defaults) : defaults)
|
66
|
+
self.deep_merge!(@storage.respond_to?(:parse_defaults) ? @storage.parse_defaults(@defaults) : @defaults)
|
83
67
|
self.deep_merge!(@original_hash.deep_symbolize!) if @original_hash.is_a?(Hash)
|
84
68
|
end
|
85
69
|
end
|
@@ -119,46 +103,7 @@ class Rbcli::Config < Hash
|
|
119
103
|
end
|
120
104
|
|
121
105
|
def annotate!
|
122
|
-
@storage.annotate! @
|
123
|
-
end
|
124
|
-
|
125
|
-
def inspect
|
126
|
-
@declared_defaults.inspect
|
127
|
-
end
|
128
|
-
|
129
|
-
def defaults
|
130
|
-
data = {}
|
131
|
-
traverse = Proc.new do |dataloc, defaultsloc|
|
132
|
-
dataloc.merge!(defaultsloc[:options].map { |k, v| [k, v[:default]] }.to_h)
|
133
|
-
defaultsloc[:groups].keys.each do |k|
|
134
|
-
dataloc[k] = {}
|
135
|
-
traverse.call dataloc[k], defaultsloc[:groups][k]
|
136
|
-
end
|
137
|
-
end
|
138
|
-
traverse.call(data, @declared_defaults)
|
139
|
-
data
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
|
144
|
-
def make_group path_arr, helptext: nil, nested: nil
|
145
|
-
return true if path_arr.nil? || path_arr.respond_to?(:empty?) && path_arr.empty?
|
146
|
-
path_arr = [path_arr] unless path_arr.is_a?(Array)
|
147
|
-
nested[:groups][path_arr.first.to_sym] ||= { groups: {}, options: {}, helptext: nil }
|
148
|
-
if path_arr.length == 1
|
149
|
-
nested[:groups][path_arr.first.to_sym][:helptext] = helptext
|
150
|
-
else
|
151
|
-
make_group path_arr[1..-1], helptext: helptext, nested: nested[:groups][path_arr.first.to_sym]
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def make_default slug, helptext: nil, group_path: nil, default: nil, permitted: nil, nested: nil
|
156
|
-
group_path = [group_path] unless group_path.is_a?(Array)
|
157
|
-
if group_path.empty? || group_path.first.nil?
|
158
|
-
nested[:options][slug.to_sym] = { helptext: helptext, default: default, permitted: permitted }
|
159
|
-
else
|
160
|
-
make_default(slug, helptext: helptext, group_path: group_path[1..-1], default: default, permitted: permitted, nested: nested[:groups][group_path.first.to_sym])
|
161
|
-
end
|
106
|
+
@storage.annotate! @banner
|
162
107
|
end
|
163
108
|
end
|
164
109
|
|
@@ -24,13 +24,11 @@ Rbcli::Configurate.config do
|
|
24
24
|
Tell the user a bit about what they're doing here.
|
25
25
|
BANNER
|
26
26
|
<%- if @showdocs -%>
|
27
|
-
|
27
|
+
##### Defaults (Optional) #####
|
28
28
|
# Set defaults for your config values.
|
29
29
|
#
|
30
30
|
# Defaults set here will be provided to your application if the values are missing in the config.
|
31
|
-
# They will also be used to create new config files when the flag `create_if_not_exists` is set
|
32
|
-
# will be written to a config file, along with the helptext and/or short descriptions.
|
31
|
+
# They will also be used to create new config files when the flag `create_if_not_exists` is set to true.
|
33
32
|
<%- end -%>
|
34
|
-
|
35
|
-
setting :enable_logins, default: true
|
33
|
+
defaults({ setting_one: true, setting_two: false })
|
36
34
|
end
|
@@ -23,6 +23,7 @@ module Rbcli::Parser
|
|
23
23
|
bannerstr += " <#{appinfo[:email]}>" unless appinfo[:author].nil? || appinfo[:email].nil?
|
24
24
|
bannerstr += "\n"
|
25
25
|
end
|
26
|
+
bannerstr += "Compatiblity: " + appinfo[:compatibility].join(', ').reverse.sub(' ,', ' dna ,').reverse + "\n" unless appinfo[:compatibility].nil? || appinfo[:compatibility].empty?
|
26
27
|
bannerstr += "License: #{appinfo[:license]}\n" unless appinfo[:license].nil?
|
27
28
|
bannerstr += "\n"
|
28
29
|
bannerstr += appinfo[:helptext].chomp + "\n\n" unless appinfo[:helptext].nil?
|
@@ -8,6 +8,18 @@
|
|
8
8
|
# Functions to convert hash keys to all symbols or all strings
|
9
9
|
##
|
10
10
|
class Hash
|
11
|
+
def deep_symbolize hsh = nil
|
12
|
+
hsh ||= Marshal.load(Marshal.dump(self))
|
13
|
+
hsh.keys.each do |k|
|
14
|
+
if k.is_a? String
|
15
|
+
hsh[k.to_sym] = hsh[k]
|
16
|
+
hsh.delete k
|
17
|
+
end
|
18
|
+
deep_symbolize! hsh[k.to_sym] if hsh[k.to_sym].is_a? Hash
|
19
|
+
end
|
20
|
+
hsh
|
21
|
+
end
|
22
|
+
|
11
23
|
def deep_symbolize! hsh = nil
|
12
24
|
hsh ||= self
|
13
25
|
hsh.keys.each do |k|
|
@@ -20,6 +32,18 @@ class Hash
|
|
20
32
|
hsh
|
21
33
|
end
|
22
34
|
|
35
|
+
def deep_stringify hsh = nil
|
36
|
+
hsh ||= Marshal.load(Marshal.dump(self))
|
37
|
+
hsh.keys.each do |k|
|
38
|
+
if k.is_a? Symbol
|
39
|
+
hsh[k.to_s] = hsh[k]
|
40
|
+
hsh.delete k
|
41
|
+
end
|
42
|
+
deep_stringify! hsh[k.to_s] if hsh[k.to_s].is_a? Hash
|
43
|
+
end
|
44
|
+
hsh
|
45
|
+
end
|
46
|
+
|
23
47
|
def deep_stringify! hsh = nil
|
24
48
|
hsh ||= self
|
25
49
|
hsh.keys.each do |k|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbcli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Khoury
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -259,7 +259,6 @@ homepage: https://akhoury6.github.io/rbcli/
|
|
259
259
|
licenses:
|
260
260
|
- MIT
|
261
261
|
metadata:
|
262
|
-
allowed_push_host: https://rubygems.org
|
263
262
|
homepage_uri: https://akhoury6.github.io/rbcli/
|
264
263
|
documentation_uri: https://akhoury6.github.io/rbcli/
|
265
264
|
source_code_uri: https://github.com/akhoury6/rbcli
|
@@ -279,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
278
|
- !ruby/object:Gem::Version
|
280
279
|
version: '0'
|
281
280
|
requirements: []
|
282
|
-
rubygems_version: 3.5.
|
281
|
+
rubygems_version: 3.5.10
|
283
282
|
signing_key:
|
284
283
|
specification_version: 4
|
285
284
|
summary: A CLI Application/Tooling Framework for Ruby
|