rbcli 0.4.0 → 0.4.1

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: 73760c480505d19af6bf3bbf67df643902f079fe2b5c22cc2368111894ce2da5
4
- data.tar.gz: 4fbbd0ca18a2cf4b0dc79bb5b2582ddc2730d2d9944147e90cc8255f20aa92c8
3
+ metadata.gz: 748853fe49a1c814fa91a3afd45908e307640d9d3ff105cb5577a97ae6483b99
4
+ data.tar.gz: 9f5e6526fd0a900b768d1589b791e8b87913976d291124bac0cd3be6ea3297b2
5
5
  SHA512:
6
- metadata.gz: d1e5a99c761cf3bb6ef81fd8877cfcb16d447a60a595189ecaeb8d41f054a6ea3d836d43a8e1776edc6e919f773f673aa1ec61c92b1829d4bdb4a741a20a87c5
7
- data.tar.gz: ead35dca33292b7c2cbd591267fe18807932e6d5f98a2f284b4699743c05aefe852af1d94a3507e41ca65aa36ef9b9bb453572a5eb66198b5d04c120907b3fe7
6
+ metadata.gz: 3428edc78581a3cc2230c6af2a0b6ddf5d9e1d9b8ef0933c38db0bb14b3adf5e95d61ec6a7c8fb896ef4af2403c8c64f189a05b212c9cdc428b2b989f28b9f69
7
+ data.tar.gz: 87bff9a24cfcf862335be93bfb09590b3b305c446166fe235c777928323431ef8c1b3649d9cd83f4e45e8260f41312f8b094af55f686b6c72a3dd0eec226d311
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
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)] }.to_h.select { |slug, match| match }.first.first
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: parameter is used on some backends to know which fields to expect and parse
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! defaults
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
- text = self.inject_banner(text, defaults[:helptext])
89
- File.write(@path, text)
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)
@@ -60,8 +60,4 @@ class Rbcli::UserConf::Env < Rbcli::UserConf::Backend
60
60
  def exist?
61
61
  true
62
62
  end
63
-
64
- def annotate! _defaults = nil
65
- true
66
- end
67
63
  end
@@ -28,5 +28,4 @@ class Rbcli::UserConf::Json < Rbcli::UserConf::Backend
28
28
  def inject_banner text, _banner
29
29
  text
30
30
  end
31
-
32
31
  end
@@ -19,14 +19,10 @@ class Rbcli::UserConf::Null < Rbcli::UserConf::Backend
19
19
  end
20
20
 
21
21
  def savable?
22
- true
22
+ false
23
23
  end
24
24
 
25
25
  def exist?
26
26
  true
27
27
  end
28
-
29
- def annotate! _defaults = nil
30
- true
31
- end
32
28
  end
@@ -10,7 +10,6 @@ class Rbcli::UserConf::Toml < Rbcli::UserConf::Backend
10
10
 
11
11
  def parse str
12
12
  begin
13
-
14
13
  parsed_str = TOML.load(str).deep_symbolize!
15
14
  rescue => e
16
15
  Rbcli.log.warn "Error when parsing TOML file", "CONF"
@@ -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.group slug #, helptext: nil
25
- @lastgroup = slug.to_sym
26
- Rbcli::Warehouse.get(:config, :parsedopts).add_group(slug.to_sym, helptext: nil)
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
- find_location = Proc.new do |method|
14
- location.each do |loc|
15
- storage = Rbcli::UserConf::Backend.create(loc, type: type)
16
- if storage.send(method)
17
- Rbcli.log.debug("Found config storage at '#{loc}'", "CONF") if method == :exist? && !loc.nil?
18
- Rbcli.log.debug("Ready to create config at '#{loc}'", "CONF") if method == :savable? && !loc.nil?
19
- @location = loc
20
- @storage = storage
21
- @should_create = true if method == :savable?
22
- break true
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
- @type = @storage.nil? ? nil : @storage.type.downcase.to_sym
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, :type
39
+ attr_accessor :is_schema, :defaults
55
40
 
56
41
  def set_banner text
57
- @declared_defaults[:helptext] = text
42
+ @banner = text
58
43
  end
59
44
 
60
- def add_group path_arr, helptext: nil
61
- make_group path_arr, helptext: helptext, nested: @declared_defaults
45
+ def add_default slug, default: nil
46
+ @defaults[slug] = default
62
47
  end
63
48
 
64
- def add_default slug, helptext: nil, group_path: nil, default: nil, permitted: nil
65
- make_group group_path, nested: @declared_defaults
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: self.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 self.defaults.empty?
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! @declared_defaults
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
- ## Config Structure & Defaults (Optional)
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 above.
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
- group :group1
35
- setting :enable_logins, default: true
33
+ defaults({ setting_one: true, setting_two: false })
36
34
  end
@@ -13,6 +13,7 @@ module Rbcli::Configurate::Cli
13
13
  author: nil,
14
14
  email: nil,
15
15
  copyright_year: nil,
16
+ compatibility: nil,
16
17
  license: nil,
17
18
  helptext: nil
18
19
  }
@@ -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?
@@ -14,6 +14,7 @@ Rbcli::Configurate.cli do
14
14
  email nil
15
15
  version <%= @appname.capitalize %>::VERSION
16
16
  copyright_year <%= Time.now.year %>
17
+ compatibility nil
17
18
  license nil
18
19
  helptext "This text shows up in `<%= @appname.downcase %> --help`"
19
20
  <%- if @showdocs -%>
@@ -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.0
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-07 00:00:00.000000000 Z
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.9
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