polytrix 0.1.0.pre → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +7 -2
  4. data/.travis.yml +2 -1
  5. data/Gemfile +1 -0
  6. data/README.md +190 -98
  7. data/Rakefile +8 -6
  8. data/bin/polytrix +2 -1
  9. data/docs/samples/code2doc/java/HelloWorld.md +4 -0
  10. data/docs/samples/code2doc/java/Quine.md +2 -0
  11. data/docs/samples/code2doc/python/hello_world.md +2 -0
  12. data/docs/samples/code2doc/python/quine.md +2 -0
  13. data/docs/samples/code2doc/ruby/hello_world.md +4 -0
  14. data/features/bootstrapping.feature +36 -0
  15. data/features/cloning.feature +34 -0
  16. data/features/execution.feature +2 -16
  17. data/features/fixtures/configs/empty.yml +12 -1
  18. data/features/fixtures/configs/hello_world.yml +11 -1
  19. data/features/fixtures/spec/polytrix_spec.rb +1 -4
  20. data/features/solo.feature +12 -0
  21. data/features/states.feature +40 -0
  22. data/features/step_definitions/sdk_steps.rb +11 -1
  23. data/features/support/env.rb +2 -1
  24. data/lib/polytrix/challenge.rb +211 -13
  25. data/lib/polytrix/challenge_result.rb +9 -0
  26. data/lib/polytrix/challenge_runner.rb +4 -11
  27. data/lib/polytrix/challenges.rb +16 -0
  28. data/lib/polytrix/cli/report.rb +0 -4
  29. data/lib/polytrix/cli.rb +229 -137
  30. data/lib/polytrix/color.rb +40 -0
  31. data/lib/polytrix/command/action.rb +26 -0
  32. data/lib/polytrix/command/list.rb +53 -0
  33. data/lib/polytrix/command/rundoc.rb +27 -0
  34. data/lib/polytrix/command/test.rb +24 -0
  35. data/lib/polytrix/command.rb +209 -0
  36. data/lib/polytrix/configuration.rb +30 -40
  37. data/lib/polytrix/core/file_system_helper.rb +2 -5
  38. data/lib/polytrix/core/hashie.rb +14 -0
  39. data/lib/polytrix/core/implementor.rb +52 -12
  40. data/lib/polytrix/core/manifest_section.rb +4 -0
  41. data/lib/polytrix/core/string_helpers.rb +15 -0
  42. data/lib/polytrix/documentation/helpers/code_helper.rb +3 -1
  43. data/lib/polytrix/error.rb +209 -0
  44. data/lib/polytrix/logger.rb +365 -8
  45. data/lib/polytrix/logging.rb +34 -0
  46. data/lib/polytrix/manifest.rb +40 -26
  47. data/lib/polytrix/result.rb +1 -0
  48. data/lib/polytrix/rspec.rb +7 -5
  49. data/lib/polytrix/runners/buff_shellout_executor.rb +19 -0
  50. data/lib/polytrix/runners/executor.rb +32 -0
  51. data/lib/polytrix/runners/mixlib_shellout_executor.rb +83 -0
  52. data/lib/polytrix/state_file.rb +60 -0
  53. data/lib/polytrix/util.rb +155 -0
  54. data/lib/polytrix/validation.rb +1 -1
  55. data/lib/polytrix/validator.rb +9 -5
  56. data/lib/polytrix/version.rb +1 -1
  57. data/lib/polytrix.rb +55 -33
  58. data/polytrix.gemspec +4 -2
  59. data/polytrix.rb +0 -5
  60. data/{polytrix_tests.yml → polytrix.yml} +5 -0
  61. data/samples/default_bootstrap.rb +0 -7
  62. data/samples/polytrix.rb +0 -9
  63. data/samples/{polytrix_tests.yml → polytrix.yml} +11 -0
  64. data/samples/polytrix_cli.sh +1 -1
  65. data/spec/fabricators/implementor_fabricator.rb +20 -0
  66. data/spec/fabricators/manifest_fabricator.rb +4 -1
  67. data/spec/fixtures/{polytrix_tests.yml → polytrix.yml} +10 -0
  68. data/spec/polytrix/challenge_runner_spec.rb +3 -2
  69. data/spec/polytrix/challenge_spec.rb +5 -4
  70. data/spec/polytrix/cli_spec.rb +23 -26
  71. data/spec/polytrix/configuration_spec.rb +4 -43
  72. data/spec/polytrix/documentation/helpers/code_helper_spec.rb +1 -1
  73. data/spec/polytrix/documentation_generator_spec.rb +2 -0
  74. data/spec/polytrix/implementor_spec.rb +44 -2
  75. data/spec/polytrix/manifest_spec.rb +7 -4
  76. data/spec/polytrix_spec.rb +9 -11
  77. data/spec/thor_spy.rb +2 -0
  78. metadata +66 -16
  79. data/features/fixtures/spec/polytrix_merge.rb +0 -5
  80. data/features/reporting.feature +0 -140
  81. data/lib/polytrix/executor.rb +0 -89
  82. data/samples/sdks/custom/polytrix.yml +0 -2
