teuton 3.1.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/teuton +2 -3
  4. data/docs/commands/readme.md +1 -1
  5. data/docs/devel/todo.md +87 -44
  6. data/docs/dsl/send.md +3 -3
  7. data/docs/dsl/show.md +2 -2
  8. data/docs/install/t-node.md +4 -14
  9. data/docs/learn/18-log.md +55 -20
  10. data/docs/tutorial/es/nginx/README.md +4 -4
  11. data/lib/teuton/case/action.rb +31 -0
  12. data/lib/teuton/case/case.rb +8 -12
  13. data/lib/teuton/case/close.rb +1 -1
  14. data/lib/teuton/case/dsl/expect.rb +10 -11
  15. data/lib/teuton/case/dsl/expect_sequence.rb +1 -2
  16. data/lib/teuton/case/dsl/macro.rb +3 -2
  17. data/lib/teuton/case/dsl/run.rb +4 -5
  18. data/lib/teuton/case/dsl/run_script.rb +3 -3
  19. data/lib/teuton/case/dsl/send.rb +2 -18
  20. data/lib/teuton/case/dsl/target.rb +6 -4
  21. data/lib/teuton/case/dsl/upload.rb +2 -5
  22. data/lib/teuton/case/dsl/weight.rb +3 -3
  23. data/lib/teuton/case/execute/execute_base.rb +4 -4
  24. data/lib/teuton/case/execute/execute_local.rb +2 -2
  25. data/lib/teuton/case/execute/execute_manager.rb +6 -6
  26. data/lib/teuton/case/execute/execute_ssh.rb +6 -6
  27. data/lib/teuton/case/execute/execute_telnet.rb +4 -4
  28. data/lib/teuton/case/play.rb +7 -8
  29. data/lib/teuton/case_manager/case_manager.rb +4 -4
  30. data/lib/teuton/case_manager/dsl.rb +7 -10
  31. data/lib/teuton/case_manager/export_manager.rb +6 -12
  32. data/lib/teuton/case_manager/ext/check_cases.rb +1 -1
  33. data/lib/teuton/cli/app.rb +123 -0
  34. data/lib/teuton/cli/run.rb +38 -0
  35. data/lib/teuton/errors.rb +94 -0
  36. data/lib/teuton/readme/action.rb +29 -0
  37. data/lib/teuton/readme/dsl/all.rb +7 -5
  38. data/lib/teuton/readme/dsl/expect.rb +3 -3
  39. data/lib/teuton/readme/dsl/run.rb +5 -11
  40. data/lib/teuton/readme/main.rb +13 -6
  41. data/lib/teuton/readme/readme.rb +12 -15
  42. data/lib/teuton/report/formatter/base_formatter.rb +2 -2
  43. data/lib/teuton/report/formatter/default/txt.rb +2 -2
  44. data/lib/teuton/report/formatter/formatter.rb +4 -13
  45. data/lib/teuton/report/formatter/resume/txt.rb +2 -2
  46. data/lib/teuton/utils/config_file_reader.rb +4 -12
  47. data/lib/teuton/utils/logger.rb +15 -10
  48. data/lib/teuton/utils/name_file_finder.rb +3 -11
  49. data/lib/teuton/version.rb +1 -1
  50. data/lib/teuton.rb +6 -11
  51. metadata +6 -2
  52. data/lib/teuton/cli.rb +0 -120
@@ -6,19 +6,21 @@ require_relative "run"
6
6
 
7
7
  module ReadmeDSL
8
8
  def readme(text)
9
- if @action[:target].nil?
9
+ if @action.description.nil?
10
10
  @current[:readme] << text # It's a group readme
11
11
  else
12
- @action[:readme] << text # It's a target readme
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[:host]
18
- @action = {target: desc, host: previous_host, readme: []}
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[:weight] = weight
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[:host] = host
29
- @action[:exec] = args[:exec] || "noexec"
22
+ @action.host = host
23
+ @action.exec = args[:exec] || "noexec"
30
24
  end
31
25
 
32
26
  def run(command, args = {})
