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 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
@@ -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
@@ -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: []