data/lib/polytrix/cli.rb CHANGED
@@ -1,158 +1,250 @@
1
- require 'polytrix'
2
1
  require 'thor'
3
2
 
4
- module Polytrix
5
- module CLI
6
- autoload :Add, 'polytrix/cli/add'
7
- autoload :Report, 'polytrix/cli/report'
8
-
9
- class Base < Thor
10
- include Polytrix::Core::FileSystemHelper
11
-
12
- def self.config_options
13
- # I had trouble with class_option and subclasses...
14
- method_option :manifest, type: 'string', default: 'polytrix_tests.yml', desc: 'The Polytrix test manifest file'
15
- method_option :config, type: 'string', default: 'polytrix.rb', desc: 'The Polytrix config file'
16
- end
17
-
18
- def self.log_options
19
- method_option :quiet, type: :boolean, default: false, desc: 'Do not print log messages'
20
- end
21
-
22
- def self.doc_options
23
- method_option :target_dir, type: :string, default: 'docs'
24
- method_option :lang, enum: Polytrix::Documentation::CommentStyles::COMMENT_STYLES.keys, desc: 'Source language (auto-detected if not specified)'
25
- method_option :format, enum: %w(md rst), default: 'md'
26
- end
3
+ require 'polytrix'
4
+ require 'polytrix/command'
27
5
 
28
- def self.sdk_options
29
- method_option :sdk, type: 'string', desc: 'An implementor name or directory', default: '.'
6
+ module Polytrix
7
+ class CLI < Thor # rubocop:disable ClassLength
8
+ # Common module to load and invoke a CLI-implementation agnostic command.
9
+ module PerformCommand
10
+ # Perform a scenario subcommand.
11
+ #
12
+ # @param task [String] action to take, usually corresponding to the
13
+ # subcommand name
14
+ # @param command [String] command class to create and invoke]
15
+ # @param args [Array] remainder arguments from processed ARGV
16
+ # (default: `nil`)
17
+ # @param additional_options [Hash] additional configuration needed to
18
+ # set up the command class (default: `{}`)
19
+ def perform(task, command, args = nil, additional_options = {})
20
+ require "polytrix/command/#{command}"
21
+
22
+ command_options = {
23
+ action: task,
24
+ help: -> { help(task) },
25
+ test_dir: @test_dir,
26
+ shell: shell
27
+ }.merge(additional_options)
28
+
29
+ str_const = Thor::Util.camel_case(command)
30
+ klass = ::Polytrix::Command.const_get(str_const)
31
+ klass.new(args, options, command_options).call
32
+ rescue ArgumentError => e
33
+ abort e.message
30
34
  end
35
+ end
31
36
 
32
- protected
33
-
34
- def find_sdks(sdks)
35
- sdks.map do |sdk|
36
- implementor = Polytrix.implementors.find { |i| i.name == sdk }
37
- abort "SDK #{sdk} not found" if implementor.nil?
38
- implementor
39
- end
40
- end
37
+ include Logging
38
+ include PerformCommand
41
39
 
42
- def pick_implementor(sdk)
43
- Polytrix.implementors.find { |i| i.name == sdk } || Polytrix.configuration.implementor(sdk)
44
- end
40
+ # The maximum number of concurrent instances that can run--which is a bit
41
+ # high
42
+ MAX_CONCURRENCY = 9999
45
43
 
46
- def debug(msg)
47
- say("polytrix::debug: #{msg}", :cyan) if debugging?
48
- end
44
+ # Constructs a new instance.
45
+ def initialize(*args)
46
+ super
47
+ $stdout.sync = true
48
+ # Polytrix.logger = Polytrix.default_file_logger
49
+ end
49
50
 