@@ -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 start(&block)
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
- # alias_method "play", "start" # REVISE THIS
27
- alias play start
30
+
31
+ def start(...)
32
+ Logger.warn "[DEPRECATED] Replace `start' by' play'"
33
+ play(...)
34
+ end
@@ -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
- reset_action
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
- reset_action
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 |item, index|
100
- item[:host] = group[:actions][0][:host] if item[:host].nil? && index.positive?
101
- if previous_host.nil? || item[:host] != previous_host
102
- previous_host = item[:host] || "null"
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#{item[:weight]}) "
106
- last = item[:target].end_with?(".", ":") ? "" : "."
107
- puts "* #{weight}#{item[:target]}#{last}"
108
- item[:readme].each { |line| puts " * #{line}\n" }
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
@@ -30,7 +30,7 @@ class BaseFormatter
30
30
 
31
31
  def trim(input)
32
32
  output = input.to_s
33
- output = "...#{input[-50, input.size]}" if output.size > 65
34
- output.to_s
33
+ output = "...#{output[-50, 50]}" if output.size > 65
34
+ output
35
35
  end
36
36
  end
@@ -112,8 +112,8 @@ class TXTFormatter < ArrayFormatter
112
112
  when :red
113
113
  Rainbow(text).color(:red)
114
114
  else
115
- puts "[ERROR] TXTFormatter#colorize option=#{option}"
116
- exit 1
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
- puts "[ERROR] Formatter:"
45
- puts " Unkown format <#{options[:format]}>. Fix line <export format: FORMAT>"
46
- puts " Available formats: #{Formatter.available_formats.join(",")}."
47
- exit 1
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
- puts "[ERROR] ResumeTXTFormatter#colorize option=#{option}"
117
- exit 1
116
+ Logger.warn "[ResumeTXTFormatter] colorize option=#{option}"
117
+ text
118
118
  end
119
119
  end
120
120
  end
@@ -11,7 +11,7 @@ module ConfigFileReader
11
11
 
12
12
  return read_json(filepath) if File.extname(filepath) == ".json"
13
13
 
14
- raise "[ERROR] ConfigFileReader.call: <#{filepath}>. Unkown extension!"
14
+ raise Rainbow("[ERROR] ConfigFileReader.call: <#{filepath}>. Unkown extension!").bright.red
15
15
  end
16
16
 
17
17
  def self.convert_string_keys_to_symbol(input)
@@ -61,9 +61,7 @@ module ConfigFileReader
61
61
  begin
62
62
  data = YAML.load(File.open(filepath))
63
63
  rescue => e
64
- warn "[ERROR] ConfigFileReader.read_yaml: #{e}"
65
- warn "[ERROR] Revise file content! <#{filepath}>"
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
- warn "[ERROR] Reading configurations from yaml:"
115
- warn "[ERROR] - File : #{filepath}"
116
- warn "[ERROR] - Type : #{e}"
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
- warn "[ERROR] Reading configurations from json:"
128
- warn "[ERROR] - File : #{filepath}"
129
- warn "[ERROR] - Type : #{e}"
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)
@@ -3,30 +3,35 @@ require "rainbow"
3
3
  class Logger
4
4
  @verbose = true
5
5
 
6
- def self.verbose=(value)
7
- @verbose = value
6
+ class << self
7
+ attr_writer :verbose
8
8
  end
9
9
 
10
- def self.verbose
11
- @verbose
10
+ class << self
11
+ attr_reader :verbose
12
+ end
13
+
14
+ def self.puts(message)
15
+ Kernel.puts message if @verbose
12
16
  end
13
17
 
14
18
  def self.info(message)
15
- puts message if @verbose
19
+ text = Rainbow("Info | #{message}").white
20
+ Kernel.puts text if @verbose
16
21
  end
17
22
 
18
23
  def self.warn(message)
19
- text = Rainbow(message).bright.yellow
20
- info(text)
24
+ text = Rainbow("Warn | #{message}").bright.yellow
25
+ Kernel.warn text if @verbose
21
26
  end
22
27
 
23
28
  def self.error(message)
24
- text = Rainbow(message).bright.red
25
- info(text)
29
+ text = Rainbow("Error | #{message}").bright.red
30
+ Kernel.warn text if @verbose
26
31
  end
27
32
 
28
33
  def self.debug(message)
29
34
  text = Rainbow(message).white
30
- info(text)
35
+ puts text if @verbose
31
36
  end
32
37
  end
@@ -1,4 +1,4 @@
1
- require "rainbow"
1
+ require_relative "logger"
2
2
 
3
3
  class NameFileFinder
4
4
  attr_reader :options, :project_path, :script_path, :config_path, :testname
