eco-rake 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/.gitlab-ci.yml +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +90 -0
- data/.yardopts +10 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +28 -0
- data/Rakefile +27 -0
- data/eco-rake.gemspec +34 -0
- data/lib/eco-rake/base/method_helpers.rb +55 -0
- data/lib/eco-rake/base/symbol_resolver.rb +82 -0
- data/lib/eco-rake/base.rb +25 -0
- data/lib/eco-rake/custom.rb +5 -0
- data/lib/eco-rake/default/const.rb +46 -0
- data/lib/eco-rake/default.rb +12 -0
- data/lib/eco-rake/lib/base_task.rb +9 -0
- data/lib/eco-rake/lib/concern/base.rb +21 -0
- data/lib/eco-rake/lib/concern/enviro.rb +23 -0
- data/lib/eco-rake/lib/concern/local_folder.rb +23 -0
- data/lib/eco-rake/lib/concern/person_schema.rb +24 -0
- data/lib/eco-rake/lib/concern.rb +11 -0
- data/lib/eco-rake/lib/export/payload.rb +78 -0
- data/lib/eco-rake/lib/export.rb +8 -0
- data/lib/eco-rake/lib/files/decrypt.rb +48 -0
- data/lib/eco-rake/lib/files/purge.rb +73 -0
- data/lib/eco-rake/lib/files/sftp.rb +49 -0
- data/lib/eco-rake/lib/files.rb +10 -0
- data/lib/eco-rake/lib/notify/mailer.rb +24 -0
- data/lib/eco-rake/lib/notify.rb +8 -0
- data/lib/eco-rake/lib/options.rb +8 -0
- data/lib/eco-rake/lib/people/base_task.rb +16 -0
- data/lib/eco-rake/lib/people/sync_launch.rb +131 -0
- data/lib/eco-rake/lib/people/sync_options.rb +15 -0
- data/lib/eco-rake/lib/people/sync_process.rb +48 -0
- data/lib/eco-rake/lib/people/sync_rely.rb +47 -0
- data/lib/eco-rake/lib/people.rb +12 -0
- data/lib/eco-rake/lib/task/runner_launch.rb +34 -0
- data/lib/eco-rake/lib/task/runner_options.rb +11 -0
- data/lib/eco-rake/lib/task/runner_rely.rb +40 -0
- data/lib/eco-rake/lib/task.rb +10 -0
- data/lib/eco-rake/lib.rb +15 -0
- data/lib/eco-rake/option/default_lookup.rb +39 -0
- data/lib/eco-rake/option/mirror.rb +34 -0
- data/lib/eco-rake/option/parented.rb +12 -0
- data/lib/eco-rake/option.rb +19 -0
- data/lib/eco-rake/options/default_lookup.rb +29 -0
- data/lib/eco-rake/options/forwarding/proxy.rb +125 -0
- data/lib/eco-rake/options/forwarding/rule.rb +82 -0
- data/lib/eco-rake/options/forwarding.rb +45 -0
- data/lib/eco-rake/options/library.rb +81 -0
- data/lib/eco-rake/options/parental.rb +37 -0
- data/lib/eco-rake/options/set.rb +21 -0
- data/lib/eco-rake/options.rb +25 -0
- data/lib/eco-rake/rake_task.rb +10 -0
- data/lib/eco-rake/shell/command.rb +59 -0
- data/lib/eco-rake/shell/eco_helpers.rb +10 -0
- data/lib/eco-rake/shell/files.rb +83 -0
- data/lib/eco-rake/shell/gpg.rb +54 -0
- data/lib/eco-rake/shell.rb +18 -0
- data/lib/eco-rake/tasks.rb +12 -0
- data/lib/eco-rake/utils/mailer.rb +91 -0
- data/lib/eco-rake/utils/mailing.rb +19 -0
- data/lib/eco-rake/utils/timing.rb +9 -0
- data/lib/eco-rake/utils.rb +19 -0
- data/lib/eco-rake/version.rb +5 -0
- data/lib/eco-rake.rb +16 -0
- metadata +271 -0
data/lib/eco-rake/lib.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'lib/base_task'
|
2
|
+
require_relative 'lib/notify'
|
3
|
+
require_relative 'lib/files'
|
4
|
+
require_relative 'lib/people'
|
5
|
+
require_relative 'lib/export'
|
6
|
+
require_relative 'lib/task'
|
7
|
+
|
8
|
+
class EcoRake
|
9
|
+
module Lib
|
10
|
+
# points to the library of option sets
|
11
|
+
def options_library
|
12
|
+
EcoRake::Options::Library
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class EcoRake
|
2
|
+
class Option
|
3
|
+
# To prevent dependencies, it should resolve via parent, where parent
|
4
|
+
# doesn't get new methods installed on the fly, but where the parent
|
5
|
+
# does have the final result (method or const)
|
6
|
+
module DefaultLookup
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
super(base)
|
10
|
+
base.extend EcoRake::Base::SymbolResolver
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Default may be a lookup
|
15
|
+
def default(&block)
|
16
|
+
return @default unless default_lookup?
|
17
|
+
result = self.class.safe_call(@default, parent, &block)
|
18
|
+
result = self.class.safe_call(result, &block) if [Proc, Method].any? {|k| result.is_a?(k)}
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
# @todo link to default resolver, but indirectly
|
23
|
+
# @return [Class, NilClass]
|
24
|
+
def type_coercion
|
25
|
+
return @type_coercion if @type_coercion
|
26
|
+
return nil unless default?
|
27
|
+
value = default
|
28
|
+
return nil if value.nil?
|
29
|
+
value.class
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def default_lookup?
|
35
|
+
@default.is_a?(Proc) || @default.is_a?(Method)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class EcoRake
|
2
|
+
class Option
|
3
|
+
module Mirror
|
4
|
+
# It allows to redirect options
|
5
|
+
# @param value [String, Symbol] the value to use.
|
6
|
+
# @return [String] command option with value
|
7
|
+
def mirror(value = :not_used, raise: false)
|
8
|
+
opt = name_hyphened
|
9
|
+
return boolean_mirror(value) unless argument?
|
10
|
+
|
11
|
+
missing = (value == :not_used) && !default?
|
12
|
+
msg = "required argument value #{argument} for option #{name} (#{short})"
|
13
|
+
raise ArgumentError, msg if missing && argument_required? && raise
|
14
|
+
return nil if missing && argument_required?
|
15
|
+
|
16
|
+
value = value == :not_used ? default : value
|
17
|
+
"#{opt} \"#{value}\""
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Implements the mirror of Boolean options/switches.
|
23
|
+
def boolean_mirror(value = :not_used)
|
24
|
+
opt = name_hyphened
|
25
|
+
puts "boolean_mirror (#{value}): #{opt}" if name == :no_get
|
26
|
+
|
27
|
+
return nil unless [TrueClass, NilClass, FalseClass].any? {|klass| type_coercion == klass}
|
28
|
+
enabled_value = !boolean_name? || [TrueClass, NilClass].any? {|klass| type_coercion == klass}
|
29
|
+
return opt if value == enabled_value
|
30
|
+
return name_false_hypen if boolean_name? && value == !enabled_value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class EcoRake
|
2
|
+
class Option < RakeCommander::Option
|
3
|
+
require_relative 'option/parented'
|
4
|
+
require_relative 'option/default_lookup'
|
5
|
+
require_relative 'option/mirror'
|
6
|
+
|
7
|
+
include EcoRake::Option::Parented
|
8
|
+
include EcoRake::Option::DefaultLookup
|
9
|
+
include EcoRake::Option::Mirror
|
10
|
+
|
11
|
+
def name_hyphened
|
12
|
+
self.class.name_hyphen(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def name_false_hyphened
|
16
|
+
self.class.name_hyphen("no-#{name}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
module DefaultLookup
|
4
|
+
class << self
|
5
|
+
def included(base)
|
6
|
+
super(base)
|
7
|
+
base.extend EcoRake::Base::MethodHelpers
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
# @note it extends `RakeCommander::Options`
|
14
|
+
# 1. default can be re-configured via callback or constant
|
15
|
+
# [ @see RakeCommander::Options::option ]
|
16
|
+
def option(*args, default_lookup: :not_used, **kargs, &block)
|
17
|
+
kargs.merge!(default: symbol_resolver(default_lookup, as: %i[method const])) unless default_lookup == :not_used
|
18
|
+
super(*args, **kargs, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# [ @see RakeCommander::Options::option_reopen ]
|
22
|
+
def option_reopen(*args, default_lookup: :not_used, **kargs, &block)
|
23
|
+
kargs.merge!(default: symbol_resolver(default_lookup, as: %i[method const])) unless default_lookup == :not_used
|
24
|
+
super(*args, **kargs, &block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
module Forwarding
|
4
|
+
# Collection of forwarding rules.
|
5
|
+
# @note rules keep associated with the option `name` (not their `short`)
|
6
|
+
# * The above means that changing the name of an exisint option will brake the link with
|
7
|
+
# a forwarding rule (as they do not auto-update on option name change)
|
8
|
+
class Proxy
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_reader :parent
|
12
|
+
|
13
|
+
# @param parent [RakeCommander::Options::Class]
|
14
|
+
def initialize(parent)
|
15
|
+
pklass = parent.is_a?(Class)? parent : parent.class
|
16
|
+
msg = "Expecting parent to be RakeCommander::Options::Class. Given: #{pklass}"
|
17
|
+
raise ArgumentError, msg unless parent.is_a?(Class) && parent <= RakeCommander::Options
|
18
|
+
@parent = parent
|
19
|
+
@rules = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
return to_enum(:each) unless block_given?
|
24
|
+
@rules.values.each(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [EcoRake::Options::Forwarding::Proxy] with a copy of the rules.
|
28
|
+
def dup(parent, override: true, require_option: false)
|
29
|
+
self.class.new(parent).tap do |rely|
|
30
|
+
each {|rule| rely.add_rule(rule.deep_dup, override: override, require_option: require_option)}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
alias_method :deep_dup, :dup
|
34
|
+
|
35
|
+
# @return [EcoRake::Options::Forwarding::Rule]
|
36
|
+
def [](value)
|
37
|
+
@rules[key(value)]
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds a new rule or overrides an existing one.
|
41
|
+
# @see #add_rule
|
42
|
+
def add(sym, rule, override: true, require_option: true)
|
43
|
+
add_rule(
|
44
|
+
EcoRake::Options::Forwarding::Rule.new(key(sym) || sym, rule, parent: self),
|
45
|
+
override: override,
|
46
|
+
require_option: require_option
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param ref [Symbol, EcoRake::Options::Forwarding::Rule, EcoRake::Option]
|
51
|
+
# @return [EcoRake::Options::Forwarding::Rule] the rule that has been deleted.
|
52
|
+
def delete(ref)
|
53
|
+
@rules.delete(key(ref))
|
54
|
+
end
|
55
|
+
|
56
|
+
# It applies the rule associated with `sym` to `from` parsed option results.
|
57
|
+
# @param sym [Symbol] the `short` or `name` of an existing option.
|
58
|
+
# @param from [Hash] the parsed option results.
|
59
|
+
# @return [Value] the value that the rule returns.
|
60
|
+
def forward(sym, from:)
|
61
|
+
self[sym]&.apply(from)
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# @note
|
67
|
+
# 1. It fixes the `rule.sym` to the option `name`, if option exists.
|
68
|
+
# 2. By default, it does not require the target option to exist.
|
69
|
+
# 3. If `override`, it will warn on overriding, but if `false` it will just silently fail
|
70
|
+
# @raise ArgumentError if there isn't an option in `parent` with and `require_option` is `true`
|
71
|
+
# @raise ArgumentError if there `sym` has already a rule and `override` is `false`
|
72
|
+
# @param sym [Symbol] the `short` or `name` of an existing option.
|
73
|
+
# @param rule [String, Proc] the rule associated wtih `sym`.
|
74
|
+
# @param override [Boolean] whether overriding existing rule is allowed.
|
75
|
+
# @param require_option [Boolean] whether an option with `sym` as short or name must exist.
|
76
|
+
# @param warning [Boolean] whether an override should warn.
|
77
|
+
# @return [Boolean, EcoRake::Options::Forwarding::Rule] the added rule if succeeded, and `false` otherwise.
|
78
|
+
def add_rule(rule, override: true, require_option: false, warning: false)
|
79
|
+
msg = "Expecting EcoRake::Options::Forwarding::Rule. Given: #{rule.class}"
|
80
|
+
raise ArgumentError, msg unless rule.is_a?(EcoRake::Options::Forwarding::Rule)
|
81
|
+
|
82
|
+
msg = "Could not find any defined option associated with '#{rule.sym}'"
|
83
|
+
raise ArgumentError, msg unless (opt = option(rule.sym)) || !require_option
|
84
|
+
|
85
|
+
rule.sym = opt&.name
|
86
|
+
if existing_rule = self[rule.sym]
|
87
|
+
return false unless override
|
88
|
+
puts "Warning: Overriding forwarding '#{existing_rule.desc}'" if warning
|
89
|
+
end
|
90
|
+
|
91
|
+
rule.parent = self
|
92
|
+
@rules[rule.sym] = rule
|
93
|
+
end
|
94
|
+
|
95
|
+
# Retrieves the rule key
|
96
|
+
# 1. The option name of an existing option
|
97
|
+
# 2. The sym of an existing rule
|
98
|
+
# @return [Symbol]
|
99
|
+
def key(value)
|
100
|
+
case value
|
101
|
+
when RakeCommander::Option
|
102
|
+
value.name
|
103
|
+
when Symbol
|
104
|
+
if opt = option(value)
|
105
|
+
key(opt)
|
106
|
+
elsif @rules.key?(value)
|
107
|
+
value
|
108
|
+
end
|
109
|
+
when String
|
110
|
+
key(value.to_sym)
|
111
|
+
when EcoRake::Options::Forwarding::Rule
|
112
|
+
key(value.sym)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# Retrieves the option associated to a symbol
|
119
|
+
def option(sym)
|
120
|
+
parent.option_get(sym.to_sym)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
module Forwarding
|
4
|
+
class Rule
|
5
|
+
extend EcoRake::Base::MethodHelpers
|
6
|
+
|
7
|
+
RULE_TYPES = [String, Symbol, Proc].freeze
|
8
|
+
SYMBOL_TYPES = [:mirror].freeze
|
9
|
+
|
10
|
+
attr_accessor :parent, :sym
|
11
|
+
attr_reader :rule
|
12
|
+
|
13
|
+
# @param rule [String, Proc]
|
14
|
+
# - `Proc` -> [value, ]
|
15
|
+
def initialize(sym, rule, parent: nil)
|
16
|
+
msg = "Rule should be either of: #{RULE_TYPES.join(', ')}. Given: #{rule.class}"
|
17
|
+
raise ArgumentError, msg unless RULE_TYPES.any? {|type| rule.is_a?(type)}
|
18
|
+
msg = "Accepted Symbol rules are: :#{SYMBOL_TYPES.join(', :')}. Given :#{rule}"
|
19
|
+
raise ArgumentError, msg if rule.is_a?(Symbol) && SYMBOL_TYPES.none? {|type| rule == type}
|
20
|
+
@parent = parent
|
21
|
+
@sym = sym
|
22
|
+
@rule = rule
|
23
|
+
end
|
24
|
+
|
25
|
+
def active?(option_results)
|
26
|
+
opt = option
|
27
|
+
[opt&.name, opt&.short, sym].compact.any? {|k| option_results.key?(k)}
|
28
|
+
end
|
29
|
+
|
30
|
+
def results_value(option_results)
|
31
|
+
opt = option
|
32
|
+
value = nil
|
33
|
+
value = option_results[opt.name] if opt && value.nil?
|
34
|
+
value = option_results[opt.short] if opt && value.nil?
|
35
|
+
value = option_results[sym] if value.nil?
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
# @note
|
40
|
+
# 1. Retrives value from parsed options results by using the option name, short or sym.
|
41
|
+
# 2. It then applies the rule on it.
|
42
|
+
# @param option_results [Hash] the parsed option results.
|
43
|
+
# @return [NilClass, Value] the value that the rule returns, `nil` if rule inactive/not-applicable.
|
44
|
+
def apply(option_results)
|
45
|
+
return nil unless active?(option_results)
|
46
|
+
opt = option
|
47
|
+
return nil unless opt || rule != :mirror
|
48
|
+
|
49
|
+
value = results_value(option_results)
|
50
|
+
return rule if value && rule.is_a?(String)
|
51
|
+
return nil if rule.is_a?(String)
|
52
|
+
return opt.mirror(value) if rule == :mirror
|
53
|
+
|
54
|
+
self.class.safe_call(rule, value, option_results, opt)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Does a copy of this rule.
|
58
|
+
# @return [EcoRake::Options::Forwarding::Rule]
|
59
|
+
def dup(parent: nil)
|
60
|
+
new_rule = rule.respond_to?(:deep_dup)? rule.deep_dup : rule.dup
|
61
|
+
self.class.new(sym, new_rule, parent: parent)
|
62
|
+
end
|
63
|
+
alias_method :deep_dup, :dup
|
64
|
+
|
65
|
+
def desc
|
66
|
+
ref = (opt_ref = option_ref) ? opt_ref : "on #{sym} (no associated option)"
|
67
|
+
"rule #{ref}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Reference of the associated option.
|
71
|
+
def option_ref
|
72
|
+
(opt = option) ? "on option '#{opt.name}' (#{opt.short})" : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [EcoRake::Option] the option associated with `sym` name.
|
76
|
+
def option
|
77
|
+
parent&.send(:option, sym)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'forwarding/rule'
|
2
|
+
require_relative 'forwarding/proxy'
|
3
|
+
|
4
|
+
class EcoRake
|
5
|
+
module Options
|
6
|
+
# Offers a way to relaunch command options from options results.
|
7
|
+
module Forwarding
|
8
|
+
class << self
|
9
|
+
def included(base)
|
10
|
+
super(base)
|
11
|
+
base.extend ClassMethods
|
12
|
+
base.attr_inheritable(:options_proxy) {|value, subclass| value&.deep_dup(subclass)}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
# Service class to forward options.
|
18
|
+
def options_proxy
|
19
|
+
@options_proxy ||= EcoRake::Options::Forwarding::Proxy.new(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Declare the forwarding rules for options.
|
23
|
+
# @param rules [Hash] where keys are option names or shorts and values the rules.
|
24
|
+
def option_forwarding(**rules)
|
25
|
+
rules.each do |sym, rule|
|
26
|
+
options_proxy.add(sym, rule, override: true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param sym [Symbol] a short or name of an option that may be present in `from`
|
32
|
+
# @param from [Hash] the parsed option results.
|
33
|
+
# @return [Value] the value defined by the `rule` linked to `opt`
|
34
|
+
def forward_option(sym, from: options)
|
35
|
+
self.class.options_proxy.forward(sym, from: from)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @see `#forward_option` (the same but for multiple options)
|
39
|
+
# @return [Array<Value>] the values defined by the `rules` linked to `opts`
|
40
|
+
def forward_options(*syms, from: options)
|
41
|
+
syms.map {|sym| forward_option(sym, from: from)}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
# Gathers all the option presets (`EcoRake::Options::Set`) defined.
|
4
|
+
# It works at class level and does lazy loading.
|
5
|
+
class Library
|
6
|
+
extend RakeCommander::Base::ClassHelpers
|
7
|
+
extend RakeCommander::Base::ClassAutoLoader
|
8
|
+
|
9
|
+
class_resolver :item_class, EcoRake::Options::Set
|
10
|
+
|
11
|
+
autoloads_children_of :item_class
|
12
|
+
autoload_namespace_ignore "EcoRake::Options"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
include Enumerable
|
16
|
+
|
17
|
+
# Iterator
|
18
|
+
def each(&block)
|
19
|
+
return to_enum(:each) unless block_given?
|
20
|
+
sets.values.each(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Retrieve an options set
|
24
|
+
# @return [EcoRake::Options::Set] the class with that `name`
|
25
|
+
def [](value)
|
26
|
+
sets[to_name(value)]
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Boolean]
|
30
|
+
def set?(name)
|
31
|
+
raise "Expected String or Symbol. Given: #{name.class}" unless name.respond_to?(:to_sym)
|
32
|
+
sets.key?(name.to_sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Array<Symbol>] names list of all available option sets.
|
36
|
+
def names
|
37
|
+
setes.keys
|
38
|
+
end
|
39
|
+
|
40
|
+
# Add a new options set.
|
41
|
+
# @note
|
42
|
+
# 1. If it receives an `item_class` (`Class`) it just adds it in
|
43
|
+
# 2. If it receives an object instance, it adds its class
|
44
|
+
# @return [EcoRake::Options::Set] the class
|
45
|
+
def add(options_set)
|
46
|
+
klass = options_set.is_a?(Class)? options_set : options_set.class
|
47
|
+
raise "Expecting #{item_class} child or instance. Given: #{klass}" unless klass <= item_class
|
48
|
+
puts "Warning: redefining options set '#{set.name}'" if self[options_set.name]
|
49
|
+
sets[options_set.name] = klass
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def autoload_children
|
55
|
+
super(self) do |instance|
|
56
|
+
add(instance)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# It loads pending children of `item_class` every time it's invoked.
|
61
|
+
# @note if sets is used as unique access point, this should ensure all children are known/loaded.
|
62
|
+
# @return [Hash] where `key` is option_set name and value is the `item_class` (i.e. EcoRake::Options::Set)
|
63
|
+
def sets
|
64
|
+
autoload_children
|
65
|
+
@sets ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
# To-name converter
|
69
|
+
# @return [Symbol, NilClass]
|
70
|
+
def to_name(value)
|
71
|
+
case value
|
72
|
+
when String, Symbol
|
73
|
+
value.to_sym
|
74
|
+
when item_class
|
75
|
+
value.name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
module Parental
|
4
|
+
class << self
|
5
|
+
def included(base)
|
6
|
+
super(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
private
|
13
|
+
|
14
|
+
def add_to_options(opt, *args)
|
15
|
+
super.tap do |out|
|
16
|
+
next unless opt.respond_to?(:parent=)
|
17
|
+
opt.parent = self if opt == out
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete_from_options(opt)
|
22
|
+
super.tap do |out|
|
23
|
+
next unless opt.respond_to?(:parent=)
|
24
|
+
out.parent = nil if opt == out
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def replace_in_options(ref, opt, **kargs)
|
29
|
+
super.tap do |out|
|
30
|
+
next unless opt.respond_to?(:parent=)
|
31
|
+
ref.parent = nil if opt == out
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Options
|
3
|
+
class Set < RakeCommander::Options::Set
|
4
|
+
include EcoRake::Options
|
5
|
+
|
6
|
+
#banner ''
|
7
|
+
attr_reader :parent
|
8
|
+
|
9
|
+
def initialize(*args, _parent: nil)
|
10
|
+
@parent = _parent
|
11
|
+
super(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
self.class.name.tap do |nm|
|
16
|
+
raise ArgumentError, "Class #{self.class}, should have a name defined" unless nm
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'options/forwarding'
|
2
|
+
require_relative 'options/parental'
|
3
|
+
require_relative 'options/default_lookup'
|
4
|
+
|
5
|
+
class EcoRake
|
6
|
+
module Options
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
super(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
base.class_resolver :option_class, EcoRake::Option
|
12
|
+
base.send :include, EcoRake::Options::Parental
|
13
|
+
base.send :include, EcoRake::Options::Forwarding
|
14
|
+
base.send :include, EcoRake::Options::DefaultLookup
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require_relative 'options/set'
|
25
|
+
require_relative 'options/library'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class EcoRake
|
2
|
+
module Shell
|
3
|
+
module Command
|
4
|
+
include Rake::DSL
|
5
|
+
|
6
|
+
# It double quotes a string (escapes the double quotes)
|
7
|
+
# @param str [String]
|
8
|
+
# @return [String]
|
9
|
+
def double_quote(str)
|
10
|
+
"\"#{str}\"" if str
|
11
|
+
end
|
12
|
+
|
13
|
+
# Helper to build command line
|
14
|
+
# @note it excludes `nil` values.
|
15
|
+
# @return [String, Array<String>]
|
16
|
+
def array_cmd(base, *opts)
|
17
|
+
base = [base] unless base.is_a?(Array)
|
18
|
+
base.tap do |out|
|
19
|
+
opts.each {|opt| out << opt unless opt.nil?}
|
20
|
+
yield(out) if block_given?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @see #array_cmd it the same but it returns a `String`
|
25
|
+
# @return [String]
|
26
|
+
def string_cmd(base, *options, join: ' ')
|
27
|
+
array_cmd(base, *options).join(join)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param continue [Boolean] whether it should continue when one failed.
|
31
|
+
# @param arr [Array<String>] array of commands to be run
|
32
|
+
def sh_chain(cmds, continue: false, &block)
|
33
|
+
cmds.each do |cmd|
|
34
|
+
next sh(cmd, &block) unless continue
|
35
|
+
ch_continue(cmd, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# It **continues** even if there was an error or `exit(1)` during the execution
|
40
|
+
# @param comm [String] the command line
|
41
|
+
def sh_continue(comm, &block)
|
42
|
+
sh(comm, &sh_default_block(comm, &block))
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the default block for `sh` native method.
|
46
|
+
# @note it wraps `block` if given
|
47
|
+
# @return [Proc]
|
48
|
+
def sh_default_block(comm)
|
49
|
+
proc do |ok, res|
|
50
|
+
yield(ok, res) if block_given?
|
51
|
+
unless ok
|
52
|
+
msg = "Command failed (status = #{res.exitstatus})"
|
53
|
+
puts "#{msg}\n • #{comm}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|