50
- def debugging?
51
- !ENV['POLYTRIX_DEBUG'].nil?
52
- end
51
+ desc 'list [INSTANCE|REGEXP|all]', 'Lists one or more scenarios'
52
+ method_option :bare,
53
+ aliases: '-b',
54
+ type: :boolean,
55
+ desc: 'List the name of each scenario only, one per line'
56
+ method_option :log_level,
57
+ aliases: '-l',
58
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
59
+ method_option :manifest,
60
+ aliases: '-m',
61
+ desc: 'The Polytrix test manifest file location',
62
+ default: 'polytrix.yml'
63
+ method_option :test_dir,
64
+ aliases: '-t',
65
+ desc: 'The Polytrix test directory',
66
+ default: 'tests/polytrix'
67
+ method_option :solo,
68
+ desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
69
+ # , default: 'polytrix.yml'
70
+ method_option :solo_glob,
71
+ desc: 'The globbing pattern to find code samples in solo mode'
72
+ def list(*args)
73
+ update_config!
74
+ perform('list', 'list', args, options)
75
+ end
53
76
 
54
- def setup
55
- manifest_file = File.expand_path options[:manifest]
56
- config_file = File.expand_path options[:config]
57
- if File.exists? manifest_file
58
- debug "Loading manifest file: #{manifest_file}"
59
- Polytrix.configuration.test_manifest = manifest_file if File.exists? manifest_file
60
- end
61
- if File.exists? config_file
62
- debug "Loading Polytrix config: #{config_file}"
63
- require_relative config_file
64
- end
77
+ {
78
+ clone: "Change scenario state to cloned. " \
79
+ "Clone the code sample from git",
80
+ bootstrap: "Change scenario state to bootstraped. " \
81
+ "Running bootstrap scripts for the implementor",
82
+ exec: "Change instance state to executed. " \
83
+ "Execute the code sample and capture the results.",
84
+ verify: "Change instance state to verified. " \
85
+ "Assert that the captured results match the expectations for the scenario.",
86
+ destroy: "Change scenario state to destroyed. " \
87
+ "Delete all information for one or more scenarios"
88
+ }.each do |action, short_desc|
89
+ desc(
90
+ "#{action} [INSTANCE|REGEXP|all]",
91
+ short_desc
92
+ )
93
+ long_desc <<-DESC
94
+ The scenario states are in order: cloned, bootstrapped, executed, verified.
95
+ Change one or more scenarios from the current state to the #{action} state. Actions for all
96
+ intermediate states will be executed.
97
+ DESC
98
+ method_option :concurrency,
99
+ aliases: '-c',
100
+ type: :numeric,
101
+ lazy_default: MAX_CONCURRENCY,
102
+ desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
103
+ Run a #{action} against all matching instances concurrently. Only N
104
+ instances will run at the same time if a number is given.
105
+ DESC
106
+ method_option :log_level,
107
+ aliases: '-l',
108
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
109
+ method_option :manifest,
110
+ aliases: '-m',
111
+ desc: 'The Polytrix test manifest file location',
112
+ default: 'polytrix.yml'
113
+ method_option :test_dir,
114
+ aliases: '-t',
115
+ desc: 'The Polytrix test directory',
116
+ default: 'tests/polytrix'
117
+ method_option :solo,
118
+ desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
119
+ method_option :solo_glob,
120
+ desc: 'The globbing pattern to find code samples in solo mode'
121
+ define_method(action) do |*args|
122
+ update_config!
123
+ action_options = options.dup
124
+ action_options['on'] = :implementor if [:clone, :bootstrap].include? action
125
+ perform(action, 'action', args, action_options)
65
126
  end
66
127
  end
67
128
 
