dupervisor 1.0.2
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/.atom-build.json +22 -0
- data/.codeclimate.yml +30 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +162 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dupervisor.gemspec +30 -0
- data/exe/dv +16 -0
- data/lib/dupervisor.rb +8 -0
- data/lib/dupervisor/cli.rb +84 -0
- data/lib/dupervisor/config.rb +30 -0
- data/lib/dupervisor/content.rb +27 -0
- data/lib/dupervisor/detector.rb +23 -0
- data/lib/dupervisor/formats.rb +60 -0
- data/lib/dupervisor/formats/ini.rb +45 -0
- data/lib/dupervisor/formats/json.rb +11 -0
- data/lib/dupervisor/formats/yaml.rb +14 -0
- data/lib/dupervisor/main.rb +24 -0
- data/lib/dupervisor/parser.rb +50 -0
- data/lib/dupervisor/renderer.rb +24 -0
- data/lib/dupervisor/version.rb +3 -0
- metadata +189 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module DuperVisor
|
2
|
+
module Formats
|
3
|
+
module Accessors
|
4
|
+
def formats
|
5
|
+
::DuperVisor::Formats::Base.formats
|
6
|
+
end
|
7
|
+
def format_classes
|
8
|
+
::DuperVisor::Formats::Base.formats.values.map(&:to_s).sort.uniq.map{ |klass| Module.const_get(klass) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Base
|
13
|
+
@formats = {}
|
14
|
+
class << self
|
15
|
+
attr_writer :formats
|
16
|
+
attr_accessor :format_aliases
|
17
|
+
|
18
|
+
# Returns a hash: +{ format: format_class, format_alias: format_class, ...}+
|
19
|
+
# For example { yaml: YAML, yml: YAML, etc.}
|
20
|
+
def formats
|
21
|
+
aliases = {}
|
22
|
+
@formats.values.each do |format_class|
|
23
|
+
if format_class.aliases && !format_class.aliases.empty?
|
24
|
+
format_class.aliases.each { |format_alias| aliases[format_alias] = format_class }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
@formats.merge!(aliases)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.inherited(klass)
|
32
|
+
klass.instance_eval do
|
33
|
+
class << self
|
34
|
+
%i(aliases from to errors).each do |a|
|
35
|
+
define_method(a) { |*args|
|
36
|
+
arg = args.first
|
37
|
+
%i(aliases errors).each do |array_field|
|
38
|
+
if a == array_field && arg && !arg.is_a?(Array)
|
39
|
+
arg = [arg]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
arg ?
|
43
|
+
instance_variable_set("@#{a}".to_sym, arg) :
|
44
|
+
instance_variable_get("@#{a}".to_sym)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def format
|
50
|
+
self.name.split(/::/)[-1].downcase.to_sym
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
self.formats[klass.format] = klass
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
DuperVisor.dir('dupervisor/formats')
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'inifile'
|
2
|
+
require_relative '../formats'
|
3
|
+
module DuperVisor
|
4
|
+
module Formats
|
5
|
+
class Ini < Base
|
6
|
+
def self.transform_hash
|
7
|
+
delete_keys = ::Set.new
|
8
|
+
keys_to_add = {}
|
9
|
+
if block_given?
|
10
|
+
hash = yield(keys_to_add, delete_keys)
|
11
|
+
end
|
12
|
+
delete_keys.each { |k| hash.delete(k) }
|
13
|
+
hash.merge!(keys_to_add)
|
14
|
+
end
|
15
|
+
|
16
|
+
errors [IniFile::Error]
|
17
|
+
|
18
|
+
from ->(string) do
|
19
|
+
hash = IniFile.new(content: string).to_h
|
20
|
+
Ini.transform_hash do |keys_to_add, delete_keys|
|
21
|
+
hash.keys.select { |k| hash[k].is_a?(Hash) && k =~ /.*:.*/ }.each do |key|
|
22
|
+
outer, inner = key.split(/:/)
|
23
|
+
keys_to_add[outer] ||= {}
|
24
|
+
keys_to_add[outer][inner] = hash[key]
|
25
|
+
delete_keys << key
|
26
|
+
end
|
27
|
+
hash
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
to ->(hash) do
|
32
|
+
Ini.transform_hash do |keys_to_add, delete_keys|
|
33
|
+
hash.keys.select { |k| hash[k].is_a?(Hash) }.each do |key|
|
34
|
+
hash[key].keys.select { |k| hash[key][k].is_a?(Hash) }.each do |sub_key|
|
35
|
+
keys_to_add["#{key}:#{sub_key}"] = hash[key][sub_key]
|
36
|
+
delete_keys << key
|
37
|
+
end
|
38
|
+
end
|
39
|
+
hash
|
40
|
+
end
|
41
|
+
IniFile.new.merge!(hash).to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative '../formats'
|
3
|
+
|
4
|
+
module DuperVisor
|
5
|
+
module Formats
|
6
|
+
class YAML < Base
|
7
|
+
aliases %i(yml)
|
8
|
+
from ->(string) { ::YAML.load(string) }
|
9
|
+
to ->(hash) { ::YAML.dump(hash) }
|
10
|
+
errors [Psych::SyntaxError]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'renderer'
|
2
|
+
require_relative 'detector'
|
3
|
+
require_relative 'parser'
|
4
|
+
require_relative 'content'
|
5
|
+
require 'colored2'
|
6
|
+
module DuperVisor
|
7
|
+
class Main
|
8
|
+
attr_accessor :config, :from_format, :content
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
self.config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
config.validate!
|
16
|
+
self.from_format = Detector.new(ARGF.filename).detect
|
17
|
+
self.content = Parser.new(ARGF.read).parse(from_format)
|
18
|
+
Renderer.new(content.parse_result, config.output).render(config.to)
|
19
|
+
rescue DuperVisor::Parser::ParseError => e
|
20
|
+
puts ' Error:'.bold.white + ' Unable to parse input.'.bold.red
|
21
|
+
puts 'Details:'.bold.white + " #{e.inspect}".red
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative 'formats'
|
2
|
+
module DuperVisor
|
3
|
+
#
|
4
|
+
# This class is responsible for coordination of parsing attempts of a
|
5
|
+
# given contet with diffirent format parsers.
|
6
|
+
#
|
7
|
+
class Parser
|
8
|
+
class ParseError < StandardError; end
|
9
|
+
class FormatNotFound < ParseError; end
|
10
|
+
|
11
|
+
include DuperVisor::Formats::Accessors
|
12
|
+
|
13
|
+
attr_accessor :content, :parse_errors
|
14
|
+
|
15
|
+
def initialize(body)
|
16
|
+
self.content = Content.new(body: body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(input_format = nil)
|
20
|
+
self.parse_errors = {}
|
21
|
+
content.parse_result = nil
|
22
|
+
formats_to_check = input_format ? [ formats[input_format] ] : format_classes
|
23
|
+
formats_to_check.each do |format_class|
|
24
|
+
format = format_class.format
|
25
|
+
parse_result = try_format(format, format_class)
|
26
|
+
if parse_result
|
27
|
+
content.parse_result = parse_result
|
28
|
+
content.format = format
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
unless content.parse_result || parse_errors.empty?
|
33
|
+
if input_format
|
34
|
+
raise ParseError.new("Can not parse from format #{input_format}. Format exception:" +
|
35
|
+
parse_errors.values.map(&:inspect).join("\n"))
|
36
|
+
else
|
37
|
+
raise FormatNotFound.new('No suitable format detected. Query #parse_errors for specifics.')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
content
|
41
|
+
end
|
42
|
+
|
43
|
+
def try_format(format, format_class)
|
44
|
+
format_class.from.call(content.body)
|
45
|
+
rescue *(format_class.errors) => e
|
46
|
+
self.parse_errors[format] = e
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'set'
|
2
|
+
require_relative 'formats'
|
3
|
+
module DuperVisor
|
4
|
+
class Renderer
|
5
|
+
include DuperVisor::Formats::Accessors
|
6
|
+
|
7
|
+
attr_accessor :output, :content_hash, :rendered_content
|
8
|
+
|
9
|
+
def initialize(content_hash, output_stream = nil)
|
10
|
+
raise ArgumentError.new('Invalid arguments - expecting a stream and a hash') unless content_hash.is_a?(Hash)
|
11
|
+
self.output = output_stream
|
12
|
+
self.content_hash = content_hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(format)
|
16
|
+
self.rendered_content = self.formats[format].to.call(content_hash)
|
17
|
+
if output.respond_to?(:puts)
|
18
|
+
output.puts rendered_content
|
19
|
+
output.close if output.respond_to?(:close) && output != STDOUT
|
20
|
+
end
|
21
|
+
rendered_content
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dupervisor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Konstantin Gredeskoul
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: require_dir
|
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
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: awesome_print
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colored2
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: inifile
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: codeclimate-test-reporter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.12'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.12'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '10.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '10.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
125
|
+
description: This gem's purpose in life is to freely convert various configurations
|
126
|
+
between supported formats, which are currently YAML, JSON and Windows INI file format.
|
127
|
+
The gem is named after a popular package supervisord, which uses INI file format
|
128
|
+
for it's configuration. This gem will allow you to move supervisord configuration
|
129
|
+
into a YAML file, and integrate with other DevOps tools, while generating INI file
|
130
|
+
on the fly. When installed, library exposes 'dv' executable, which is a an easy-to-use
|
131
|
+
converter between these three formats.
|
132
|
+
email:
|
133
|
+
- kigster@gmail.com
|
134
|
+
executables:
|
135
|
+
- dv
|
136
|
+
extensions: []
|
137
|
+
extra_rdoc_files: []
|
138
|
+
files:
|
139
|
+
- ".atom-build.json"
|
140
|
+
- ".codeclimate.yml"
|
141
|
+
- ".gitignore"
|
142
|
+
- ".rspec"
|
143
|
+
- ".rubocop.yml"
|
144
|
+
- ".travis.yml"
|
145
|
+
- Gemfile
|
146
|
+
- LICENSE
|
147
|
+
- README.md
|
148
|
+
- Rakefile
|
149
|
+
- bin/console
|
150
|
+
- bin/setup
|
151
|
+
- dupervisor.gemspec
|
152
|
+
- exe/dv
|
153
|
+
- lib/dupervisor.rb
|
154
|
+
- lib/dupervisor/cli.rb
|
155
|
+
- lib/dupervisor/config.rb
|
156
|
+
- lib/dupervisor/content.rb
|
157
|
+
- lib/dupervisor/detector.rb
|
158
|
+
- lib/dupervisor/formats.rb
|
159
|
+
- lib/dupervisor/formats/ini.rb
|
160
|
+
- lib/dupervisor/formats/json.rb
|
161
|
+
- lib/dupervisor/formats/yaml.rb
|
162
|
+
- lib/dupervisor/main.rb
|
163
|
+
- lib/dupervisor/parser.rb
|
164
|
+
- lib/dupervisor/renderer.rb
|
165
|
+
- lib/dupervisor/version.rb
|
166
|
+
homepage: https://github.com/kigster/dupervisor
|
167
|
+
licenses: []
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.5.1
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Convert between YAML/JSON format and Windows INI format.
|
189
|
+
test_files: []
|