dk 0.0.1 → 0.1.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 +5 -5
- data/README.md +643 -1
- data/bin/dk +7 -0
- data/dk.gemspec +7 -3
- data/lib/dk/ansi.rb +98 -0
- data/lib/dk/cli.rb +173 -0
- data/lib/dk/config.rb +217 -0
- data/lib/dk/config_runner.rb +24 -0
- data/lib/dk/dk_runner.rb +13 -0
- data/lib/dk/dry_runner.rb +43 -0
- data/lib/dk/has_set_param.rb +42 -0
- data/lib/dk/has_ssh_opts.rb +36 -0
- data/lib/dk/has_the_runs.rb +23 -0
- data/lib/dk/has_the_stubs.rb +116 -0
- data/lib/dk/local.rb +84 -0
- data/lib/dk/null_logger.rb +13 -0
- data/lib/dk/remote.rb +132 -0
- data/lib/dk/runner.rb +202 -0
- data/lib/dk/task.rb +266 -0
- data/lib/dk/task_run.rb +17 -0
- data/lib/dk/test_runner.rb +54 -0
- data/lib/dk/tree_runner.rb +64 -0
- data/lib/dk/version.rb +1 -1
- data/lib/dk.rb +23 -1
- data/test/helper.rb +6 -1
- data/test/support/config/dk.rb +7 -0
- data/test/support/config/task_defs.rb +10 -0
- data/test/support/factory.rb +38 -0
- data/test/support/log/.gitkeep +0 -0
- data/test/system/has_the_stubs_tests.rb +355 -0
- data/test/system/runner_tests.rb +222 -0
- data/test/unit/ansi_tests.rb +40 -0
- data/test/unit/cli_tests.rb +317 -0
- data/test/unit/config_runner_tests.rb +60 -0
- data/test/unit/config_tests.rb +427 -0
- data/test/unit/dk_runner_tests.rb +34 -0
- data/test/unit/dk_tests.rb +49 -0
- data/test/unit/dry_runner_tests.rb +71 -0
- data/test/unit/has_set_param_tests.rb +46 -0
- data/test/unit/has_ssh_opts_tests.rb +81 -0
- data/test/unit/has_the_runs_tests.rb +37 -0
- data/test/unit/has_the_stubs_tests.rb +279 -0
- data/test/unit/local_tests.rb +174 -0
- data/test/unit/null_logger_tests.rb +17 -0
- data/test/unit/remote_tests.rb +330 -0
- data/test/unit/runner_tests.rb +398 -0
- data/test/unit/task_run_tests.rb +40 -0
- data/test/unit/task_tests.rb +943 -0
- data/test/unit/test_runner_tests.rb +189 -0
- data/test/unit/tree_runner_tests.rb +152 -0
- metadata +106 -9
data/lib/dk/ansi.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
module Dk
|
2
|
+
|
3
|
+
module Ansi
|
4
|
+
|
5
|
+
def self.styled_msg(msg, *styles)
|
6
|
+
code = self.code_for(*styles)
|
7
|
+
return msg if code.empty?
|
8
|
+
code + msg + self.code_for(:reset)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.code_for(*style_names)
|
12
|
+
style_names.map{ |n| "\e[#{CODES[n]}m" if CODES.key?(n) }.compact.join('')
|
13
|
+
end
|
14
|
+
|
15
|
+
# Table of supported styles/codes (http://en.wikipedia.org/wiki/ANSI_escape_code)
|
16
|
+
|
17
|
+
CODES = {
|
18
|
+
:clear => 0,
|
19
|
+
:reset => 0,
|
20
|
+
:bright => 1,
|
21
|
+
:bold => 1,
|
22
|
+
:faint => 2,
|
23
|
+
:dark => 2,
|
24
|
+
:italic => 3,
|
25
|
+
:underline => 4,
|
26
|
+
:underscore => 4,
|
27
|
+
:blink => 5,
|
28
|
+
:slow_blink => 5,
|
29
|
+
:rapid => 6,
|
30
|
+
:rapid_blink => 6,
|
31
|
+
:invert => 7,
|
32
|
+
:inverse => 7,
|
33
|
+
:reverse => 7,
|
34
|
+
:negative => 7,
|
35
|
+
:swap => 7,
|
36
|
+
:conceal => 8,
|
37
|
+
:concealed => 8,
|
38
|
+
:hide => 9,
|
39
|
+
:strike => 9,
|
40
|
+
|
41
|
+
:default_font => 10,
|
42
|
+
:font_default => 10,
|
43
|
+
:font0 => 10,
|
44
|
+
:font1 => 11,
|
45
|
+
:font2 => 12,
|
46
|
+
:font3 => 13,
|
47
|
+
:font4 => 14,
|
48
|
+
:font5 => 15,
|
49
|
+
:font6 => 16,
|
50
|
+
:font7 => 17,
|
51
|
+
:font8 => 18,
|
52
|
+
:font9 => 19,
|
53
|
+
:fraktur => 20,
|
54
|
+
:bright_off => 21,
|
55
|
+
:bold_off => 21,
|
56
|
+
:double_underline => 21,
|
57
|
+
:clean => 22,
|
58
|
+
:italic_off => 23,
|
59
|
+
:fraktur_off => 23,
|
60
|
+
:underline_off => 24,
|
61
|
+
:blink_off => 25,
|
62
|
+
:inverse_off => 26,
|
63
|
+
:positive => 26,
|
64
|
+
:conceal_off => 27,
|
65
|
+
:show => 27,
|
66
|
+
:reveal => 27,
|
67
|
+
:crossed_off => 29,
|
68
|
+
:crossed_out_off => 29,
|
69
|
+
|
70
|
+
:black => 30,
|
71
|
+
:red => 31,
|
72
|
+
:green => 32,
|
73
|
+
:yellow => 33,
|
74
|
+
:blue => 34,
|
75
|
+
:magenta => 35,
|
76
|
+
:cyan => 36,
|
77
|
+
:white => 37,
|
78
|
+
|
79
|
+
:on_black => 40,
|
80
|
+
:on_red => 41,
|
81
|
+
:on_green => 42,
|
82
|
+
:on_yellow => 43,
|
83
|
+
:on_blue => 44,
|
84
|
+
:on_magenta => 45,
|
85
|
+
:on_cyan => 46,
|
86
|
+
:on_white => 47,
|
87
|
+
|
88
|
+
:frame => 51,
|
89
|
+
:encircle => 52,
|
90
|
+
:overline => 53,
|
91
|
+
:frame_off => 54,
|
92
|
+
:encircle_off => 54,
|
93
|
+
:overline_off => 55,
|
94
|
+
}
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/lib/dk/cli.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'dk'
|
2
|
+
require 'dk/dk_runner'
|
3
|
+
require 'dk/dry_runner'
|
4
|
+
require 'dk/tree_runner'
|
5
|
+
require 'dk/version'
|
6
|
+
|
7
|
+
module Dk
|
8
|
+
|
9
|
+
class CLI
|
10
|
+
|
11
|
+
DEFAULT_CONFIG_PATH = 'config/dk.rb'.freeze
|
12
|
+
|
13
|
+
def self.run(args)
|
14
|
+
self.new.run(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :clirb
|
18
|
+
|
19
|
+
def initialize(kernel = nil)
|
20
|
+
@kernel = kernel || Kernel
|
21
|
+
|
22
|
+
load config_path
|
23
|
+
Dk.init
|
24
|
+
@config = Dk.config
|
25
|
+
|
26
|
+
@clirb = CLIRB.new do
|
27
|
+
option 'list-tasks', 'list all tasks available to run', {
|
28
|
+
:abbrev => 'T'
|
29
|
+
}
|
30
|
+
option 'dry-run', 'run the tasks without executing any local/remote cmds'
|
31
|
+
option 'tree', 'print out the tree of tasks/sub-tasks that would be run'
|
32
|
+
option 'verbose', 'run tasks showing verbose (ie debug log level) details'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def run(*args)
|
37
|
+
begin
|
38
|
+
run!(*args)
|
39
|
+
rescue ShowTaskList
|
40
|
+
@kernel.puts task_list
|
41
|
+
rescue CLIRB::HelpExit
|
42
|
+
@kernel.puts help
|
43
|
+
rescue CLIRB::VersionExit
|
44
|
+
@kernel.puts Dk::VERSION
|
45
|
+
rescue CLIRB::Error, Dk::Config::UnknownTaskError => exception
|
46
|
+
@kernel.puts help
|
47
|
+
@kernel.puts "\n\n#{exception.message}\n"
|
48
|
+
@kernel.exit 1
|
49
|
+
rescue Dk::NoticeError => exception
|
50
|
+
@kernel.puts "\n\n#{exception.message}\n\n"
|
51
|
+
@kernel.puts exception.backtrace.first
|
52
|
+
@kernel.exit 1
|
53
|
+
rescue StandardError => exception
|
54
|
+
@kernel.puts "\n\n#{exception.class}: #{exception.message}"
|
55
|
+
@kernel.puts exception.backtrace.join("\n")
|
56
|
+
@kernel.exit 1
|
57
|
+
end
|
58
|
+
@kernel.exit 0
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def run!(*args)
|
64
|
+
@clirb.parse!(args)
|
65
|
+
raise ShowTaskList if @clirb.opts['list-tasks']
|
66
|
+
|
67
|
+
@config.stdout_log_level('debug') if @clirb.opts['verbose']
|
68
|
+
|
69
|
+
unknowns = @clirb.args.select{ |name| !@config.tasks.keys.include?(name) }
|
70
|
+
if !unknowns.empty?
|
71
|
+
raise Dk::Config::UnknownTaskError, unknowns.map{ |u| "`#{u}`"}.join(', ')
|
72
|
+
end
|
73
|
+
|
74
|
+
runner = get_runner(@config, @clirb.opts)
|
75
|
+
runner.log_cli_run(args.join(' ')) do
|
76
|
+
@clirb.args.each do |task_name|
|
77
|
+
runner.log_cli_task_run(task_name) do
|
78
|
+
runner.run(@config.task(task_name))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def help
|
85
|
+
"Usage: dk [TASKS] [options]\n\n" \
|
86
|
+
"Tasks:\n" \
|
87
|
+
"#{task_list(' ')}\n\n" \
|
88
|
+
"Options: #{@clirb}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def task_list(prefix = '')
|
92
|
+
max_name_width = @config.tasks.keys.map(&:size).max
|
93
|
+
items = @config.tasks.map do |(name, task_class)|
|
94
|
+
"#{prefix}#{name.ljust(max_name_width)} # #{task_class.description}"
|
95
|
+
end
|
96
|
+
items.sort.join("\n")
|
97
|
+
end
|
98
|
+
|
99
|
+
def config_path
|
100
|
+
File.expand_path(ENV['DK_CONFIG'] || DEFAULT_CONFIG_PATH, ENV['PWD'])
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_runner(config, opts)
|
104
|
+
return Dk::DryRunner.new(config) if opts['dry-run']
|
105
|
+
|
106
|
+
if opts['tree']
|
107
|
+
@kernel.puts "building task tree#{'s' if @clirb.args.size > 1}..."
|
108
|
+
return Dk::TreeRunner.new(config, @kernel)
|
109
|
+
end
|
110
|
+
|
111
|
+
Dk::DkRunner.new(config)
|
112
|
+
end
|
113
|
+
|
114
|
+
ShowTaskList = Class.new(RuntimeError)
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
|
119
|
+
Error = Class.new(RuntimeError);
|
120
|
+
HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
|
121
|
+
attr_reader :argv, :args, :opts, :data
|
122
|
+
|
123
|
+
def initialize(&block)
|
124
|
+
@options = []; instance_eval(&block) if block
|
125
|
+
require 'optparse'
|
126
|
+
@data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
|
127
|
+
p.banner = ''; @options.each do |o|
|
128
|
+
@opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
|
129
|
+
end
|
130
|
+
p.on_tail('--version', ''){ |v| raise VersionExit, v.to_s }
|
131
|
+
p.on_tail('--help', ''){ |v| raise HelpExit, v.to_s }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def option(*args); @options << Option.new(*args); end
|
136
|
+
def parse!(argv)
|
137
|
+
@args = (argv || []).dup.tap do |args_list|
|
138
|
+
begin; @parser.parse!(args_list)
|
139
|
+
rescue OptionParser::ParseError => err; raise Error, err.message; end
|
140
|
+
end; @data = @args + [@opts]
|
141
|
+
end
|
142
|
+
def to_s; @parser.to_s; end
|
143
|
+
def inspect
|
144
|
+
"#<#{self.class}:#{'0x0%x' % (object_id << 1)} @data=#{@data.inspect}>"
|
145
|
+
end
|
146
|
+
|
147
|
+
class Option
|
148
|
+
attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
|
149
|
+
|
150
|
+
def initialize(name, *args)
|
151
|
+
settings, @desc = args.last.kind_of?(::Hash) ? args.pop : {}, args.pop || ''
|
152
|
+
@name, @opt_name, @abbrev = parse_name_values(name, settings[:abbrev])
|
153
|
+
@value, @klass = gvalinfo(settings[:value])
|
154
|
+
@parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
|
155
|
+
["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
|
156
|
+
else
|
157
|
+
["-#{@abbrev}", "--#{@opt_name} #{@opt_name.upcase}", @klass, @desc]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def parse_name_values(name, custom_abbrev)
|
164
|
+
[ (processed_name = name.to_s.strip.downcase), processed_name.gsub('_', '-'),
|
165
|
+
custom_abbrev || processed_name.gsub(/[^a-z]/, '').chars.first || 'a'
|
166
|
+
]
|
167
|
+
end
|
168
|
+
def gvalinfo(v); v.kind_of?(Class) ? [nil,gklass(v)] : [v,gklass(v.class)]; end
|
169
|
+
def gklass(k); k == Fixnum ? Integer : k; end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
data/lib/dk/config.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'logsly'
|
2
|
+
require 'dk/has_set_param'
|
3
|
+
require 'dk/has_ssh_opts'
|
4
|
+
require 'dk/task'
|
5
|
+
|
6
|
+
module Dk
|
7
|
+
|
8
|
+
class Config
|
9
|
+
include Dk::HasSetParam
|
10
|
+
include Dk::HasSSHOpts
|
11
|
+
|
12
|
+
UnknownTaskError = Class.new(ArgumentError) do
|
13
|
+
def initialize(task_name)
|
14
|
+
super("No task named #{task_name}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
DEFAULT_INIT_PROCS = [].freeze
|
19
|
+
DEFAULT_PARAMS = {}.freeze
|
20
|
+
DEFAULT_CALLBACKS = Hash.new{ |h, k| h[k] = Dk::Task::CallbackSet.new }.freeze
|
21
|
+
DEFAULT_SSH_HOSTS = {}.freeze
|
22
|
+
DEFAULT_SSH_ARGS = ''.freeze
|
23
|
+
DEFAULT_HOST_SSH_ARGS = Hash.new{ |h, k| h[k] = DEFAULT_SSH_ARGS }
|
24
|
+
DEFAULT_TASKS = Hash.new{ |h, k| raise UnknownTaskError.new("`#{k}`") }.freeze
|
25
|
+
DEFAULT_LOG_PATTERN = "%m\n".freeze
|
26
|
+
DEFAULT_LOG_FILE_PATTERN = '[%d %-5l] : %m\n'.freeze
|
27
|
+
DEFAULT_STDOUT_LOG_LEVEL = 'info'.freeze
|
28
|
+
DEFAULT_STUBS = [].freeze
|
29
|
+
FILE_LOG_LEVEL = 'debug'.freeze
|
30
|
+
|
31
|
+
attr_reader :init_procs, :params
|
32
|
+
attr_reader :before_callbacks, :prepend_before_callbacks
|
33
|
+
attr_reader :after_callbacks, :prepend_after_callbacks
|
34
|
+
attr_reader :tasks, :dry_tree_cmd_stubs, :dry_tree_ssh_stubs
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@init_procs = DEFAULT_INIT_PROCS.dup
|
38
|
+
@params = DEFAULT_PARAMS.dup
|
39
|
+
@before_callbacks = DEFAULT_CALLBACKS.dup
|
40
|
+
@prepend_before_callbacks = DEFAULT_CALLBACKS.dup
|
41
|
+
@after_callbacks = DEFAULT_CALLBACKS.dup
|
42
|
+
@prepend_after_callbacks = DEFAULT_CALLBACKS.dup
|
43
|
+
@ssh_hosts = DEFAULT_SSH_HOSTS.dup
|
44
|
+
@ssh_args = DEFAULT_SSH_ARGS.dup
|
45
|
+
@host_ssh_args = DEFAULT_HOST_SSH_ARGS.dup
|
46
|
+
@tasks = DEFAULT_TASKS.dup
|
47
|
+
@stdout_log_level = DEFAULT_STDOUT_LOG_LEVEL
|
48
|
+
@log_pattern = DEFAULT_LOG_PATTERN
|
49
|
+
@log_file = nil
|
50
|
+
@log_file_pattern = DEFAULT_LOG_FILE_PATTERN
|
51
|
+
@dry_tree_cmd_stubs = DEFAULT_STUBS.dup
|
52
|
+
@dry_tree_ssh_stubs = DEFAULT_STUBS.dup
|
53
|
+
end
|
54
|
+
|
55
|
+
def init
|
56
|
+
self.init_procs.each{ |block| self.instance_eval(&block) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_param(key, value)
|
60
|
+
self.params.merge!(dk_normalize_params(key => value))
|
61
|
+
end
|
62
|
+
|
63
|
+
def before(subject_task_class, callback_task_class, params = nil)
|
64
|
+
self.before_callbacks[subject_task_class] << Task::Callback.new(
|
65
|
+
callback_task_class,
|
66
|
+
params
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def prepend_before(subject_task_class, callback_task_class, params = nil)
|
71
|
+
self.prepend_before_callbacks[subject_task_class].unshift(Task::Callback.new(
|
72
|
+
callback_task_class,
|
73
|
+
params
|
74
|
+
))
|
75
|
+
end
|
76
|
+
|
77
|
+
def after(subject_task_class, callback_task_class, params = nil)
|
78
|
+
self.after_callbacks[subject_task_class] << Task::Callback.new(
|
79
|
+
callback_task_class,
|
80
|
+
params
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def prepend_after(subject_task_class, callback_task_class, params = nil)
|
85
|
+
self.prepend_after_callbacks[subject_task_class].unshift(Task::Callback.new(
|
86
|
+
callback_task_class,
|
87
|
+
params
|
88
|
+
))
|
89
|
+
end
|
90
|
+
|
91
|
+
def before_callback_task_classes(for_task_class)
|
92
|
+
self.before_callbacks[for_task_class].map(&:task_class)
|
93
|
+
end
|
94
|
+
|
95
|
+
def prepend_before_callback_task_classes(for_task_class)
|
96
|
+
self.prepend_before_callbacks[for_task_class].map(&:task_class)
|
97
|
+
end
|
98
|
+
|
99
|
+
def after_callback_task_classes(for_task_class)
|
100
|
+
self.after_callbacks[for_task_class].map(&:task_class)
|
101
|
+
end
|
102
|
+
|
103
|
+
def prepend_after_callback_task_classes(for_task_class)
|
104
|
+
self.prepend_after_callbacks[for_task_class].map(&:task_class)
|
105
|
+
end
|
106
|
+
|
107
|
+
def task(name, task_class = nil)
|
108
|
+
if !task_class.nil?
|
109
|
+
if !task_class.kind_of?(Class) || !task_class.include?(Dk::Task)
|
110
|
+
raise ArgumentError, "#{task_class.inspect} is not a Dk::Task"
|
111
|
+
end
|
112
|
+
@tasks[name.to_s] = task_class
|
113
|
+
end
|
114
|
+
@tasks[name.to_s]
|
115
|
+
end
|
116
|
+
|
117
|
+
def stdout_log_level(value = nil)
|
118
|
+
@stdout_log_level = value if !value.nil?
|
119
|
+
@stdout_log_level
|
120
|
+
end
|
121
|
+
|
122
|
+
def log_pattern(value = nil)
|
123
|
+
@log_pattern = value if !value.nil?
|
124
|
+
@log_pattern
|
125
|
+
end
|
126
|
+
|
127
|
+
def log_file(value = nil)
|
128
|
+
@log_file = value if !value.nil?
|
129
|
+
@log_file
|
130
|
+
end
|
131
|
+
|
132
|
+
def log_file_pattern(value = nil)
|
133
|
+
@log_file_pattern = value if !value.nil?
|
134
|
+
@log_file_pattern
|
135
|
+
end
|
136
|
+
|
137
|
+
def stub_dry_tree_cmd(cmd_str, args = nil, &block)
|
138
|
+
args ||= {}
|
139
|
+
|
140
|
+
cmd_str_proc = get_cmd_ssh_proc(cmd_str)
|
141
|
+
input_proc = get_cmd_ssh_proc(args[:input])
|
142
|
+
given_opts_proc = get_cmd_ssh_proc(args[:opts])
|
143
|
+
|
144
|
+
@dry_tree_cmd_stubs.unshift(
|
145
|
+
DryTreeStub.new(cmd_str_proc, input_proc, given_opts_proc, block)
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
def stub_dry_tree_ssh(cmd_str, args = nil, &block)
|
150
|
+
args ||= {}
|
151
|
+
|
152
|
+
cmd_str_proc = get_cmd_ssh_proc(cmd_str)
|
153
|
+
input_proc = get_cmd_ssh_proc(args[:input])
|
154
|
+
given_opts_proc = get_cmd_ssh_proc(args[:opts])
|
155
|
+
|
156
|
+
@dry_tree_ssh_stubs.unshift(
|
157
|
+
DryTreeStub.new(cmd_str_proc, input_proc, given_opts_proc, block)
|
158
|
+
)
|
159
|
+
end
|
160
|
+
|
161
|
+
# private - intended for internal use only
|
162
|
+
|
163
|
+
def dk_logger_stdout_output_name
|
164
|
+
# include the object id to ensure the output is unique to the instance
|
165
|
+
@dk_logger_stdout_output_name ||= "dk-config-#{self.object_id}-stdout"
|
166
|
+
end
|
167
|
+
|
168
|
+
def dk_logger_file_output_name
|
169
|
+
# include the object id to ensure the output is unique to the instance
|
170
|
+
@dk_logger_file_output_name ||= "dk-config-#{self.object_id}-file"
|
171
|
+
end
|
172
|
+
|
173
|
+
def dk_logger
|
174
|
+
@dk_logger ||= LogslyLogger.new(self)
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
def get_cmd_ssh_proc(obj)
|
180
|
+
obj.kind_of?(::Proc) ? obj : proc{ obj }
|
181
|
+
end
|
182
|
+
|
183
|
+
DryTreeStub = Struct.new(:cmd_str_proc, :input_proc, :given_opts_proc, :block)
|
184
|
+
|
185
|
+
class LogslyLogger
|
186
|
+
include Logsly
|
187
|
+
|
188
|
+
LOG_TYPE = 'dk'.freeze
|
189
|
+
|
190
|
+
attr_reader :config
|
191
|
+
|
192
|
+
def initialize(config)
|
193
|
+
@config = config # set the reader first so it can be used when supering
|
194
|
+
|
195
|
+
Logsly.stdout(@config.dk_logger_stdout_output_name) do |logger|
|
196
|
+
level logger.config.stdout_log_level
|
197
|
+
pattern logger.config.log_pattern
|
198
|
+
end
|
199
|
+
outputs = [@config.dk_logger_stdout_output_name]
|
200
|
+
|
201
|
+
if @config.log_file
|
202
|
+
Logsly.file(@config.dk_logger_file_output_name) do |logger|
|
203
|
+
path File.expand_path(logger.config.log_file, ENV['PWD'])
|
204
|
+
level Dk::Config::FILE_LOG_LEVEL
|
205
|
+
pattern logger.config.log_file_pattern
|
206
|
+
end
|
207
|
+
outputs << @config.dk_logger_file_output_name
|
208
|
+
end
|
209
|
+
|
210
|
+
super(LOG_TYPE, :outputs => outputs)
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'dk/runner'
|
2
|
+
|
3
|
+
module Dk
|
4
|
+
|
5
|
+
class ConfigRunner < Runner
|
6
|
+
|
7
|
+
def initialize(config, opts = nil)
|
8
|
+
opts ||= {}
|
9
|
+
super({
|
10
|
+
:params => config.params,
|
11
|
+
:before_callbacks => config.before_callbacks,
|
12
|
+
:prepend_before_callbacks => config.prepend_before_callbacks,
|
13
|
+
:after_callbacks => config.after_callbacks,
|
14
|
+
:prepend_after_callbacks => config.prepend_after_callbacks,
|
15
|
+
:ssh_hosts => config.ssh_hosts,
|
16
|
+
:ssh_args => config.ssh_args,
|
17
|
+
:host_ssh_args => config.host_ssh_args,
|
18
|
+
:logger => opts[:logger] || config.dk_logger
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/dk/dk_runner.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'dk/config_runner'
|
2
|
+
require 'dk/has_the_stubs'
|
3
|
+
|
4
|
+
module Dk
|
5
|
+
|
6
|
+
class DryRunner < ConfigRunner
|
7
|
+
include HasTheStubs
|
8
|
+
|
9
|
+
# run with disabled cmds, just log actions, but run all sub-tasks
|
10
|
+
|
11
|
+
def initialize(config, *args)
|
12
|
+
super(config, *args)
|
13
|
+
config.dry_tree_cmd_stubs.each do |s|
|
14
|
+
self.stub_cmd(s.cmd_str_proc, {
|
15
|
+
:input => s.input_proc,
|
16
|
+
:opts => s.given_opts_proc
|
17
|
+
}, &s.block)
|
18
|
+
end
|
19
|
+
config.dry_tree_ssh_stubs.each do |s|
|
20
|
+
self.stub_ssh(s.cmd_str_proc, {
|
21
|
+
:input => s.input_proc,
|
22
|
+
:opts => s.given_opts_proc
|
23
|
+
}, &s.block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def has_the_stubs_build_local_cmd(cmd_str, given_opts)
|
30
|
+
given_opts ||= {}
|
31
|
+
cmd_klass = given_opts[:dry_tree_run] ? Local::Cmd : Local::CmdSpy
|
32
|
+
cmd_klass.new(cmd_str, given_opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_the_stubs_build_remote_cmd(cmd_str, ssh_opts)
|
36
|
+
ssh_opts ||= {}
|
37
|
+
cmd_klass = ssh_opts[:dry_tree_run] ? Remote::Cmd : Remote::CmdSpy
|
38
|
+
cmd_klass.new(cmd_str, ssh_opts)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
|
3
|
+
module Dk
|
4
|
+
|
5
|
+
module HasSetParam
|
6
|
+
include MuchPlugin
|
7
|
+
|
8
|
+
plugin_included do
|
9
|
+
include InstanceMethods
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
|
15
|
+
def set_param(key, value)
|
16
|
+
self.params.merge!(dk_normalize_params(key => value))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def dk_normalize_params(params)
|
22
|
+
StringifyParams.new(params || {})
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
module StringifyParams
|
28
|
+
def self.new(object)
|
29
|
+
case(object)
|
30
|
+
when ::Hash
|
31
|
+
object.inject({}){ |h, (k, v)| h.merge(k.to_s => self.new(v)) }
|
32
|
+
when ::Array
|
33
|
+
object.map{ |item| self.new(item) }
|
34
|
+
else
|
35
|
+
object
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
|
3
|
+
module Dk
|
4
|
+
|
5
|
+
module HasSSHOpts
|
6
|
+
include MuchPlugin
|
7
|
+
|
8
|
+
plugin_included do
|
9
|
+
include InstanceMethods
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
|
15
|
+
def ssh_hosts(group_name = nil, *values)
|
16
|
+
return @ssh_hosts if group_name.nil?
|
17
|
+
@ssh_hosts[group_name.to_s] = values.flatten if !values.empty?
|
18
|
+
@ssh_hosts[group_name.to_s]
|
19
|
+
end
|
20
|
+
|
21
|
+
def ssh_args(value = nil)
|
22
|
+
@ssh_args = value if !value.nil?
|
23
|
+
@ssh_args
|
24
|
+
end
|
25
|
+
|
26
|
+
def host_ssh_args(host_name = nil, value = nil)
|
27
|
+
return @host_ssh_args if host_name.nil?
|
28
|
+
@host_ssh_args[host_name.to_s] = value if !value.nil?
|
29
|
+
@host_ssh_args[host_name.to_s]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|