68
- class Main < Base
69
- include Polytrix::Documentation::Helpers::CodeHelper
70
-
71
- # register Add, :add, 'add', 'Add implementors or code samples'
72
- # register Report, :report, 'report', 'Generate test reports'
73
- desc 'add', 'Add implementors or code samples'
74
- subcommand 'add', Add
75
-
76
- desc 'report', 'Generate test reports'
77
- subcommand 'report', Report
78
-
79
- desc 'code2doc FILES', 'Converts annotated code to Markdown or reStructuredText'
80
- doc_options
81
- def code2doc(*files)
82
- if files.empty?
83
- help('code2doc')
84
- abort 'No FILES were specified, check usage above'
85
- end
86
-
87
- files.each do |file|
88
- target_file_name = File.basename(file, File.extname(file)) + ".#{options[:format]}"
89
- target_file = File.join(options[:target_dir], target_file_name)
90
- say_status 'polytrix:code2doc', "Converting #{file} to #{target_file}", !quiet?
91
- doc = Polytrix::DocumentationGenerator.new.code2doc(file, options[:lang])
92
- FileUtils.mkdir_p File.dirname(target_file)
93
- File.write(target_file, doc)
94
- end
95
- rescue Polytrix::Documentation::CommentStyles::UnknownStyleError => e
96
- abort "Unknown file extension: #{e.extension}, please use --lang to set the language manually"
97
- end
129
+ desc 'test [INSTANCE|REGEXP|all]',
130
+ 'Test (clone, bootstrap, exec, and verify) one or more scenarios'
131
+ long_desc <<-DESC
132
+ The scenario states are in order: cloned, bootstrapped, executed, verified.
133
+ Test changes the state of one or more scenarios executes
134
+ the actions for each state up to verify.
135
+ DESC
136
+ method_option :concurrency,
137
+ aliases: '-c',
138
+ type: :numeric,
139
+ lazy_default: MAX_CONCURRENCY,
140
+ desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
141
+ Run a test against all matching instances concurrently. Only N
142
+ instances will run at the same time if a number is given.
143
+ DESC
144
+ method_option :log_level,
145
+ aliases: '-l',
146
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
147
+ method_option :manifest,
148
+ aliases: '-m',
149
+ desc: 'The Polytrix test manifest file location',
150
+ default: 'polytrix.yml'
151
+ method_option :test_dir,
152
+ aliases: '-t',
153
+ desc: 'The Polytrix test directory',
154
+ default: 'tests/polytrix'
155
+ method_option :solo,
156
+ desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
157
+ # , default: 'polytrix.yml'
158
+ method_option :solo_glob,
159
+ desc: 'The globbing pattern to find code samples in solo mode'
160
+ def test(*args)
161
+ update_config!
162
+ action_options = options.dup
163
+ perform('test', 'test', args, action_options)
164
+ end
98
165
 
99
- desc 'exec', 'Executes code sample(s), using the SDK settings if provided'
100
- method_option :code2doc, type: :boolean, desc: 'Convert successfully executed code samples to documentation using the code2doc command'
101
- doc_options
102
- sdk_options
103
- config_options
104
- def exec(*files)
105
- setup
106
- if files.empty?
107
- help('exec')
108
- abort 'No FILES were specified, check usage above'
109
- end
110
-
111
- exec_options = {
112
- # default_implementor: pick_implementor(options[:sdk])
113
- }
114
-
115
- files.each do | file |
116
- say_status 'polytrix:exec', "Running #{file}..."
117
- results = Polytrix.exec(file, exec_options)
118
- display_results results
119
- code2doc(file) if options[:code2doc]
120
- end
121
- end
166
+ desc 'code2doc [INSTANCE|REGEXP|all]',
167
+ 'Generates documenation from sample code for one or more scenarios'
168
+ long_desc <<-DESC
169
+ This task will convert annotated sample code to documentation. Markdown or
170
+ reStructureText are supported.
171
+ DESC
172
+ method_option :log_level,
173
+ aliases: '-l',
174
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
175
+ method_option :manifest,
176
+ aliases: '-m',
177
+ desc: 'The Polytrix test manifest file location',
178
+ default: 'polytrix.yml'
179
+ method_option :solo,
180
+ desc: 'Enable solo mode - Polytrix will auto-configure a single implementor and its scenarios'
181
+ # , default: 'polytrix.yml'
182
+ method_option :solo_glob,
183
+ desc: 'The globbing pattern to find code samples in solo mode'
184
+ method_option :format,
185
+ aliases: '-f',
186
+ enum: %w(md rst),
187
+ default: 'md',
188
+ desc: 'Target documentation format'
189
+ method_option :target_dir,
190
+ aliases: '-d',
191
+ default: 'docs/',
192
+ desc: 'The target directory where documentation for generated documentation.'
193
+ def code2doc(*args)
194
+ update_config!
195
+ action_options = options.dup
196
+ perform('code2doc', 'action', args, action_options)
197
+ end
122
198
 
