teuton 2.8.0 → 2.9.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 +4 -4
- data/README.md +4 -4
- data/docs/changelog/changelog.1.md +119 -0
- data/docs/changelog/changelog.2.md +109 -0
- data/docs/diagram.md +10 -10
- data/docs/dsl/expect.md +76 -25
- data/docs/dsl/result.md +24 -30
- data/docs/learn/02-target.md +32 -27
- data/docs/learn/25-expect-result.md +39 -0
- data/docs/learn/26-expect_sequence.md +79 -0
- data/docs/learn/27-run_script.md +91 -0
- data/docs/learn/28-upload.md +55 -0
- data/docs/learn/README.md +4 -15
- data/docs/videos.md +14 -8
- data/lib/teuton/case/case.rb +3 -2
- data/lib/teuton/case/config.rb +0 -5
- data/lib/teuton/case/dsl/all.rb +5 -1
- data/lib/teuton/case/dsl/expect.rb +13 -42
- data/lib/teuton/case/dsl/expect_exitcode.rb +31 -0
- data/lib/teuton/case/dsl/expect_sequence.rb +173 -0
- data/lib/teuton/case/dsl/getset.rb +0 -1
- data/lib/teuton/case/dsl/host.rb +5 -0
- data/lib/teuton/case/dsl/macro.rb +7 -3
- data/lib/teuton/case/dsl/run_script.rb +35 -0
- data/lib/teuton/case/dsl/upload.rb +42 -0
- data/lib/teuton/case/dsl/weight.rb +12 -0
- data/lib/teuton/case/host.rb +68 -0
- data/lib/teuton/case/play.rb +2 -6
- data/lib/teuton/{utils → case}/result/ext_array.rb +0 -1
- data/lib/teuton/{utils → case}/result/ext_compare.rb +0 -1
- data/lib/teuton/{utils → case}/result/ext_filter.rb +0 -2
- data/lib/teuton/{utils → case}/result/result.rb +13 -21
- data/lib/teuton/check/checker.rb +82 -0
- data/lib/teuton/check/dsl/all.rb +37 -0
- data/lib/teuton/check/{builtin.rb → dsl/builtin.rb} +1 -3
- data/lib/teuton/check/dsl/expect.rb +90 -0
- data/lib/teuton/check/dsl/expect_sequence.rb +29 -0
- data/lib/teuton/check/dsl/getset.rb +23 -0
- data/lib/teuton/check/dsl/run.rb +35 -0
- data/lib/teuton/check/main.rb +29 -0
- data/lib/teuton/check/show.rb +75 -100
- data/lib/teuton/deprecated/application_test.rb +32 -0
- data/lib/teuton/readme/dsl/all.rb +32 -0
- data/lib/teuton/readme/dsl/expect.rb +29 -0
- data/lib/teuton/readme/dsl/getset.rb +33 -0
- data/lib/teuton/readme/dsl/run.rb +51 -0
- data/lib/teuton/readme/lang.rb +8 -10
- data/lib/teuton/readme/main.rb +27 -0
- data/lib/teuton/readme/readme.rb +31 -58
- data/lib/teuton/readme/result.rb +7 -0
- data/lib/teuton/utils/configfile_reader.rb +25 -10
- data/lib/teuton/utils/logger.rb +32 -0
- data/lib/teuton/utils/verbose.rb +1 -1
- data/lib/teuton/version.rb +1 -1
- data/lib/teuton.rb +6 -5
- metadata +45 -39
- data/docs/CHANGELOG.md +0 -10
- data/docs/changelog/v2.0.md +0 -18
- data/docs/changelog/v2.1.md +0 -54
- data/docs/changelog/v2.2.md +0 -42
- data/docs/changelog/v2.3.md +0 -10
- data/docs/changelog/v2.4.md +0 -41
- data/docs/changelog/v2.5.md +0 -6
- data/docs/changelog/v2.6.md +0 -4
- data/docs/changelog/v2.7.md +0 -23
- data/docs/changelog/v2.8.md +0 -11
- data/docs/changelog/version2.1.md +0 -4
- data/docs/learn/videos.md +0 -13
- data/lib/teuton/case/execute/copy_ssh.rb +0 -70
- data/lib/teuton/check/dsl.rb +0 -112
- data/lib/teuton/check/laboratory.rb +0 -59
- data/lib/teuton/readme/dsl.rb +0 -126
- /data/lib/teuton/case/dsl/{goto.rb → run.rb} +0 -0
- /data/lib/teuton/{utils → deprecated}/application.rb +0 -0
- /data/lib/teuton/{case/deprecated → deprecated}/runner.rb +0 -0
- /data/lib/teuton/{case/deprecated → deprecated}/utils.rb +0 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative "../../utils/project"
|
2
|
+
require_relative "../../utils/verbose"
|
3
|
+
|
4
|
+
module DSL
|
5
|
+
def upload(localfilter, args = {})
|
6
|
+
abslocalfilter = if File.absolute_path? localfilter
|
7
|
+
localfilter
|
8
|
+
else
|
9
|
+
File.join(Project.value[:project_path], localfilter)
|
10
|
+
end
|
11
|
+
|
12
|
+
Dir.glob(abslocalfilter).each do |abslocalpath|
|
13
|
+
upload_one(abslocalpath, args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def upload_one(localpath, args = {})
|
18
|
+
if args[:to].nil?
|
19
|
+
Logger.err("ERROR upload requires to: XXX")
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
23
|
+
host = get_host(args[:to])
|
24
|
+
if host.protocol == "ssh"
|
25
|
+
begin
|
26
|
+
localfile = File.basename(localpath)
|
27
|
+
remotepath = args[:remotedir] ? File.join(args[:remotedir], localfile) : localfile
|
28
|
+
Net::SFTP.start(
|
29
|
+
host.ip, host.username, password: host.password, port: host.port
|
30
|
+
) { |sftp| sftp.upload!(localpath, remotepath) }
|
31
|
+
verbose(Rainbow("u").green)
|
32
|
+
rescue => e
|
33
|
+
log("Upload #{localfile} to #{host.ip}:#{remotepath}", :warn)
|
34
|
+
log(e.to_s, :warn)
|
35
|
+
verbose(Rainbow("!").green)
|
36
|
+
end
|
37
|
+
elsif host.protocol != "local"
|
38
|
+
msg = Rainbow("==> [ERROR] upload: Incorrect protocol(#{host.protocol})").red
|
39
|
+
verboseln(msg)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class Case
|
2
|
+
class Host
|
3
|
+
attr_reader :id
|
4
|
+
attr_reader :ip
|
5
|
+
attr_reader :username
|
6
|
+
attr_reader :password
|
7
|
+
attr_reader :port
|
8
|
+
attr_reader :protocol
|
9
|
+
attr_reader :route
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
def get(id = nil)
|
16
|
+
if id.nil?
|
17
|
+
init_default
|
18
|
+
else
|
19
|
+
init(id)
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
data = {
|
26
|
+
id: id,
|
27
|
+
ip: ip, username: username, password: password,
|
28
|
+
port: port, protocol: protocol, route: route
|
29
|
+
}
|
30
|
+
data.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def init(id)
|
36
|
+
@id = id.to_sym
|
37
|
+
@ip = @config.get("#{@id}_ip".to_sym).to_s
|
38
|
+
@username = @config.get("#{@id}_username".to_sym).to_s
|
39
|
+
@password = @config.get("#{@id}_password".to_sym).to_s
|
40
|
+
|
41
|
+
@protocol = @config.get("#{@id}_protocol".to_sym).to_s.downcase
|
42
|
+
if @protocol == "nodata"
|
43
|
+
@protocol = if @ip == "localhost" || @ip.start_with?("127.0.0.")
|
44
|
+
"local"
|
45
|
+
else
|
46
|
+
"ssh"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
@port = @config.get("#{@id}_port".to_sym).to_i
|
51
|
+
if @port.zero?
|
52
|
+
default = {"local" => 0, "ssh" => 22, "telnet" => 23}
|
53
|
+
@port = default[@protocol]
|
54
|
+
end
|
55
|
+
@route = @config.get("#{@id}_route".to_sym)
|
56
|
+
end
|
57
|
+
|
58
|
+
def init_default
|
59
|
+
@id = :default
|
60
|
+
@ip = "localhost"
|
61
|
+
@username = "NODATA"
|
62
|
+
@password = "NODATA"
|
63
|
+
@protocol = "local"
|
64
|
+
@port = 0
|
65
|
+
@route = "NODATA"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/teuton/case/play.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Case
|
4
|
-
# Case class: play
|
5
|
-
# TODO: Encapsulate code into PlayManager class
|
6
|
-
# * play_in_parallel, play_in_sequence, fill_report, close_opened_sessions
|
7
4
|
# READ: sessions, config, groups, action, report
|
8
5
|
# TODO: groups from Project or from Case???
|
9
6
|
def play
|
@@ -18,19 +15,18 @@ class Case
|
|
18
15
|
end
|
19
16
|
alias_method :start, :play
|
20
17
|
|
18
|
+
private
|
19
|
+
|
21
20
|
def close_opened_sessions
|
22
21
|
@sessions.each_value do |s|
|
23
22
|
s.close if s.instance_of? Net::SSH::Connection::Session
|
24
23
|
end
|
25
24
|
end
|
26
25
|
|
27
|
-
private
|
28
|
-
|
29
26
|
def play_groups_in_sequence
|
30
27
|
verboseln "\n=> Starting case [#{@config.get(:tt_members)}]" if get(:tt_sequence) == true
|
31
28
|
@groups.each do |t|
|
32
29
|
@action[:groupname] = t[:name]
|
33
|
-
# TODO: @parent(case).instance_eval(&t[:block])
|
34
30
|
instance_eval(&t[:block])
|
35
31
|
end
|
36
32
|
end
|
@@ -4,15 +4,6 @@ require_relative "ext_array"
|
|
4
4
|
require_relative "ext_compare"
|
5
5
|
require_relative "ext_filter"
|
6
6
|
|
7
|
-
# This object contains data returned by remote/local execution
|
8
|
-
# * initialize
|
9
|
-
# * alterations
|
10
|
-
# * content
|
11
|
-
# * debug
|
12
|
-
# * ok?
|
13
|
-
# * reset
|
14
|
-
# * restore
|
15
|
-
# * value
|
16
7
|
class Result
|
17
8
|
attr_reader :content
|
18
9
|
attr_accessor :exitcode
|
@@ -22,6 +13,16 @@ class Result
|
|
22
13
|
reset
|
23
14
|
end
|
24
15
|
|
16
|
+
def reset
|
17
|
+
@content_backup = []
|
18
|
+
@content = []
|
19
|
+
@exitcode = -1
|
20
|
+
|
21
|
+
# @value = nil
|
22
|
+
@expected = nil
|
23
|
+
@alterations = []
|
24
|
+
end
|
25
|
+
|
25
26
|
def alterations
|
26
27
|
if @alterations.is_a? String
|
27
28
|
@alterations
|
@@ -49,15 +50,6 @@ class Result
|
|
49
50
|
@expected.to_s
|
50
51
|
end
|
51
52
|
|
52
|
-
def reset
|
53
|
-
@content_backup = []
|
54
|
-
@content = []
|
55
|
-
@exitcode = -1
|
56
|
-
@value = nil
|
57
|
-
@expected = nil
|
58
|
-
@alterations = []
|
59
|
-
end
|
60
|
-
|
61
53
|
def ok?
|
62
54
|
@exitcode.zero?
|
63
55
|
end
|
@@ -65,10 +57,10 @@ class Result
|
|
65
57
|
def restore
|
66
58
|
temp = @content_backup.clone
|
67
59
|
reset
|
68
|
-
@content_backup = temp
|
69
|
-
@content = temp.clone
|
60
|
+
# @content_backup = temp
|
61
|
+
# @content = temp.clone
|
62
|
+
self.content = (temp)
|
70
63
|
end
|
71
|
-
alias_method :restore!, :restore
|
72
64
|
|
73
65
|
def value
|
74
66
|
@content[0]
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../case/dsl/macro"
|
4
|
+
require_relative "../case/result/result"
|
5
|
+
require_relative "../utils/project"
|
6
|
+
require_relative "../utils/logger"
|
7
|
+
require_relative "dsl/all"
|
8
|
+
require_relative "show"
|
9
|
+
|
10
|
+
class Checker
|
11
|
+
include DSL # Include case/DSL/macro functions only
|
12
|
+
include CheckDSL
|
13
|
+
|
14
|
+
attr_reader :result
|
15
|
+
|
16
|
+
def initialize(script_path, config_path)
|
17
|
+
@path = {}
|
18
|
+
@path[:script] = script_path
|
19
|
+
@path[:dirname] = File.dirname(script_path)
|
20
|
+
@path[:filename] = File.basename(script_path, ".rb")
|
21
|
+
@path[:config] = config_path
|
22
|
+
reset
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
@result = Result.new
|
27
|
+
@targetid = 0
|
28
|
+
@stats = {
|
29
|
+
groups: 0,
|
30
|
+
targets: 0,
|
31
|
+
logs: 0,
|
32
|
+
readmes: 0,
|
33
|
+
uniques: 0,
|
34
|
+
hosts: {},
|
35
|
+
gets: {},
|
36
|
+
sets: [],
|
37
|
+
uploads: []
|
38
|
+
}
|
39
|
+
@target_begin = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def show
|
43
|
+
Logger.verbose = true
|
44
|
+
process_content
|
45
|
+
cs = ShowCheck.new(stats: @stats, path: @path)
|
46
|
+
cs.show_stats
|
47
|
+
cs.revise_config_content
|
48
|
+
end
|
49
|
+
|
50
|
+
def show_onlyconfig
|
51
|
+
Logger.verbose = false
|
52
|
+
process_content
|
53
|
+
Logger.verbose = true
|
54
|
+
cs = ShowCheck.new(stats: @stats, path: @path)
|
55
|
+
cs.suggest_config_content
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def process_content
|
61
|
+
groups = Project.value[:groups]
|
62
|
+
option = Project.value[:options]
|
63
|
+
|
64
|
+
Logger.info ""
|
65
|
+
if Project.value[:uses].size.positive?
|
66
|
+
Logger.info Terminal::Table.new { |st| st.add_row ["USE: external libraries"] }
|
67
|
+
Project.value[:uses].each_with_index { Logger.info " #{_2 + 1}. #{_1}" }
|
68
|
+
end
|
69
|
+
groups.each do |t|
|
70
|
+
@stats[:groups] += 1
|
71
|
+
unless option[:panel]
|
72
|
+
msg = "GROUP: #{t[:name]}"
|
73
|
+
my_screen_table = Terminal::Table.new { |st| st.add_row [msg] }
|
74
|
+
Logger.info my_screen_table
|
75
|
+
end
|
76
|
+
instance_eval(&t[:block])
|
77
|
+
end
|
78
|
+
if @target_begin
|
79
|
+
Logger.warn "WARN Last 'target' requires 'expect'\n"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative "builtin"
|
2
|
+
require_relative "expect"
|
3
|
+
require_relative "getset"
|
4
|
+
require_relative "run"
|
5
|
+
|
6
|
+
module CheckDSL
|
7
|
+
def log(text = "", type = :info)
|
8
|
+
@stats[:logs] += 1
|
9
|
+
prefix = (type == :info) ? "" : "#{type.to_s.upcase}: "
|
10
|
+
Logger.info " log #{prefix}" + text.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def readme(text)
|
14
|
+
@stats[:readmes] += 1
|
15
|
+
Logger.info " readme #{text}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def target(desc, args = {})
|
19
|
+
if @target_begin
|
20
|
+
Logger.warn "WARN Previous 'target' requires 'expect'"
|
21
|
+
end
|
22
|
+
@target_begin = true
|
23
|
+
@stats[:targets] += 1
|
24
|
+
@targetid += 1
|
25
|
+
weight = args[:weight] ? args[:weight].to_f : 1.0
|
26
|
+
Logger.info format("(%03<targetid>d) target %<desc>s", targetid: @targetid, desc: desc)
|
27
|
+
Logger.info " weight #{weight}"
|
28
|
+
end
|
29
|
+
alias_method :goal, :target
|
30
|
+
|
31
|
+
def unique(key, _value)
|
32
|
+
@stats[:uniques] += 1
|
33
|
+
|
34
|
+
Logger.info " unique value for <#{key}>"
|
35
|
+
Logger.info ""
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative "expect_sequence"
|
2
|
+
|
3
|
+
module CheckDSL
|
4
|
+
def expect(cond)
|
5
|
+
unless @target_begin
|
6
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
7
|
+
end
|
8
|
+
Logger.info " alter #{result.alterations}" unless result.alterations.empty?
|
9
|
+
Logger.info " expect #{cond} (#{cond.class})"
|
10
|
+
Logger.info ""
|
11
|
+
@target_begin = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def expect_exit(cond)
|
15
|
+
unless @target_begin
|
16
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
17
|
+
end
|
18
|
+
Logger.info " expect_exit #{cond} (#{cond.class})"
|
19
|
+
Logger.info ""
|
20
|
+
@target_begin = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def expect_fail
|
24
|
+
unless @target_begin
|
25
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
26
|
+
end
|
27
|
+
Logger.info " expect_fail"
|
28
|
+
Logger.info ""
|
29
|
+
@target_begin = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def expect_first(cond)
|
33
|
+
unless @target_begin
|
34
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
35
|
+
end
|
36
|
+
Logger.info " alter #{result.alterations}" unless result.alterations.empty?
|
37
|
+
Logger.info " expect_first #{cond} (#{cond.class})"
|
38
|
+
Logger.info ""
|
39
|
+
@target_begin = false
|
40
|
+
end
|
41
|
+
|
42
|
+
def expect_last(cond)
|
43
|
+
unless @target_begin
|
44
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
45
|
+
end
|
46
|
+
Logger.info " alter #{result.alterations}" unless result.alterations.empty?
|
47
|
+
Logger.info " expect_last #{cond} (#{cond.class})"
|
48
|
+
Logger.info ""
|
49
|
+
@target_begin = false
|
50
|
+
end
|
51
|
+
|
52
|
+
def expect_none(cond = nil, args = {})
|
53
|
+
unless @target_begin
|
54
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
55
|
+
end
|
56
|
+
Logger.info " alter #{result.alterations}" unless result.alterations.empty?
|
57
|
+
Logger.info " expect_none #{cond} (#{cond.class})"
|
58
|
+
Logger.info ""
|
59
|
+
@target_begin = false
|
60
|
+
end
|
61
|
+
|
62
|
+
def expect_nothing
|
63
|
+
expect_none nil, {}
|
64
|
+
end
|
65
|
+
|
66
|
+
def expect_ok
|
67
|
+
expect_exit 0
|
68
|
+
end
|
69
|
+
|
70
|
+
def expect_one(cond)
|
71
|
+
unless @target_begin
|
72
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
73
|
+
end
|
74
|
+
Logger.info " alter #{result.alterations}" unless result.alterations.empty?
|
75
|
+
Logger.info " expect_one #{cond} (#{cond.class})"
|
76
|
+
Logger.info ""
|
77
|
+
@target_begin = false
|
78
|
+
end
|
79
|
+
|
80
|
+
def expect_sequence(&block)
|
81
|
+
unless @target_begin
|
82
|
+
Logger.warn "WARN 'expect' with no previous 'target'"
|
83
|
+
end
|
84
|
+
seq = CheckDSL::ExpectSequence.new
|
85
|
+
seq.is_valid?(&block)
|
86
|
+
Logger.info " expect_sequence #{seq.expected}"
|
87
|
+
Logger.info ""
|
88
|
+
@target_begin = false
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CheckDSL
|
2
|
+
class ExpectSequence
|
3
|
+
def initialize
|
4
|
+
@expected = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def is_valid?(&block)
|
8
|
+
instance_eval(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def expected
|
12
|
+
@expected.join(">")
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def find(value)
|
18
|
+
@expected << "find(#{value})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def next_to(value)
|
22
|
+
@expected << "next_to(#{value})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def ignore(value)
|
26
|
+
@expected << "ignore(#{value})"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CheckDSL
|
2
|
+
def get(varname)
|
3
|
+
data = @stats[:gets]
|
4
|
+
data[varname] = data[varname] ? (data[varname] + 1) : 1
|
5
|
+
"get(#{varname})"
|
6
|
+
end
|
7
|
+
|
8
|
+
def gett(option)
|
9
|
+
get(option)
|
10
|
+
end
|
11
|
+
|
12
|
+
def set(key, value)
|
13
|
+
key = ":" + key.to_s if key.instance_of? Symbol
|
14
|
+
value = ":" + value.to_s if value.instance_of? Symbol
|
15
|
+
|
16
|
+
@stats[:sets] << "#{key}=#{value}"
|
17
|
+
Logger.info " set(#{key},#{value})"
|
18
|
+
end
|
19
|
+
|
20
|
+
def unset(key)
|
21
|
+
Logger.info " unset(#{key})"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module CheckDSL
|
2
|
+
def run(command, args = {})
|
3
|
+
args[:exec] = command
|
4
|
+
host = :localhost
|
5
|
+
host = args[:on] if args[:on]
|
6
|
+
goto(host, args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run_script(command, args = {})
|
10
|
+
host = :localhost
|
11
|
+
host = args[:on] if args[:on]
|
12
|
+
filename = command.split[1]
|
13
|
+
upload filename, to: host
|
14
|
+
run command, args
|
15
|
+
end
|
16
|
+
|
17
|
+
def goto(host = :localhost, args = {})
|
18
|
+
result.reset
|
19
|
+
@stats[:hosts][host] = @stats[:hosts][host] ? (@stats[:hosts][host] + 1) : 1
|
20
|
+
Logger.info " run '#{args[:exec]}' on #{host}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def upload(filename, args = {})
|
24
|
+
host = args[:to]
|
25
|
+
args.delete(:to)
|
26
|
+
custom = if args == {}
|
27
|
+
""
|
28
|
+
else
|
29
|
+
values = args.map { "#{_1}=#{_2}" }
|
30
|
+
"and #{values.join(",")}"
|
31
|
+
end
|
32
|
+
@stats[:uploads] << filename
|
33
|
+
Logger.info " upload '#{filename}' to #{host} #{custom}"
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../utils/project"
|
4
|
+
|
5
|
+
def use(filename)
|
6
|
+
filename += ".rb"
|
7
|
+
rbfiles = File.join(Project.value[:project_path], "**", filename)
|
8
|
+
files = Dir.glob(rbfiles)
|
9
|
+
use = []
|
10
|
+
files.sort.each { |f| use << f if f.include?(filename) }
|
11
|
+
require_relative use[0]
|
12
|
+
Project.value[:uses] << use[0]
|
13
|
+
end
|
14
|
+
|
15
|
+
def group(name, &block)
|
16
|
+
Project.value[:groups] << {name: name, block: block}
|
17
|
+
end
|
18
|
+
alias task group
|
19
|
+
|
20
|
+
def define_macro(name, *args, &block)
|
21
|
+
Project.value[:macros][name] = {args: args, block: block}
|
22
|
+
end
|
23
|
+
alias def_macro define_macro
|
24
|
+
alias defmacro define_macro
|
25
|
+
|
26
|
+
def start(&block)
|
27
|
+
# Don't do nothing. We are checking test not running it
|
28
|
+
end
|
29
|
+
alias play start
|