confmaker 0.0.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 +7 -0
- data/lib/confmaker.rb +18 -0
- data/lib/confoptions.rb +97 -0
- data/lib/confsources.rb +124 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 534f3991463e68b2d66789040ff5cf9695c186a7
|
4
|
+
data.tar.gz: 12c6f1b4f3254983b77a4622a9a75f573e54bdb2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 87186cc6880ccbafb8f239cc0f1dfbbde7a5b56465bc78bc9894e570bebcb557b9d79ed32af6bba7157ee985cced3d2292fab17a5fa9ae08dda296964af0d548
|
7
|
+
data.tar.gz: d318623fd286aaba1f3ed7e6b0f0f024fccfa393fec56fe4d8fbc32b4938c3c401c6147bb5c3dab48cc1840c418fa293274338726e6e06036f43e45d46772e5a
|
data/lib/confmaker.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module ConfMaker
|
2
|
+
require_relative 'confoptions'
|
3
|
+
def self.define_desc desc
|
4
|
+
@@desc = desc
|
5
|
+
end
|
6
|
+
def self.get_desc
|
7
|
+
@@desc
|
8
|
+
end
|
9
|
+
def self.define_options options
|
10
|
+
@@options = options
|
11
|
+
require_relative 'confsources'
|
12
|
+
ConfSources::Default.new
|
13
|
+
end
|
14
|
+
def self.get_options
|
15
|
+
@@options
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/lib/confoptions.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
module ConfOptions
|
2
|
+
class Standard < Hash
|
3
|
+
def initialize init_hash
|
4
|
+
merge! init_hash
|
5
|
+
end
|
6
|
+
def to_pair
|
7
|
+
[self[:name],self[:value]]
|
8
|
+
end
|
9
|
+
def get
|
10
|
+
if self[:getter].is_a? Proc
|
11
|
+
self[:getter].call self
|
12
|
+
else
|
13
|
+
default_getter
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def to_s
|
17
|
+
get.collect { |k,v|
|
18
|
+
k.to_s.capitalize.gsub('_',' ') + ': ' + v.to_s
|
19
|
+
}.join "\n"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class String < Standard
|
23
|
+
def validate! context = ConfSources::Default.new
|
24
|
+
self[:validator].call(self,context) if self[:validator].is_a? Proc
|
25
|
+
default_validator if self[:check_regexp]
|
26
|
+
end
|
27
|
+
def get
|
28
|
+
if self[:getter].is_a? Proc
|
29
|
+
self[:getter].call self
|
30
|
+
elsif self[:env_names].is_a? ::Array and self[:check_regexp].is_a? Regexp
|
31
|
+
default_getter
|
32
|
+
else
|
33
|
+
[ to_pair ].to_h
|
34
|
+
end
|
35
|
+
end
|
36
|
+
private
|
37
|
+
def default_getter
|
38
|
+
(self[:env_names].zip (self[:check_regexp].match self[:value]).to_a).to_h
|
39
|
+
end
|
40
|
+
def default_validator
|
41
|
+
raise RuntimeError, "Option #{self[:name]} become #{self[:value].class} during validation" unless self[:value].is_a? ::String or self[:value].kind_of? Numeric
|
42
|
+
raise ArgumentError, "#{self[:desc]} (#{self[:value].to_s}) must satisfy #{self[:check_regexp].to_s}" unless
|
43
|
+
self[:value].to_s.match self[:check_regexp]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
class Bool < Standard
|
47
|
+
def validate! context = ConfSources::Default.new
|
48
|
+
default_validator
|
49
|
+
self[:validator].call(self,context) if self[:validator].is_a? Proc
|
50
|
+
end
|
51
|
+
def to_s
|
52
|
+
(self[:env_name] ? self[:env_name] : self[:name] ).to_s.capitalize.gsub('_',' ') + ': ' + self[:value].to_s
|
53
|
+
end
|
54
|
+
private
|
55
|
+
def default_getter
|
56
|
+
{ (self[:env_name] ? self[:env_name] : self[:name] ) => (self[:value] ? "true" : "") }
|
57
|
+
end
|
58
|
+
def default_validator
|
59
|
+
unless self[:value].is_a? TrueClass or self[:value].is_a? FalseClass
|
60
|
+
raise ArgumentError, "Value #{self[:name]} is not boolean, but #{self[:value].class}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
class Array < Standard
|
65
|
+
def validate! context = ConfSources::Default.new
|
66
|
+
default_validator
|
67
|
+
self[:validator].call(self,context) if self[:validator].is_a? Proc
|
68
|
+
end
|
69
|
+
private
|
70
|
+
def default_validator
|
71
|
+
if self[:value].is_a? ::String
|
72
|
+
unless self[:separator].is_a? ::String and self[:separator].length == 1
|
73
|
+
raise ArgumentError, "#{self[:name]} is a String, but :separator is not 1 symbol length String"
|
74
|
+
end
|
75
|
+
self[:value] = self[:value].split self[:separator]
|
76
|
+
end
|
77
|
+
unless self[:value].is_a? ::Array
|
78
|
+
raise ArgumentError, "#{self[:name]} should be Array, but #{self[:value].class}"
|
79
|
+
end
|
80
|
+
if self[:check_regexp]
|
81
|
+
self[:value].each {|el|
|
82
|
+
raise ArgumentError, "Array element #{el} sould satisfy #{self[:check_regexp]}, but is not" unless
|
83
|
+
el.to_s.match self[:check_regexp]
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
def default_getter
|
88
|
+
if self[:env_names]
|
89
|
+
(self[:env_names].zip (self[:value])).to_h
|
90
|
+
elsif self[:env_name]
|
91
|
+
{ self[:env_name] => self[:value].join(self[:separator]) }
|
92
|
+
else
|
93
|
+
{ self[:name].to_s => self[:value].join(self[:separator]) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/confsources.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
#Sources is the raw-data config
|
4
|
+
#It imay not valid, but can parse itself to hash
|
5
|
+
module ConfSources
|
6
|
+
require 'securerandom'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'ipaddr'
|
9
|
+
require 'yaml'
|
10
|
+
require 'thor'
|
11
|
+
|
12
|
+
def self.is_option_exist? opt_name
|
13
|
+
! ConfMaker::get_options.select{ |opt| opt[:name] == opt_name }.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
class Default
|
17
|
+
attr_reader :options
|
18
|
+
def initialize
|
19
|
+
@options = ConfMaker::get_options.collect{|e| e.clone }
|
20
|
+
#Some default options may be not valid
|
21
|
+
#validate!
|
22
|
+
end
|
23
|
+
def merge other_one
|
24
|
+
options = @options.collect { |el| (other_one.is_defined? el[:name]) ? other_one[el[:name]] : el }
|
25
|
+
Clone.new options
|
26
|
+
end
|
27
|
+
def merge! other_one
|
28
|
+
@options.collect! { |el| (other_one.is_defined? el[:name]) ? other_one[el[:name]].clone : el }
|
29
|
+
end
|
30
|
+
def [] arg
|
31
|
+
@options.select{ |opt| opt[:name] == arg }.first
|
32
|
+
end
|
33
|
+
def validate!
|
34
|
+
@options.each { |el|
|
35
|
+
unless @options.select{ |opt| opt[:name] == el[:name] }.count == 1
|
36
|
+
raise ArgumentError, "Options with name #{el[:name]} duplicated"
|
37
|
+
end
|
38
|
+
unless @options.select{ |opt| opt[:name] == el[:name] }.count == 1
|
39
|
+
raise ArgumentError, "Option #{el[:name]} duplicates aliases with #{opt[:name]}"
|
40
|
+
end
|
41
|
+
el.validate! Clone.new(self)
|
42
|
+
}
|
43
|
+
end
|
44
|
+
def to_a
|
45
|
+
@options.collect{ |opt| opt.to_h }
|
46
|
+
end
|
47
|
+
def to_pairs
|
48
|
+
@options.collect{ |opt| opt.to_pair }.to_h
|
49
|
+
end
|
50
|
+
#Export into bash environment script
|
51
|
+
def export_to file
|
52
|
+
::File.open(file,"w+") { |f|
|
53
|
+
@options.each { |opt|
|
54
|
+
opt.get.each_pair { |k,v|
|
55
|
+
f.puts "#{k.to_s}='#{v.to_s}'"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
#Human-readable description
|
61
|
+
def to_s
|
62
|
+
("Configuration:\n" + @options.collect {|opt| opt.to_s}.join("\n")).gsub("\n","\n\t")
|
63
|
+
end
|
64
|
+
def is_defined? opt_name
|
65
|
+
self[opt_name].kind_of? ConfOptions::Standard
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Clone < Default
|
70
|
+
def initialize other
|
71
|
+
if other.kind_of? Default
|
72
|
+
@options = other.options.collect {|el|el.clone}
|
73
|
+
elsif other.is_a? Array
|
74
|
+
@options = other.collect {|el| el.clone}
|
75
|
+
else
|
76
|
+
raise RuntimeError, "Can't clone configuration sorce from #{other.class}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class File < Default
|
82
|
+
def initialize conf_file
|
83
|
+
loaded_yaml = YAML.load_file conf_file
|
84
|
+
if loaded_yaml.is_a? Hash
|
85
|
+
@options = loaded_yaml.select { |k,v| ConfSources::is_option_exist? k.to_sym and not v.nil?
|
86
|
+
}.collect { |k,v|
|
87
|
+
candidate = ConfMaker::get_options.select{|e|e[:name] == k.to_sym}.first.clone
|
88
|
+
candidate[:value] = v
|
89
|
+
candidate
|
90
|
+
}
|
91
|
+
else
|
92
|
+
@options = []
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class CommandLine < Default
|
98
|
+
class Wrapper < Thor
|
99
|
+
desc "", ConfMaker::get_desc
|
100
|
+
ConfMaker.get_options.each { |opt|
|
101
|
+
class_option opt[:name], :type => opt[:cmdline_type],
|
102
|
+
:desc => opt[:desc],
|
103
|
+
:aliases => opt[:aliase],
|
104
|
+
:banner => opt[:example]
|
105
|
+
}
|
106
|
+
def execute
|
107
|
+
options.to_h
|
108
|
+
end
|
109
|
+
default_task :execute
|
110
|
+
end
|
111
|
+
def initialize
|
112
|
+
result = Wrapper.start
|
113
|
+
unless result.is_a? Hash
|
114
|
+
exit 0
|
115
|
+
end
|
116
|
+
@options = result.collect { |k,v|
|
117
|
+
candidate = ConfMaker::get_options.select{|e|e[:name] == k.to_sym}.first.clone
|
118
|
+
candidate[:value] = v
|
119
|
+
candidate
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: confmaker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nothing
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Configuration getter, parser and validator
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/confmaker.rb
|
34
|
+
- lib/confoptions.rb
|
35
|
+
- lib/confsources.rb
|
36
|
+
homepage:
|
37
|
+
licenses: []
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 2.5.2
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: Your utility configuration maker
|
59
|
+
test_files: []
|