123
- desc 'bootstrap [SDKs]', 'Bootstraps the SDK by installing dependencies'
124
- config_options
125
- def bootstrap(*sdks)
126
- setup
127
- Polytrix.bootstrap(*sdks)
128
- rescue ArgumentError => e
129
- abort e.message
130
- end
199
+ desc 'version', "Print Polytrix's version information"
200
+ def version
201
+ puts "Polytrix version #{Polytrix::VERSION}"
202
+ end
203
+ map %w[-v --version] => :version
204
+
205
+ # register Polytrix::Generator::Init, "init",
206
+ # "init", "Adds some configuration to your cookbook so Polytrix can rock"
207
+ # long_desc <<-D, :for => "init"
208
+ # Init will add Test Polytrix support to an existing project for
209
+ # convergence integration testing. A default .polytrix.yml file (which is
210
+ # intended to be customized) is created in the project's root directory
211
+ # and one or more gems will be added to the project's Gemfile.
212
+ # D
213
+ # tasks["init"].options = Polytrix::Generator::Init.class_options
214
+
215
+ private
216
+
217
+ # Ensure the any failing commands exit non-zero.
218
+ #
219
+ # @return [true] you die always on failure
220
+ # @api private
221
+ def self.exit_on_failure?
222
+ true
223
+ end
131
224
 
132
- desc 'test [SDKs]', 'Runs and tests the code samples'
133
- method_option :rspec_options, format: 'string', desc: 'Extra options to pass to rspec'
134
- config_options
135
- def test(*sdks)
136
- setup
137
- implementors = find_sdks(sdks)
138
- Polytrix.configuration.rspec_options = options[:rspec_options]
139
- Polytrix.run_tests(implementors)
140
- end
225
+ # @return [Logger] the common logger
226
+ # @api private
227
+ def logger
228
+ Polytrix.logger
229
+ end
141
230
 
142
- protected
231
+ # Update and finalize options for logging, concurrency, and other concerns.
232
+ #
233
+ # @api private
234
+ def update_config!
235
+ end
143
236
 
144
- def quiet?
145
- options[:quiet] || false
146
- end
237
+ # If auto_init option is active, invoke the init generator.
238
+ #
239
+ # @api private
240
+ def ensure_initialized
241
+ end
147
242
 
148
- def display_results(challenge)
149
- short_name = challenge.name
150
- exit_code = challenge.result.execution_result.exitstatus
151
- color = exit_code == 0 ? :green : :red
152
- stderr = challenge.result.execution_result.stderr
153
- say_status "polytrix:exec[#{short_name}][stderr]", stderr, !quiet? unless stderr.empty?
154
- say_status "polytrix:exec[#{short_name}]", "Finished with exec code: #{challenge.result.execution_result.exitstatus}", color unless quiet?
155
- end
243
+ def duration(total)
244
+ total = 0 if total.nil?
245
+ minutes = (total / 60).to_i
246
+ seconds = (total - (minutes * 60))
247
+ format('(%dm%.2fs)', minutes, seconds)
156
248
  end
157
249
  end
158
250
  end
