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 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