@@ -33,10 +33,7 @@ class NameFileFinder
33
33
  # Find project filenames into directory <folder path>
34
34
  # COMPLEX MODE: main RB file is <start.rb>
35
35
  script_path = File.join(folder_path, "start.rb")
36
- unless File.exist? script_path
37
- warn Rainbow("[ERROR] Main script file not found! <#{script_path}>").bright.red
38
- exit 1
39
- end
36
+ raise Teuton::MainScriptNotFoundError, script_path unless File.exist? script_path
40
37
 
41
38
  @project_path = folder_path
42
39
  @script_path = script_path
@@ -66,12 +63,7 @@ class NameFileFinder
66
63
  def find_filenames_from_rb(script_path)
67
64
  # SIMPLE MODE: We use script_path as main RB file
68
65
  # This must be fullpath to DSL script file
69
- if File.extname(script_path) != ".rb"
70
- warn Rainbow("[ERROR] Main script file not found!").bright.red
71
- warn Rainbow("[ERROR] Not found <#{script_path}/start.rb>").white
72
- warn Rainbow("[ERROR] Not found <#{script_path}.rb>").white
73
- exit 1
74
- end
66
+ raise Teuton::MainScriptNotFoundError, script_path if File.extname(script_path) != ".rb"
75
67
 
76
68
  @project_path = File.dirname(script_path)
77
69
  @script_path = script_path
@@ -1,5 +1,5 @@
1
1
  module Teuton
2
- VERSION = "3.1.0".freeze
2
+ VERSION = "3.2.1".freeze
3
3
  APPNAME = "teuton".freeze
4
4
  GEMNAME = "teuton".freeze
5
5
  DOCKERNAME = "dvarrui/#{GEMNAME}".freeze
data/lib/teuton.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require_relative "teuton/utils/project"
2
- # require_relative "teuton/version"
2
+ require_relative "teuton/errors"
3
3
 
4
4
  module Teuton
5
5
  def self.create(path_to_new_dir)
@@ -36,15 +36,10 @@ module Teuton
36
36
  private_class_method def self.require_dsl_and_script(dslpath)
37
37
  # Load DSL file and then load script file
38
38
  require_relative dslpath
39
- begin
40
- mainscriptfile = Project.value[:script_path]
41
- require_relative mainscriptfile
42
- rescue => e
43
- warn Rainbow("[ERROR] #{e}").bright.red
44
- e.backtrace&.first(3)&.each do |line|
45
- warn Rainbow("[ERROR] #{line}").red
46
- end
47
- exit 1
48
- end
39
+
40
+ mainscriptfile = Project.value[:script_path]
41
+ raise MainScriptNotFoundError.new(mainscriptfile) unless File.exist?(mainscriptfile)
42
+
43
+ require_relative mainscriptfile
49
44
  end
50
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teuton
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Vargas Ruiz
@@ -252,6 +252,7 @@ files:
252
252
  - docs/more.md
253
253
  - docs/tutorial/es/nginx/README.md
254
254
  - lib/teuton.rb
255
+ - lib/teuton/case/action.rb
255
256
  - lib/teuton/case/builtin/main.rb
256
257
  - lib/teuton/case/builtin/package.rb
257
258
  - lib/teuton/case/builtin/service.rb
@@ -305,12 +306,15 @@ files:
305
306
  - lib/teuton/check/dsl/run.rb
306
307
  - lib/teuton/check/main.rb
307
308
  - lib/teuton/check/show.rb
308
- - lib/teuton/cli.rb
309
+ - lib/teuton/cli/app.rb
310
+ - lib/teuton/cli/run.rb
309
311
  - lib/teuton/deprecated/utils.rb
312
+ - lib/teuton/errors.rb
310
313
  - lib/teuton/files/config.yaml
311
314
  - lib/teuton/files/start.rb
312
315
  - lib/teuton/files/template/case.html
313
316
  - lib/teuton/files/template/resume.html
317
+ - lib/teuton/readme/action.rb
314
318
  - lib/teuton/readme/dsl/all.rb
315
319
  - lib/teuton/readme/dsl/expect.rb
316
320
  - lib/teuton/readme/dsl/getset.rb
