eco-rake 0.1.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/.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
|