@@ -0,0 +1,40 @@
1
+ module Polytrix
2
+ module Color
3
+ ANSI = {
4
+ reset: 0, black: 30, red: 31, green: 32, yellow: 33,
5
+ blue: 34, magenta: 35, cyan: 36, white: 37,
6
+ bright_black: 90, bright_red: 91, bright_green: 92,
7
+ bright_yellow: 93, bright_blue: 94, bright_magenta: 95,
8
+ bright_cyan: 96, bright_white: 97
9
+ }.freeze
10
+
11
+ COLORS = %w[
12
+ cyan yellow green magenta blue bright_cyan bright_yellow
13
+ bright_green bright_magenta bright_blue
14
+ ].freeze
15
+
16
+ # Returns an ansi escaped string representing a color control sequence.
17
+ #
18
+ # @param name [Symbol] a valid color representation, taken from
19
+ # Polytrix::Color::ANSI
20
+ # @return [String] an ansi escaped string if the color is valid and an
21
+ # empty string otherwise
22
+ def self.escape(name)
23
+ return '' if name.nil?
24
+ return '' unless ANSI[name]
25
+ "\e[#{ANSI[name]}m"
26
+ end
27
+
28
+ # Returns a colorized ansi escaped string with the given color.
29
+ #
30
+ # @param str [String] a string to colorize
31
+ # @param name [Symbol] a valid color representation, taken from
32
+ # Polytrix::Color::ANSI
33
+ # @return [String] an ansi escaped string if the color is valid and an
34
+ # unescaped string otherwise
35
+ def self.colorize(str, name)
36
+ color = escape(name)
37
+ color.empty? ? str : "#{color}#{str}#{escape(:reset)}"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ require 'benchmark'
2
+
3
+ module Polytrix
4
+ module Command
5
+ class Action < Polytrix::Command::Base
6
+ include RunAction
7
+
8
+ # Invoke the command.
9
+ def call
10
+ banner "Starting Polytrix (v#{Polytrix::VERSION})"
11
+ elapsed = Benchmark.measure do
12
+ setup
13
+ tests = parse_subcommand(args.first)
14
+ implementors = tests.map(&:implementor).uniq
15
+ # Logging.mdc['command'] = action
16
+ if [:clone, :bootstrap].include? action # actions on implementors
17
+ run_action(action, implementors)
18
+ else # actions on tests
19
+ run_action(action, tests)
20
+ end
21
+ end
22
+ banner "Polytrix is finished. #{Util.duration(elapsed.real)}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,53 @@
1
+ module Polytrix
2
+ module Command
3
+ class List < Polytrix::Command::Base
4
+ def call
5
+ # Logging.mdc['command'] = 'list'
6
+
7
+ setup
8
+ tests = parse_subcommand(args.first)
9
+
10
+ table = [
11
+ [
12
+ colorize('Suite', :green), colorize('Scenario', :green),
13
+ colorize('Implementor', :green), colorize('Status', :green)
14
+ ]
15
+ ]
16
+ table += tests.map do | challenge |
17
+ [
18
+ color_pad(challenge.suite),
19
+ color_pad(challenge.name),
20
+ color_pad(challenge.implementor.name),
21
+ format_last_action(challenge)
22
+ ]
23
+ end
24
+ shell.print_table table
25
+ end
26
+
27
+ private
28
+
29
+ def print_table(*args)
30
+ shell.print_table(*args)
31
+ end
32
+
33
+ def colorize(string, *args)
34
+ shell.set_color(string, *args)
35
+ end
36
+
37
+ def color_pad(string)
38
+ string + colorize('', :white)
39
+ end
40
+
41
+ def format_last_action(challenge)
42
+ case challenge.last_action
43
+ when 'clone' then colorize('Cloned', :cyan)
44
+ when 'bootstrap' then colorize('Bootstrapped', :magenta)
45
+ when 'exec' then colorize('Executed', :blue)
46
+ when 'verify' then colorize("Verified (Level #{challenge.verification_level})", :yellow)
47
+ when nil then colorize('<Not Found>', :red)
48
+ else colorize("<Unknown (#{challenge.last_action})>", :white)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ module Polytrix
2
+ module Command
3
+ class RunDoc < Thor::Group
4
+ class_option :format,
5
+ aliases: '-f',
6
+ enum: %w(markdown rst),
7
+ default: 'markdown',
8
+ desc: 'The documentation input format'
9
+
10
+ def rundoc
11
+ files = args
12
+ # Logging.mdc['command'] = 'rundoc'
13
+ if files.empty?
14
+ # help('code2doc')
15
+ abort 'No FILES were specified, check usage above'
16
+ end
17
+
18
+ files.each do |file|
19
+ target_file_name = File.basename(file, File.extname(file)) + ".#{options[:format]}"
20
+ target_file = File.join(options[:target_dir], target_file_name)
21
+ say_status 'polytrix:code2doc', "Converting #{file} to #{target_file}"
22
+ Polytrix::DocumentationExecutor.new.execute file
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ require 'polytrix/command'
2
+
3
+ require 'benchmark'
4
+
5
+ module Polytrix
6
+ module Command
7
+ # Command to test one or more instances.
8
+ class Test < Polytrix::Command::Base
9
+ include RunAction
10
+
11
+ # Invoke the command.
12
+ def call
13
+ banner "Starting Polytrix (v#{Polytrix::VERSION})"
14
+ elapsed = Benchmark.measure do
15
+ setup
16
+ results = parse_subcommand(args.join('|'))
17
+
18
+ run_action(:test, results)
19
+ end
20
+ banner "Polytrix is finished. #{Util.duration(elapsed.real)}"
21
+ end
22
+ end
23
+ end
24
+ end