grouik 1.0.0
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/src/bin/grouik +36 -0
- data/src/lib/grouik/cli.rb +172 -0
- data/src/lib/grouik/concerns/helpable.rb +19 -0
- data/src/lib/grouik/concerns.rb +16 -0
- data/src/lib/grouik/formatter.rb +67 -0
- data/src/lib/grouik/helpers/cli.rb +102 -0
- data/src/lib/grouik/helpers/loader.rb +72 -0
- data/src/lib/grouik/helpers/process.rb +82 -0
- data/src/lib/grouik/helpers.rb +50 -0
- data/src/lib/grouik/loadable.rb +51 -0
- data/src/lib/grouik/loader.rb +156 -0
- data/src/lib/grouik/output/message.rb +54 -0
- data/src/lib/grouik/output/messager.rb +86 -0
- data/src/lib/grouik/output.rb +13 -0
- data/src/lib/grouik/process.rb +195 -0
- data/src/lib/grouik/types.rb +46 -0
- data/src/lib/grouik/version_info.yml +16 -0
- data/src/lib/grouik.rb +101 -0
- metadata +216 -0
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require 'benchmark'
|
10
|
+
require 'pathname'
|
11
|
+
require 'ostruct'
|
12
|
+
|
13
|
+
require 'grouik/concerns'
|
14
|
+
|
15
|
+
# Main class loader
|
16
|
+
#
|
17
|
+
# loads files during ``Grouik::Loader#load_all``
|
18
|
+
class Grouik::Loader
|
19
|
+
attr_accessor :basedir
|
20
|
+
attr_accessor :ignores
|
21
|
+
attr_reader :paths
|
22
|
+
|
23
|
+
attr_reader :attempts
|
24
|
+
attr_reader :errors
|
25
|
+
attr_reader :stats
|
26
|
+
|
27
|
+
include Grouik::Concerns::Helpable
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
self.basedir = '.'
|
31
|
+
self.ignores = []
|
32
|
+
|
33
|
+
@loadeds = []
|
34
|
+
@errors = {}
|
35
|
+
@loadables = []
|
36
|
+
@attempts = 0
|
37
|
+
@stats = nil
|
38
|
+
|
39
|
+
return self unless block_given?
|
40
|
+
|
41
|
+
yield self
|
42
|
+
register
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [Array<String|Regexp>] ignores
|
46
|
+
def ignores=(ignores)
|
47
|
+
@ignores = helpers.get(:loader).make_ignores(ignores)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param [Array<String>] paths
|
51
|
+
def paths=(paths)
|
52
|
+
@paths = paths.to_a.map { |path| Pathname.new(path.to_s) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Array<Pathname>]
|
56
|
+
def paths
|
57
|
+
(@paths || (@paths.empty? ? ['.'] : @paths)).clone
|
58
|
+
end
|
59
|
+
|
60
|
+
# Register paths
|
61
|
+
#
|
62
|
+
# @return [self]
|
63
|
+
def register
|
64
|
+
helpers.get(:loader).register_paths(basedir, @paths)
|
65
|
+
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
# Get loadables
|
70
|
+
#
|
71
|
+
# @return [Array<Grouik::Loadable>]
|
72
|
+
def loadables
|
73
|
+
if @loadables.empty?
|
74
|
+
self.basedir do
|
75
|
+
@loadables = helpers.get(:loader)
|
76
|
+
.collect_loadables(paths)
|
77
|
+
.ignores(ignores)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
@loadables.clone
|
82
|
+
end
|
83
|
+
|
84
|
+
# @return [Pathname]
|
85
|
+
def basedir
|
86
|
+
Dir.chdir(helpers.get(:loader).pwd.join(basedir)) { yield } if block_given?
|
87
|
+
|
88
|
+
Pathname.new(@basedir)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [self]
|
92
|
+
def load_all
|
93
|
+
return @loadeds.clone unless @loadeds.empty?
|
94
|
+
|
95
|
+
loadables = self.loadables
|
96
|
+
@loadeds = []
|
97
|
+
@errors = {}
|
98
|
+
|
99
|
+
@stats = Benchmark.measure do
|
100
|
+
loop do
|
101
|
+
loadables = process_loadables(loadables)
|
102
|
+
break if loadables.nil? or (loadables and loadables.empty?)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
@loadeds.compact
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
# Format using a formatter
|
110
|
+
#
|
111
|
+
# @param [Hash] options
|
112
|
+
# @return [String]
|
113
|
+
def format(options = {})
|
114
|
+
Grouik.get(:formatter).format(load_all.loadables, options).to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
def loaded?
|
118
|
+
self.loadables.size == @loadeds.size
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Fixnum]
|
122
|
+
def attempts_maxcount
|
123
|
+
(self.loadables.size**2) + 1
|
124
|
+
end
|
125
|
+
|
126
|
+
protected
|
127
|
+
|
128
|
+
def process_loadables(processables)
|
129
|
+
processables.each_with_index do |loadable, index|
|
130
|
+
return [] if attempts >= attempts_maxcount or processables.empty?
|
131
|
+
|
132
|
+
@attempts += 1
|
133
|
+
loaded = nil
|
134
|
+
begin
|
135
|
+
loaded = loadable.load(helpers.get(:loader).pwd.join(basedir))
|
136
|
+
rescue StandardError => e
|
137
|
+
unless @errors[loadable.to_s]
|
138
|
+
@errors[loadable.to_s] = OpenStruct.new(
|
139
|
+
source: loadable.to_s,
|
140
|
+
message: e.message.lines[0].strip.freeze,
|
141
|
+
line: e.backtrace[0].split(':')[1],
|
142
|
+
error: e
|
143
|
+
).freeze
|
144
|
+
end
|
145
|
+
next
|
146
|
+
end
|
147
|
+
|
148
|
+
next if loaded.nil?
|
149
|
+
|
150
|
+
@loadeds.push(processables.delete_at(index))
|
151
|
+
# when loadable is loaded, then error is removed
|
152
|
+
@errors.delete(loadable.to_s)
|
153
|
+
end
|
154
|
+
processables
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
# Describe a message (sent on a IO as STDOUT/STDERR)
|
10
|
+
class Grouik::Output::Message
|
11
|
+
attr_accessor :content
|
12
|
+
attr_accessor :type
|
13
|
+
attr_accessor :stream
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
yield self if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param content [String]
|
20
|
+
def content=(content)
|
21
|
+
@content = content.to_s.empty? ? nil : content.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param stream [IO]
|
25
|
+
def stream=(stream)
|
26
|
+
@stream = stream.clone
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [IO]
|
30
|
+
def stream
|
31
|
+
@stream || STDOUT.clone
|
32
|
+
end
|
33
|
+
|
34
|
+
# @raise [RuntimeError]
|
35
|
+
# @return [self]
|
36
|
+
def send
|
37
|
+
attrs = [:stream, :content, :type]
|
38
|
+
attrs.each do |attr|
|
39
|
+
raise 'attributes %s must be set' % attrs if public_send(attr).nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
messager_class.new(stream, content.to_s).output(type)
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
# @return [Grouik::Output::Messager]
|
49
|
+
def messager_class
|
50
|
+
require '%s/messager' % __dir__
|
51
|
+
|
52
|
+
Grouik::Output::Messager
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
# Provide a wrapper over ``Rainbow``
|
10
|
+
class Grouik::Output::Messager
|
11
|
+
attr_accessor :stream
|
12
|
+
attr_accessor :content
|
13
|
+
|
14
|
+
def initialize(stream = STDOUT, content = nil)
|
15
|
+
@stream = stream
|
16
|
+
self.content = content
|
17
|
+
end
|
18
|
+
|
19
|
+
def content=(content)
|
20
|
+
@content = content.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
# @todo Catch ``NoMethodError`` or similar error
|
24
|
+
# @return [self]
|
25
|
+
def output(type)
|
26
|
+
stream.puts self.format_as(type)
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
# @return [self]
|
33
|
+
def output(stream, type)
|
34
|
+
self.new(stream, content).output(type)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Defines available formats
|
38
|
+
#
|
39
|
+
# @return [Hash]
|
40
|
+
def formats
|
41
|
+
{
|
42
|
+
status_success: {
|
43
|
+
background: :green,
|
44
|
+
color: :black,
|
45
|
+
},
|
46
|
+
status_failure: {
|
47
|
+
background: :red,
|
48
|
+
color: :black,
|
49
|
+
},
|
50
|
+
error: {
|
51
|
+
color: :red,
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param type [Symbol|String]
|
58
|
+
# @return [Rainbow::Presenter, Rainbow::NullPresenter]
|
59
|
+
def format_as(type)
|
60
|
+
colorize(self.class.formats[type.to_sym])
|
61
|
+
end
|
62
|
+
|
63
|
+
# Denote output is colorizable (``tty?``)
|
64
|
+
def colorizable?
|
65
|
+
stream.tty?
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
# Get a colorizable (almost a wrapper over ``Rainbow``) content instance
|
71
|
+
#
|
72
|
+
# @return [Rainbow::Presenter, Rainbow::NullPresenter]
|
73
|
+
def colorizable
|
74
|
+
require 'rainbow'
|
75
|
+
|
76
|
+
Rainbow.enabled = colorizable?
|
77
|
+
Rainbow::Wrapper.new(colorizable?).wrap(content)
|
78
|
+
end
|
79
|
+
|
80
|
+
def colorize(format = {})
|
81
|
+
colorizable = self.colorizable.clone
|
82
|
+
format.to_h.each { |k, v| colorizable = colorizable.public_send(k, v) }
|
83
|
+
|
84
|
+
colorizable
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
module Grouik::Output
|
10
|
+
[:message].each do |req|
|
11
|
+
require '%s/output/%s' % [__dir__, req]
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
|
11
|
+
require 'grouik/concerns'
|
12
|
+
|
13
|
+
# Intended to wrap ``Grouik::Loader``
|
14
|
+
#
|
15
|
+
# Easify reusability through ``Grouik::Cli``
|
16
|
+
# or as standalone (for example in a Rake task)
|
17
|
+
#
|
18
|
+
# Sample of use:
|
19
|
+
#
|
20
|
+
# ~~~~
|
21
|
+
# task 'src/ceres.rb' do
|
22
|
+
# require 'grouik'
|
23
|
+
#
|
24
|
+
# Grouik.process do |process|
|
25
|
+
# process.verbose = false
|
26
|
+
# process.paths = ['lib']
|
27
|
+
# process.basedir = 'src'
|
28
|
+
# process.output = 'src/ceres.rb'
|
29
|
+
# process.template = 'src/ceres.tpl'
|
30
|
+
# end.on_failure { exit Errno::ECANCELED::Errno }
|
31
|
+
# end
|
32
|
+
# ~~~~
|
33
|
+
class Grouik::Process
|
34
|
+
attr_accessor :template
|
35
|
+
attr_accessor :bootstrap
|
36
|
+
attr_accessor :verbose
|
37
|
+
attr_reader :output
|
38
|
+
|
39
|
+
include Grouik::Concerns::Helpable
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
@output = nil
|
43
|
+
@template = nil
|
44
|
+
@bootstrap = nil
|
45
|
+
@verbose = false
|
46
|
+
|
47
|
+
@loader = Grouik::Loader.new
|
48
|
+
yield self if block_given?
|
49
|
+
@loader.register
|
50
|
+
end
|
51
|
+
|
52
|
+
def verbose?
|
53
|
+
!!@verbose
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [Pathname|String] output
|
57
|
+
# @return [Object]
|
58
|
+
def output=(output)
|
59
|
+
@output = output.is_a?(String) ? Pathname.new(output) : output
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [self]
|
63
|
+
# @todo Do not suppress exceptions
|
64
|
+
def process
|
65
|
+
@output.write('') if @output.respond_to?(:file?) and !@output.exist?
|
66
|
+
if bootstrap
|
67
|
+
begin
|
68
|
+
require bootstrap if bootstrap
|
69
|
+
rescue NameError
|
70
|
+
rescue LoadError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
output = @loader.format(template: @template)
|
75
|
+
display_errors
|
76
|
+
# avoid to break previouly written file in case of failure
|
77
|
+
@output.write(output) if success?
|
78
|
+
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
# @param [Hash] options
|
83
|
+
def format(options = {})
|
84
|
+
@loader.format(options)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Errors encountered during process
|
88
|
+
#
|
89
|
+
# @return [Hash]
|
90
|
+
def errors
|
91
|
+
loader.errors
|
92
|
+
end
|
93
|
+
|
94
|
+
# Denote errors encountered
|
95
|
+
#
|
96
|
+
# @return [Boolean]
|
97
|
+
def errors?
|
98
|
+
errors.empty? ? false : true
|
99
|
+
end
|
100
|
+
|
101
|
+
# Display encountered errors
|
102
|
+
#
|
103
|
+
# @return [self]
|
104
|
+
def display_errors
|
105
|
+
helpers.get(:process).display_errors(self)
|
106
|
+
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
# Display status
|
111
|
+
#
|
112
|
+
# @return [self]
|
113
|
+
def display_status
|
114
|
+
helpers.get(:process).display_status(self)
|
115
|
+
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
# Denote process is a success
|
120
|
+
#
|
121
|
+
# @return [Boolean]
|
122
|
+
def success?
|
123
|
+
loader.loaded? and !errors?
|
124
|
+
end
|
125
|
+
|
126
|
+
# Denote process is a failure
|
127
|
+
#
|
128
|
+
# @return [Boolean]
|
129
|
+
def failure?
|
130
|
+
!success?
|
131
|
+
end
|
132
|
+
|
133
|
+
# Block executed on failure
|
134
|
+
#
|
135
|
+
# @yield [self] Block executed when errors have been encountered
|
136
|
+
# @return [self]
|
137
|
+
def on_failure
|
138
|
+
yield(self) if failure?
|
139
|
+
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
# Block executed on success
|
144
|
+
#
|
145
|
+
# @yield [self] Block executed when process is a success
|
146
|
+
# @return [self]
|
147
|
+
def on_success
|
148
|
+
yield(self) if success?
|
149
|
+
|
150
|
+
self
|
151
|
+
end
|
152
|
+
|
153
|
+
# Provides access to public accessors
|
154
|
+
def method_missing(method, *args, &block)
|
155
|
+
if respond_to_missing?(method)
|
156
|
+
@loader.public_send(method, *args, &block)
|
157
|
+
else
|
158
|
+
super
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def respond_to_missing?(method, include_private = false)
|
163
|
+
result = loader_accessors.include?(method.to_sym)
|
164
|
+
unless result
|
165
|
+
return super if include_private
|
166
|
+
end
|
167
|
+
|
168
|
+
result
|
169
|
+
end
|
170
|
+
|
171
|
+
# Get loader
|
172
|
+
#
|
173
|
+
# @return [Grouik::Loader]
|
174
|
+
def loader
|
175
|
+
@loader.clone.freeze
|
176
|
+
end
|
177
|
+
|
178
|
+
protected
|
179
|
+
|
180
|
+
# Get loader public attributes
|
181
|
+
#
|
182
|
+
# @return [Array]
|
183
|
+
def loader_attributes
|
184
|
+
loader.public_methods
|
185
|
+
.grep(/^\w+=$/)
|
186
|
+
.map { |m| m.to_s.gsub(/=$/, '').to_sym }
|
187
|
+
end
|
188
|
+
|
189
|
+
# Get loader public accessors
|
190
|
+
#
|
191
|
+
# @return [Array]
|
192
|
+
def loader_accessors
|
193
|
+
loader_attributes + loader_attributes.map { |m| ('%s=' % m).to_sym }
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
# Special types in use
|
10
|
+
module Grouik::Types
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get filtered loadables, using ignores regexp
|
14
|
+
#
|
15
|
+
# @return [Array<Grouik::Loadable>]
|
16
|
+
class Grouik::Types::Loadables < Array
|
17
|
+
# Removes ignored patterns (regexps)
|
18
|
+
#
|
19
|
+
# @param [Array<Regexp>] regexps
|
20
|
+
# @return [self]
|
21
|
+
def ignores(regexps)
|
22
|
+
filter = lambda do |loadable, regexps|
|
23
|
+
regexps.each do |regexp|
|
24
|
+
return true if loadable and regexp.match(loadable.to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
self.clone.delete_if do |loadable|
|
31
|
+
filter.call(loadable, regexps)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [self]
|
36
|
+
def add_file(file, basedir = nil)
|
37
|
+
self.push(make_loadable(basedir, file))
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Grouik::Loadable]
|
43
|
+
def make_loadable(*args)
|
44
|
+
Grouik.get(:loadable_factory).call(*args)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
---
|
2
|
+
major: 1
|
3
|
+
minor: 0
|
4
|
+
patch: 0
|
5
|
+
authors: ['Dimitri Arrigoni']
|
6
|
+
email: 'dimitri@arrigoni.me'
|
7
|
+
date: '2017-03-28'
|
8
|
+
summary: 'Grouik!'
|
9
|
+
description: 'Simple require file generator'
|
10
|
+
licenses: ['GPL-3.0']
|
11
|
+
license: 'Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
12
|
+
License GPLv3+: GNU GPL version 3 or later
|
13
|
+
<http://www.gnu.org/licenses/gpl.html>.
|
14
|
+
This is free software: you are free to change and redistribute it.
|
15
|
+
There is NO WARRANTY, to the extent permitted by law.'
|
16
|
+
homepage: 'https://github.com/SwagDevOps/ruby-grouik'
|
data/src/lib/grouik.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2017 Dimitri Arrigoni <dimitri@arrigoni.me>
|
4
|
+
# License GPLv3+: GNU GPL version 3 or later
|
5
|
+
# <http://www.gnu.org/licenses/gpl.html>.
|
6
|
+
# This is free software: you are free to change and redistribute it.
|
7
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
require 'active_support/inflector'
|
11
|
+
require 'version_info'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift Pathname.new(__dir__)
|
14
|
+
|
15
|
+
# Produce a ``require`` file, resolving classes dependencies
|
16
|
+
#
|
17
|
+
# Sample of use:
|
18
|
+
#
|
19
|
+
# ~~~~
|
20
|
+
# Grouik.process do |process|
|
21
|
+
# process.basedir = './path/to/my/project'
|
22
|
+
# process.paths = ['lib']
|
23
|
+
# process.ignores = []
|
24
|
+
# process.output = '/dev/stdout'
|
25
|
+
# process.template = 'lib/main'
|
26
|
+
# process.bootstrap = nil
|
27
|
+
# process.verbose = true
|
28
|
+
# end.success? ? 0 : 1
|
29
|
+
# ~~~~
|
30
|
+
#
|
31
|
+
# or using command line.
|
32
|
+
module Grouik
|
33
|
+
require 'grouik/helpers'
|
34
|
+
|
35
|
+
class << self
|
36
|
+
# @return [Hash]
|
37
|
+
def version_info
|
38
|
+
unless self.const_defined?(:VERSION)
|
39
|
+
include VersionInfo
|
40
|
+
|
41
|
+
VersionInfo.file_format = :yaml
|
42
|
+
VERSION.file_name = self.version_filepath
|
43
|
+
VERSION.load
|
44
|
+
end
|
45
|
+
|
46
|
+
VERSION.to_hash.freeze
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
# Get path to the ``version`` file
|
52
|
+
#
|
53
|
+
# @return [Pathname]
|
54
|
+
def version_filepath
|
55
|
+
name = ActiveSupport::Inflector.underscore(self.name)
|
56
|
+
|
57
|
+
Pathname.new(__dir__).join(name, 'version_info.yml')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# registers version_info
|
62
|
+
self.version_info
|
63
|
+
# loads sub(modules|classes)
|
64
|
+
[:loader, :loadable, :formatter, :process, :output].each do |r|
|
65
|
+
require '%s/%s' % [ActiveSupport::Inflector.underscore(name), r]
|
66
|
+
end
|
67
|
+
|
68
|
+
@components = {
|
69
|
+
process_class: Process,
|
70
|
+
formatter: Formatter,
|
71
|
+
helpers: Grouik::Helpers,
|
72
|
+
inflector: ActiveSupport::Inflector,
|
73
|
+
messager_factory: ->(&block) { Output::Message.new(&block) },
|
74
|
+
loadable_factory: ->(base, path) { Loadable.new(base, path) },
|
75
|
+
}
|
76
|
+
|
77
|
+
class << self
|
78
|
+
attr_accessor :components
|
79
|
+
|
80
|
+
# Access to components
|
81
|
+
#
|
82
|
+
# @param name [String, Symbol] name of component
|
83
|
+
# @return [Object]
|
84
|
+
# @see Grouik.components
|
85
|
+
def get(name)
|
86
|
+
components.fetch(name.to_sym)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Initialize a Process and process it
|
90
|
+
#
|
91
|
+
# @return [Grouik::Process]
|
92
|
+
def process(&block)
|
93
|
+
self.get(:process_class).new(&block).process
|
94
|
+
end
|
95
|
+
|
96
|
+
def message(&block)
|
97
|
+
self.get(:messager_factory).call(&block).send
|
98
|
+
self
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|