data/lib/teuton/cli.rb DELETED
@@ -1,120 +0,0 @@
1
- require "thor"
2
- require_relative "version"
3
- require_relative "../teuton"
4
-
5
- class CLI < Thor
6
- map ["h", "-h", "--help"] => "help"
7
-
8
- map ["n", "-n", "--new"] => "new"
9
- desc "new DIRECTORY", "Create skeleton for a new project"
10
- long_desc <<-LONGDESC
11
- Create files for a new project.
12
- LONGDESC
13
- def new(projectpath)
14
- Teuton.create(projectpath)
15
- end
16
-
17
- map ["c", "-c", "--check"] => "check"
18
- option :onlyconfig, type: :boolean
19
- option :color, type: :boolean
20
- option :cname, type: :string
21
- option :cpath, type: :string
22
- desc "check [OPTIONS] DIRECTORY", "Check test and config file content"
23
- long_desc <<~LONGDESC
24
-
25
- (1) teuton check PATH/TO/DIR , Check content of start.rb and config.yaml files.
26
-
27
- (2) teuton check PATH/TO/DIR --cname=demo , Check content of start.rb and demo.yaml files:
28
-
29
- (3) teuton check PATH/TO/DIR --onlyconfig , Only show config file recomendations
30
-
31
- (4) teuton check PATH/TO/DIR/foo.rb , Check content of foo.rb and foo.yaml files.
32
-
33
- (5) teuton check PATH/TO/DIR/foo.rb --cname=demo , Check content of foo.rb and demo.yaml files.
34
-
35
- LONGDESC
36
- def check(projectpath)
37
- Teuton.check(projectpath, options)
38
- end
39
-
40
- map ["co", "-co", "--config"] => "config"
41
- desc "config [OPTIONS] DIRECTORY", "Suggest configuration."
42
- long_desc <<~LONGDESC
43
- config DIRECTORY, "Suggest the content of the configuration file based on the test"
44
- LONGDESC
45
- def config(projectpath)
46
- # Check Test: suggest the content of the configuration file based on the test
47
- opt = {"onlyconfig" => true}
48
- Teuton.check(projectpath, opt)
49
- end
50
-
51
- map ["--readme"] => "readme"
52
- option :lang, type: :string
53
- desc "readme DIRECTORY", "Show README extracted from test contents"
54
- long_desc <<-LONGDESC
55
-
56
- (1) teuton readme foo
57
- , Create README.md from foo/start.rb.
58
-
59
- (2) teuton readme foo/demo.rb
60
- , Create README.md from foo/demo.rb.
61
- LONGDESC
62
-
63
- def readme(projectpath)
64
- # Create README from teuton test
65
- Teuton.readme(projectpath, options)
66
- end
67
-
68
- map ["--run", "run"] => "play"
69
- option :export, type: :string
70
- option :cname, type: :string
71
- option :cpath, type: :string
72
- option :case, type: :string
73
- option :color, type: :boolean
74
- option :quiet, type: :boolean
75
- desc "[run] [OPTIONS] DIRECTORY", "Run test from directory"
76
- long_desc <<-LONGDESC
77
- This function execute challenge from specified directory.
78
- By default, show progress on the screen.
79
-
80
- Let's see others options:
81
-
82
- (1) teuton foo, run challenge from foo/start.rb with foo/config.yaml config file.
83
-
84
- (2) teuton run foo, same as (1).
85
-
86
- (3) teuton run --export=json foo, run challenge and export using json format.
87
- Others output formats availables are: txt, html, yaml, json and colored_text.
88
-
89
- (4) teuton run --cname=demo foo, run challenge from foo/start.rb with foo/demo.yaml config file.
90
-
91
- (5) teuton foo/demo.rb, Run challenge from foo/demo.rb with foo/demo.yaml config file.
92
-
93
- LONGDESC
94
- def play(filepath)
95
- Teuton.run(filepath, options)
96
- end
97
-
98
- map ["v", "-v", "--version"] => "version"
99
- desc "version", "Show the program version"
100
- def version
101
- puts "#{Teuton::APPNAME} version #{Teuton::VERSION}"
102
- end
103
-
104
- ##
105
- # These inputs are equivalents:
106
- # * teuton dir/foo
107
- # * teuton run dir/foo
108
- def method_missing(method, *_args, &_block)
109
- play(method.to_s)
110
- end
111
-
112
- def respond_to_missing?(method_name, include_private = false)
113
- # Respond to missing methods name
114
- super
115
- end
116
-
117
- def self.exit_on_failure?
118
- true
119
- end
120
- end