teuton 3.2.0 → 3.2.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 +1 -1
- data/bin/teuton +2 -3
- data/docs/commands/readme.md +1 -1
- data/docs/devel/todo.md +74 -1
- data/docs/dsl/send.md +3 -3
- data/docs/dsl/show.md +2 -2
- data/docs/tutorial/es/nginx/README.md +4 -4
- data/lib/teuton/case/action.rb +31 -0
- data/lib/teuton/case/case.rb +8 -12
- data/lib/teuton/case/close.rb +1 -1
- data/lib/teuton/case/dsl/expect.rb +9 -10
- data/lib/teuton/case/dsl/expect_sequence.rb +1 -2
- data/lib/teuton/case/dsl/macro.rb +3 -2
- data/lib/teuton/case/dsl/run.rb +4 -5
- data/lib/teuton/case/dsl/send.rb +1 -17
- data/lib/teuton/case/dsl/target.rb +6 -4
- data/lib/teuton/case/dsl/upload.rb +1 -4
- data/lib/teuton/case/dsl/weight.rb +3 -3
- data/lib/teuton/case/execute/execute_base.rb +1 -1
- data/lib/teuton/case/execute/execute_local.rb +2 -2
- data/lib/teuton/case/execute/execute_manager.rb +6 -6
- data/lib/teuton/case/execute/execute_ssh.rb +6 -6
- data/lib/teuton/case/execute/execute_telnet.rb +4 -4
- data/lib/teuton/case/play.rb +7 -8
- data/lib/teuton/case_manager/case_manager.rb +4 -4
- data/lib/teuton/case_manager/dsl.rb +6 -9
- data/lib/teuton/case_manager/export_manager.rb +6 -12
- data/lib/teuton/case_manager/ext/check_cases.rb +1 -1
- data/lib/teuton/cli/app.rb +123 -0
- data/lib/teuton/cli/run.rb +38 -0
- data/lib/teuton/errors.rb +94 -0
- data/lib/teuton/readme/action.rb +29 -0
- data/lib/teuton/readme/dsl/all.rb +7 -5
- data/lib/teuton/readme/dsl/expect.rb +3 -3
- data/lib/teuton/readme/dsl/run.rb +5 -11
- data/lib/teuton/readme/main.rb +13 -6
- data/lib/teuton/readme/readme.rb +12 -15
- data/lib/teuton/report/formatter/default/txt.rb +2 -2
- data/lib/teuton/report/formatter/formatter.rb +4 -13
- data/lib/teuton/report/formatter/resume/txt.rb +2 -2
- data/lib/teuton/utils/config_file_reader.rb +3 -11
- data/lib/teuton/utils/logger.rb +15 -10
- data/lib/teuton/utils/name_file_finder.rb +3 -11
- data/lib/teuton/version.rb +1 -1
- data/lib/teuton.rb +6 -11
- metadata +6 -2
- data/lib/teuton/cli.rb +0 -120
|
@@ -13,19 +13,19 @@ end
|
|
|
13
13
|
alias def_macro define_macro
|
|
14
14
|
alias defmacro define_macro
|
|
15
15
|
|
|
16
|
-
# Define a group of [target/run/expect]s
|
|
17
|
-
# @param name (String) Group name
|
|
18
|
-
# @param block (Block) Tests code
|
|
19
16
|
def group(name, &block)
|
|
20
17
|
Project.value[:groups] << { name: name, block: block }
|
|
21
18
|
end
|
|
22
19
|
alias task group
|
|
23
20
|
|
|
24
21
|
def play(&block)
|
|
25
|
-
# Start test
|
|
26
22
|
CaseManager.new.play(&block)
|
|
27
23
|
end
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
def start(...)
|
|
26
|
+
Logger.warn "[DEPRECATED] Replace 'start do' by `play do'"
|
|
27
|
+
play(...)
|
|
28
|
+
end
|
|
29
29
|
|
|
30
30
|
def use(filename)
|
|
31
31
|
filename += ".rb"
|
|
@@ -37,9 +37,6 @@ def use(filename)
|
|
|
37
37
|
require_relative findfiles.first
|
|
38
38
|
Project.value[:uses] << File.basename(findfiles.first)
|
|
39
39
|
rescue StandardError => e
|
|
40
|
-
|
|
41
|
-
warn Rainbow("[ERROR] File not found!").white
|
|
42
|
-
warn Rainbow("[ERROR] Fix line <use '#{filename}'>").white
|
|
43
|
-
exit 1
|
|
40
|
+
raise Teuton::CaseManagerDslError.new(e, filename)
|
|
44
41
|
end
|
|
45
42
|
end
|
|
@@ -14,23 +14,17 @@ class ExportManager
|
|
|
14
14
|
# @param cases (Array)
|
|
15
15
|
# @param input (Hash) Selected export options
|
|
16
16
|
def call(main_report, cases, args)
|
|
17
|
-
if args.class != Hash
|
|
18
|
-
warn Rainbow("[ERROR] ExportManager: argument error!").bright.red
|
|
19
|
-
warn Rainbow("[ERROR] Fix line <export #{args}>").white
|
|
20
|
-
warn Rainbow("[ERROR] Replace by <export format: 'txt'>").white
|
|
21
|
-
warn ""
|
|
22
|
-
exit 1
|
|
23
|
-
end
|
|
17
|
+
raise Teuton::ExportArgumentError, args if args.class != Hash
|
|
24
18
|
|
|
25
19
|
# Step 1: Validate options
|
|
26
20
|
options = strings2symbols(args)
|
|
27
21
|
options[:format] = Project.value[:format] if options[:format].nil?
|
|
28
22
|
|
|
29
23
|
unless Formatter.available_formats.include? options[:format]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
Logger.warn "ExportManager: Unkown format!"
|
|
25
|
+
Logger.warn "Fix line <export format: #{options[:format]}>"
|
|
26
|
+
Logger.warn "Available formats: #{Formatter.available_formats.join(", ")}."
|
|
27
|
+
Logger.warn "Using default format <txt>."
|
|
34
28
|
options[:format] = :txt
|
|
35
29
|
end
|
|
36
30
|
|
|
@@ -84,7 +78,7 @@ class ExportManager
|
|
|
84
78
|
"%<hour>02d%<min>02d%<sec>02d", data)
|
|
85
79
|
preserve_dir = File.join(srcdir, subdir)
|
|
86
80
|
|
|
87
|
-
|
|
81
|
+
Logger.info "Preserving files => #{preserve_dir}"
|
|
88
82
|
FileUtils.mkdir(preserve_dir)
|
|
89
83
|
Dir.glob(File.join(srcdir, "**.*")).each { |file| FileUtils.cp(file, preserve_dir) }
|
|
90
84
|
end
|
|
@@ -69,7 +69,7 @@ module CheckCasesExtension
|
|
|
69
69
|
# 3) And order to build hall of fame
|
|
70
70
|
def close_reports_for_all_cases(uniques)
|
|
71
71
|
threads = []
|
|
72
|
-
@cases.each { |c| threads << Thread.new { c.close
|
|
72
|
+
@cases.each { |c| threads << Thread.new { c.close(uniques) } }
|
|
73
73
|
threads.each(&:join)
|
|
74
74
|
|
|
75
75
|
HallOfFame.new(@cases).call
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require "thor"
|
|
2
|
+
require_relative "../version"
|
|
3
|
+
require_relative "../../teuton"
|
|
4
|
+
|
|
5
|
+
module Teuton
|
|
6
|
+
module CLI
|
|
7
|
+
class App < Thor
|
|
8
|
+
map ["h", "-h", "--help"] => "help"
|
|
9
|
+
|
|
10
|
+
map ["n", "-n", "--new"] => "new"
|
|
11
|
+
desc "new DIRECTORY", "Create skeleton for a new project"
|
|
12
|
+
long_desc <<-LONGDESC
|
|
13
|
+
Create files for a new project.
|
|
14
|
+
LONGDESC
|
|
15
|
+
def new(projectpath)
|
|
16
|
+
Teuton.create(projectpath)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
map ["c", "-c", "--check"] => "check"
|
|
20
|
+
option :onlyconfig, type: :boolean
|
|
21
|
+
option :color, type: :boolean
|
|
22
|
+
option :cname, type: :string
|
|
23
|
+
option :cpath, type: :string
|
|
24
|
+
desc "check [OPTIONS] DIRECTORY", "Check test and config file content"
|
|
25
|
+
long_desc <<~LONGDESC
|
|
26
|
+
|
|
27
|
+
(1) teuton check PATH/TO/DIR , Check content of start.rb and config.yaml files.
|
|
28
|
+
|
|
29
|
+
(2) teuton check PATH/TO/DIR --cname=demo , Check content of start.rb and demo.yaml files:
|
|
30
|
+
|
|
31
|
+
(3) teuton check PATH/TO/DIR --onlyconfig , Only show config file recomendations
|
|
32
|
+
|
|
33
|
+
(4) teuton check PATH/TO/DIR/foo.rb , Check content of foo.rb and foo.yaml files.
|
|
34
|
+
|
|
35
|
+
(5) teuton check PATH/TO/DIR/foo.rb --cname=demo , Check content of foo.rb and demo.yaml files.
|
|
36
|
+
|
|
37
|
+
LONGDESC
|
|
38
|
+
def check(projectpath)
|
|
39
|
+
Teuton.check(projectpath, options)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
map ["co", "-co", "--config"] => "config"
|
|
43
|
+
desc "config [OPTIONS] DIRECTORY", "Suggest configuration."
|
|
44
|
+
long_desc <<~LONGDESC
|
|
45
|
+
config DIRECTORY, "Suggest the content of the configuration file based on the test"
|
|
46
|
+
LONGDESC
|
|
47
|
+
def config(projectpath)
|
|
48
|
+
# Check Test: suggest the content of the configuration file based on the test
|
|
49
|
+
opt = {"onlyconfig" => true}
|
|
50
|
+
Teuton.check(projectpath, opt)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
map ["--readme"] => "readme"
|
|
54
|
+
option :lang, type: :string
|
|
55
|
+
desc "readme DIRECTORY", "Show README extracted from test contents"
|
|
56
|
+
long_desc <<-LONGDESC
|
|
57
|
+
|
|
58
|
+
(1) teuton readme foo
|
|
59
|
+
, Create README.md from foo/start.rb.
|
|
60
|
+
|
|
61
|
+
(2) teuton readme foo/demo.rb
|
|
62
|
+
, Create README.md from foo/demo.rb.
|
|
63
|
+
LONGDESC
|
|
64
|
+
|
|
65
|
+
def readme(projectpath)
|
|
66
|
+
Teuton.readme(projectpath, options)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
map ["--run", "run"] => "play"
|
|
70
|
+
option :export, type: :string
|
|
71
|
+
option :cname, type: :string
|
|
72
|
+
option :cpath, type: :string
|
|
73
|
+
option :case, type: :string
|
|
74
|
+
option :color, type: :boolean
|
|
75
|
+
option :quiet, type: :boolean
|
|
76
|
+
desc "[run] [OPTIONS] DIRECTORY", "Run test from directory"
|
|
77
|
+
long_desc <<-LONGDESC
|
|
78
|
+
This function execute challenge from specified directory.
|
|
79
|
+
By default, show progress on the screen.
|
|
80
|
+
|
|
81
|
+
Let's see others options:
|
|
82
|
+
|
|
83
|
+
(1) teuton foo, run challenge from foo/start.rb with foo/config.yaml config file.
|
|
84
|
+
|
|
85
|
+
(2) teuton run foo, same as (1).
|
|
86
|
+
|
|
87
|
+
(3) teuton run --export=json foo, run challenge and export using json format.
|
|
88
|
+
Others output formats availables are: txt, html, yaml, json and colored_text.
|
|
89
|
+
|
|
90
|
+
(4) teuton run --cname=demo foo, run challenge from foo/start.rb with foo/demo.yaml config file.
|
|
91
|
+
|
|
92
|
+
(5) teuton foo/demo.rb, Run challenge from foo/demo.rb with foo/demo.yaml config file.
|
|
93
|
+
|
|
94
|
+
LONGDESC
|
|
95
|
+
def play(filepath)
|
|
96
|
+
Teuton.run(filepath, options)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
map ["v", "-v", "--version"] => "version"
|
|
100
|
+
desc "version", "Show the program version"
|
|
101
|
+
def version
|
|
102
|
+
puts "#{Teuton::APPNAME} version #{Teuton::VERSION}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# These inputs are equivalents:
|
|
107
|
+
# * teuton dir/foo
|
|
108
|
+
# * teuton run dir/foo
|
|
109
|
+
def method_missing(method, *_args, &_block)
|
|
110
|
+
play(method.to_s)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
114
|
+
# Respond to missing methods name
|
|
115
|
+
super
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def self.exit_on_failure?
|
|
119
|
+
true
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative "app"
|
|
4
|
+
|
|
5
|
+
module Teuton::CLI
|
|
6
|
+
def self.run(argv)
|
|
7
|
+
begin
|
|
8
|
+
Teuton::CLI::App.start(argv)
|
|
9
|
+
exit 0
|
|
10
|
+
rescue Interrupt
|
|
11
|
+
puts "\nExecution cancelled by the user."
|
|
12
|
+
exit 130
|
|
13
|
+
rescue Teuton::CaseManagerDslError => e
|
|
14
|
+
lines = e.message.split("\n")
|
|
15
|
+
head = lines.shift
|
|
16
|
+
warn "Error | #{head}"
|
|
17
|
+
lines.each { |line| warn Rainbow("Error| #{line}").white }
|
|
18
|
+
rescue Teuton::ConfigFileError => e
|
|
19
|
+
lines = e.message.split("\n")
|
|
20
|
+
head = lines.shift
|
|
21
|
+
warn "Error | #{head}"
|
|
22
|
+
lines.each { |line| warn Rainbow("Error| #{line}").white }
|
|
23
|
+
rescue Teuton::MainScriptNotFoundError => e
|
|
24
|
+
warn "Error | #{e.message}"
|
|
25
|
+
rescue Teuton::Error => e
|
|
26
|
+
warn "Controlled error: #{e.message}"
|
|
27
|
+
e.backtrace&.first(3)&.each do |line|
|
|
28
|
+
warn Rainbow("Error | #{line}").white
|
|
29
|
+
end
|
|
30
|
+
rescue => e
|
|
31
|
+
warn "Unexpected error: #{e.message}"
|
|
32
|
+
raise e if ENV["DEBUG"]
|
|
33
|
+
|
|
34
|
+
e.backtrace&.first(3)&.each { |line| warn Rainbow("Error | #{line}").white }
|
|
35
|
+
end
|
|
36
|
+
exit 1
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Teuton
|
|
2
|
+
class Error < StandardError; end
|
|
3
|
+
|
|
4
|
+
class CaseManagerDslError < Error
|
|
5
|
+
attr_reader :original_error, :filename
|
|
6
|
+
|
|
7
|
+
def initialize(original_error, filename)
|
|
8
|
+
@original_error = original_error
|
|
9
|
+
@filename = filename
|
|
10
|
+
super(build_message)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def build_message
|
|
16
|
+
<<~MSG.strip
|
|
17
|
+
case_manager/dsl: #{@original_error}
|
|
18
|
+
File not found! Fix line <use '#{@filename}'>
|
|
19
|
+
MSG
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class ConfigurationError < Error; end
|
|
24
|
+
|
|
25
|
+
class ConfigFileError < Error
|
|
26
|
+
attr_reader :filepath, :original_error
|
|
27
|
+
|
|
28
|
+
def initialize(filepath, original_error)
|
|
29
|
+
@filepath = filepath
|
|
30
|
+
@original_error = original_error
|
|
31
|
+
super(build_message)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def build_message
|
|
37
|
+
<<~MSG.strip
|
|
38
|
+
Reading configurations file:
|
|
39
|
+
- File : #{@filepath}
|
|
40
|
+
- Type : #{@original_error}
|
|
41
|
+
MSG
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class InputError < Error; end
|
|
46
|
+
class ExecutionError < Error; end
|
|
47
|
+
|
|
48
|
+
class ExportArgumentError < Error
|
|
49
|
+
attr_reader :args
|
|
50
|
+
|
|
51
|
+
def initialize(args)
|
|
52
|
+
@args = args
|
|
53
|
+
super(build_message)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def build_message
|
|
59
|
+
<<~MSG.strip
|
|
60
|
+
ExportManager: argument error!
|
|
61
|
+
- Fix line <export #{@args}>
|
|
62
|
+
- Replace by <export format: 'txt'>
|
|
63
|
+
MSG
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class MainScriptNotFoundError < Error
|
|
68
|
+
attr_reader :script_path
|
|
69
|
+
|
|
70
|
+
def initialize(script_path)
|
|
71
|
+
@script_path = script_path
|
|
72
|
+
super(build_message)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def build_message
|
|
78
|
+
<<~MSG.strip
|
|
79
|
+
Main script file not found!
|
|
80
|
+
- File: #{script_path}
|
|
81
|
+
MSG
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class UnexpectedSequenceTypeError < Error
|
|
86
|
+
attr_reader :received_class
|
|
87
|
+
|
|
88
|
+
def initialize(value_class)
|
|
89
|
+
super("expect_sequence #{value_class}")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
class UploadArgumentError < ArgumentError; end
|
|
94
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Readme
|
|
2
|
+
class Action
|
|
3
|
+
attr_reader :id
|
|
4
|
+
attr_accessor :description, :weight, :readme, :host, :exec
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@id = 0
|
|
8
|
+
@description = nil
|
|
9
|
+
@host = nil
|
|
10
|
+
@readme = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def reset
|
|
14
|
+
@id += 1
|
|
15
|
+
@description = nil
|
|
16
|
+
@host = nil
|
|
17
|
+
@readme = []
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_h
|
|
22
|
+
{
|
|
23
|
+
id: id,
|
|
24
|
+
description: description, weight: weight, readme: readme,
|
|
25
|
+
host: host, exec: exec
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -6,19 +6,21 @@ require_relative "run"
|
|
|
6
6
|
|
|
7
7
|
module ReadmeDSL
|
|
8
8
|
def readme(text)
|
|
9
|
-
if @action
|
|
9
|
+
if @action.description.nil?
|
|
10
10
|
@current[:readme] << text # It's a group readme
|
|
11
11
|
else
|
|
12
|
-
@action
|
|
12
|
+
@action.readme << text # It's a target readme
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def target(desc, args = {})
|
|
17
|
-
previous_host = @action
|
|
18
|
-
@action =
|
|
17
|
+
previous_host = @action.host
|
|
18
|
+
@action.description = desc
|
|
19
|
+
@action.host = previous_host
|
|
20
|
+
@action.readme = []
|
|
19
21
|
weight = 1.0
|
|
20
22
|
weight = args[:weight].to_f if args[:weight]
|
|
21
|
-
@action
|
|
23
|
+
@action.weight = weight
|
|
22
24
|
end
|
|
23
25
|
alias_method :goal, :target
|
|
24
26
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module ReadmeDSL
|
|
4
4
|
def expect(_cond, _args = {})
|
|
5
|
-
@current[:actions] << @action
|
|
5
|
+
@current[:actions] << @action.to_h
|
|
6
6
|
result.reset
|
|
7
7
|
end
|
|
8
8
|
alias_method :expect_any, :expect
|
|
@@ -12,7 +12,7 @@ module ReadmeDSL
|
|
|
12
12
|
alias_method :expect_one, :expect
|
|
13
13
|
|
|
14
14
|
def expect_fail
|
|
15
|
-
@current[:actions] << @action
|
|
15
|
+
@current[:actions] << @action.to_h
|
|
16
16
|
result.reset
|
|
17
17
|
end
|
|
18
18
|
alias_method :expect_ok, :expect_fail
|
|
@@ -23,7 +23,7 @@ module ReadmeDSL
|
|
|
23
23
|
alias_method :expect_nothing, :expect_none
|
|
24
24
|
|
|
25
25
|
def expect_sequence(&block)
|
|
26
|
-
@current[:actions] << @action
|
|
26
|
+
@current[:actions] << @action.to_h
|
|
27
27
|
result.reset
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -3,30 +3,24 @@ module ReadmeDSL
|
|
|
3
3
|
unless host == :localhost
|
|
4
4
|
b = {}
|
|
5
5
|
a = :"#{host}_ip"
|
|
6
|
-
if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
7
|
-
@cases_params << a
|
|
8
|
-
end
|
|
6
|
+
@cases_params << a if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
9
7
|
b[:ip] = @config[:global][a] if @config[:global][a]
|
|
10
8
|
b[:ip] = @setted_params[a] if @setted_params[a]
|
|
11
9
|
|
|
12
10
|
a = :"#{host}_username"
|
|
13
|
-
if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
14
|
-
@cases_params << a
|
|
15
|
-
end
|
|
11
|
+
@cases_params << a if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
16
12
|
b[:username] = @config[:global][a] if @config[:global][a]
|
|
17
13
|
b[:username] = @setted_params[a] if @setted_params[a]
|
|
18
14
|
|
|
19
15
|
a = :"#{host}_password"
|
|
20
|
-
if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
21
|
-
@cases_params << a
|
|
22
|
-
end
|
|
16
|
+
@cases_params << a if @config[:global][a].nil? && !@setted_params.include?(a)
|
|
23
17
|
b[:password] = @config[:global][a] if @config[:global][a]
|
|
24
18
|
b[:password] = @setted_params[a] if @setted_params[a]
|
|
25
19
|
|
|
26
20
|
@required_hosts[host.to_s] = b
|
|
27
21
|
end
|
|
28
|
-
@action
|
|
29
|
-
@action
|
|
22
|
+
@action.host = host
|
|
23
|
+
@action.exec = args[:exec] || "noexec"
|
|
30
24
|
end
|
|
31
25
|
|
|
32
26
|
def run(command, args = {})
|
data/lib/teuton/readme/main.rb
CHANGED
|
@@ -12,16 +12,23 @@ def use(filename)
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def define_macro(name, *args, &block)
|
|
15
|
-
Project.value[:macros][name] = {args: args, block: block}
|
|
15
|
+
Project.value[:macros][name] = { args: args, block: block }
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def group(name, &block)
|
|
19
|
-
Project.value[:groups] << {name: name, block: block}
|
|
19
|
+
Project.value[:groups] << { name: name, block: block }
|
|
20
20
|
end
|
|
21
|
-
alias task group
|
|
22
21
|
|
|
23
|
-
def
|
|
22
|
+
def task(...)
|
|
23
|
+
Logger.warn "[DEPRECATED] Replace 'task' by 'group'"
|
|
24
|
+
group(...)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def play(&block)
|
|
24
28
|
# don't do nothing
|
|
25
29
|
end
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
|
|
31
|
+
def start(...)
|
|
32
|
+
Logger.warn "[DEPRECATED] Replace `start' by' play'"
|
|
33
|
+
play(...)
|
|
34
|
+
end
|
data/lib/teuton/readme/readme.rb
CHANGED
|
@@ -3,12 +3,13 @@ require_relative "../utils/project"
|
|
|
3
3
|
require_relative "../utils/config_file_reader"
|
|
4
4
|
require_relative "../case/dsl/macro"
|
|
5
5
|
require_relative "../version"
|
|
6
|
+
require_relative "action"
|
|
6
7
|
require_relative "dsl/all"
|
|
7
8
|
require_relative "lang"
|
|
8
9
|
require_relative "result"
|
|
9
10
|
|
|
10
11
|
class Readme
|
|
11
|
-
include DSL
|
|
12
|
+
include DSL # Used by case/dsl/macro
|
|
12
13
|
include ReadmeDSL
|
|
13
14
|
|
|
14
15
|
attr_reader :result, :data
|
|
@@ -39,7 +40,7 @@ class Readme
|
|
|
39
40
|
@data[:macros] = []
|
|
40
41
|
@data[:groups] = []
|
|
41
42
|
@data[:play] = []
|
|
42
|
-
|
|
43
|
+
@action = Action.new
|
|
43
44
|
@setted_params = {}
|
|
44
45
|
@cases_params = []
|
|
45
46
|
@global_params = {}
|
|
@@ -50,15 +51,11 @@ class Readme
|
|
|
50
51
|
Project.value[:groups].each do |group|
|
|
51
52
|
@current = {name: group[:name], readme: [], actions: []}
|
|
52
53
|
@data[:groups] << @current
|
|
53
|
-
|
|
54
|
+
@action.reset
|
|
54
55
|
instance_eval(&group[:block])
|
|
55
56
|
end
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
def reset_action
|
|
59
|
-
@action = {readme: []}
|
|
60
|
-
end
|
|
61
|
-
|
|
62
59
|
def show_head
|
|
63
60
|
puts "```"
|
|
64
61
|
puts format(Lang.get(:date), Time.now)
|
|
@@ -96,16 +93,16 @@ class Readme
|
|
|
96
93
|
puts "\n## #{group[:name].capitalize}\n"
|
|
97
94
|
group[:readme].each { |line| puts "#{line}\n" }
|
|
98
95
|
previous_host = nil
|
|
99
|
-
group[:actions].each_with_index do |
|
|
100
|
-
|
|
101
|
-
if previous_host.nil? ||
|
|
102
|
-
previous_host =
|
|
96
|
+
group[:actions].each_with_index do |a, index|
|
|
97
|
+
a[:host] = group[:actions][0][:host] if a[:host].nil? && index.positive?
|
|
98
|
+
if previous_host.nil? || a[:host] != previous_host
|
|
99
|
+
previous_host = a[:host] || "null"
|
|
103
100
|
puts format(Lang.get(:goto), previous_host.upcase)
|
|
104
101
|
end
|
|
105
|
-
weight = "(x#{
|
|
106
|
-
last =
|
|
107
|
-
puts "* #{weight}#{
|
|
108
|
-
|
|
102
|
+
weight = "(x#{a[:weight]}) "
|
|
103
|
+
last = a[:description].end_with?(".", ":") ? "" : "."
|
|
104
|
+
puts "* #{weight}#{a[:description]}#{last}"
|
|
105
|
+
a[:readme].each { |line| puts " * #{line}\n" }
|
|
109
106
|
end
|
|
110
107
|
end
|
|
111
108
|
end
|
|
@@ -112,8 +112,8 @@ class TXTFormatter < ArrayFormatter
|
|
|
112
112
|
when :red
|
|
113
113
|
Rainbow(text).color(:red)
|
|
114
114
|
else
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
Logger.warn "[TXTFormatter] colorize option=#{option}"
|
|
116
|
+
text
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
end
|
|
@@ -41,10 +41,10 @@ module Formatter
|
|
|
41
41
|
def self.call(report, options, filename)
|
|
42
42
|
klass = get(options[:format])
|
|
43
43
|
if klass.nil?
|
|
44
|
-
warn
|
|
45
|
-
warn
|
|
46
|
-
warn
|
|
47
|
-
|
|
44
|
+
Logger.warn "Formatter:"
|
|
45
|
+
Logger.warn "- Unkown format <#{options[:format]}>. Fix line <export format: FORMAT>"
|
|
46
|
+
Logger.warn "- Available formats: #{Formatter.available_formats.join(",")}."
|
|
47
|
+
return
|
|
48
48
|
end
|
|
49
49
|
formatter = klass.new(report)
|
|
50
50
|
formatter.init(filename)
|
|
@@ -55,13 +55,4 @@ module Formatter
|
|
|
55
55
|
def self.get(format)
|
|
56
56
|
LIST[format]
|
|
57
57
|
end
|
|
58
|
-
|
|
59
|
-
# def self.hide_feedback(report)
|
|
60
|
-
# report2 = report.clone
|
|
61
|
-
# report2.groups.each do |group|
|
|
62
|
-
# group.each do |item|
|
|
63
|
-
# puts item
|
|
64
|
-
# end
|
|
65
|
-
# end
|
|
66
|
-
# end
|
|
67
58
|
end
|
|
@@ -113,8 +113,8 @@ class ResumeTXTFormatter < ResumeArrayFormatter
|
|
|
113
113
|
when :red_bright
|
|
114
114
|
Rainbow(text).red.bright
|
|
115
115
|
else
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
Logger.warn "[ResumeTXTFormatter] colorize option=#{option}"
|
|
117
|
+
text
|
|
118
118
|
end
|
|
119
119
|
end
|
|
120
120
|
end
|
|
@@ -61,9 +61,7 @@ module ConfigFileReader
|
|
|
61
61
|
begin
|
|
62
62
|
data = YAML.load(File.open(filepath))
|
|
63
63
|
rescue => e
|
|
64
|
-
|
|
65
|
-
warn Rainbow("[ERROR] Revise file content! <#{filepath}>").white
|
|
66
|
-
exit 1
|
|
64
|
+
raise Teuton::ConfigFileError.new(filepath, e)
|
|
67
65
|
end
|
|
68
66
|
data = convert_string_keys_to_symbol(data)
|
|
69
67
|
data[:global] = data[:global] || {}
|
|
@@ -111,10 +109,7 @@ module ConfigFileReader
|
|
|
111
109
|
begin
|
|
112
110
|
data = YAML.load(File.open(filepath))
|
|
113
111
|
rescue => e
|
|
114
|
-
|
|
115
|
-
warn Rainbow("[ERROR] - File : #{filepath}").white
|
|
116
|
-
warn Rainbow("[ERROR] - Type : #{e}").white
|
|
117
|
-
exit 1
|
|
112
|
+
raise Teuton::ConfigFileError.new(filepath, e)
|
|
118
113
|
end
|
|
119
114
|
data[:tt_source_file] = relative_path(filepath)
|
|
120
115
|
convert_string_keys_to_symbol(data)
|
|
@@ -124,10 +119,7 @@ module ConfigFileReader
|
|
|
124
119
|
begin
|
|
125
120
|
data = JSON.parse(File.read(filepath), symbolize_names: true)
|
|
126
121
|
rescue => e
|
|
127
|
-
|
|
128
|
-
warn Rainboe("[ERROR] - File : #{filepath}").white
|
|
129
|
-
warn Rainbow("[ERROR] - Type : #{e}").white
|
|
130
|
-
exit 1
|
|
122
|
+
raise Teuton::ConfigFileError.new(filepath, e)
|
|
131
123
|
end
|
|
132
124
|
data[:tt_source_file] = relative_path(filepath)
|
|
133
125
|
convert_string_keys_to_symbol(data)
|