omnitest 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitmodules +0 -0
  4. data/.groc.json +7 -0
  5. data/.rspec +6 -0
  6. data/.rubocop.yml +5 -0
  7. data/.rubocop_todo.yml +47 -0
  8. data/.travis.yml +12 -0
  9. data/.yardopts +3 -0
  10. data/Gemfile +26 -0
  11. data/README.md +341 -0
  12. data/Rakefile +33 -0
  13. data/appveyor.yml +9 -0
  14. data/bin/omnidoc +5 -0
  15. data/bin/omnitask +5 -0
  16. data/bin/omnitest +5 -0
  17. data/bower.json +21 -0
  18. data/doc-src/index.md.tt +341 -0
  19. data/doc-src/project_sets.md.tt +31 -0
  20. data/doc-src/usage/crosstask.md.tt +86 -0
  21. data/doc-src/usage/omnitest.md.tt +87 -0
  22. data/features/bootstrapping.feature +25 -0
  23. data/features/cloning.feature +32 -0
  24. data/features/fixtures/configs/omnitest_sample.yaml +11 -0
  25. data/features/fixtures/configs/skeptic_empty.yaml +12 -0
  26. data/features/fixtures/configs/skeptic_hello_world.yaml +10 -0
  27. data/features/show.feature +38 -0
  28. data/features/states.feature +40 -0
  29. data/features/step_definitions/sdk_steps.rb +22 -0
  30. data/features/support/env.rb +9 -0
  31. data/lib/omnitest.rb +211 -0
  32. data/lib/omnitest/cli.rb +297 -0
  33. data/lib/omnitest/command.rb +103 -0
  34. data/lib/omnitest/command/generate.rb +29 -0
  35. data/lib/omnitest/command/generators/code2doc.rb +79 -0
  36. data/lib/omnitest/command/generators/dashboard.rb +148 -0
  37. data/lib/omnitest/command/generators/documentation.rb +119 -0
  38. data/lib/omnitest/command/list.rb +62 -0
  39. data/lib/omnitest/command/project_action.rb +26 -0
  40. data/lib/omnitest/command/scenario_action.rb +20 -0
  41. data/lib/omnitest/command/show.rb +148 -0
  42. data/lib/omnitest/command/task.rb +27 -0
  43. data/lib/omnitest/command/test.rb +41 -0
  44. data/lib/omnitest/configuration.rb +53 -0
  45. data/lib/omnitest/documentation_generator.rb +68 -0
  46. data/lib/omnitest/project.rb +100 -0
  47. data/lib/omnitest/project_logger.rb +273 -0
  48. data/lib/omnitest/project_set.rb +47 -0
  49. data/lib/omnitest/reporters.rb +27 -0
  50. data/lib/omnitest/reporters/hash_reporter.rb +32 -0
  51. data/lib/omnitest/reporters/json_reporter.rb +12 -0
  52. data/lib/omnitest/reporters/markdown_reporter.rb +26 -0
  53. data/lib/omnitest/reporters/yaml_reporter.rb +12 -0
  54. data/lib/omnitest/run_action.rb +44 -0
  55. data/lib/omnitest/version.rb +3 -0
  56. data/lib/omnitest/workflow.rb +5 -0
  57. data/mkdocs.yml +8 -0
  58. data/omnitest.gemspec +39 -0
  59. data/omnitest.yaml +5 -0
  60. data/resources/assets/angular/angular.min.js +217 -0
  61. data/resources/assets/angular/angular.min.js.map +8 -0
  62. data/resources/assets/angular/json-formatter.min.css +6 -0
  63. data/resources/assets/angular/json-formatter.min.js +7 -0
  64. data/resources/assets/angular/ng-table.map +1 -0
  65. data/resources/assets/angular/ng-table.min.css +3 -0
  66. data/resources/assets/angular/ng-table.min.js +3 -0
  67. data/resources/assets/angular/ui-bootstrap-tpls.min.js +10 -0
  68. data/resources/assets/bootstrap/bootstrap.min.css +9 -0
  69. data/resources/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  70. data/resources/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  71. data/resources/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  72. data/resources/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  73. data/resources/assets/pygments/autumn.css +58 -0
  74. data/resources/assets/pygments/borland.css +46 -0
  75. data/resources/assets/pygments/bw.css +34 -0
  76. data/resources/assets/pygments/colorful.css +61 -0
  77. data/resources/assets/pygments/default.css +62 -0
  78. data/resources/assets/pygments/emacs.css +61 -0
  79. data/resources/assets/pygments/friendly.css +61 -0
  80. data/resources/assets/pygments/fruity.css +69 -0
  81. data/resources/assets/pygments/github.css +61 -0
  82. data/resources/assets/pygments/manni.css +61 -0
  83. data/resources/assets/pygments/monokai.css +64 -0
  84. data/resources/assets/pygments/murphy.css +61 -0
  85. data/resources/assets/pygments/native.css +69 -0
  86. data/resources/assets/pygments/pastie.css +60 -0
  87. data/resources/assets/pygments/perldoc.css +58 -0
  88. data/resources/assets/pygments/tango.css +69 -0
  89. data/resources/assets/pygments/trac.css +59 -0
  90. data/resources/assets/pygments/vim.css +69 -0
  91. data/resources/assets/pygments/vs.css +33 -0
  92. data/resources/assets/pygments/zenburn.css +1 -0
  93. data/resources/assets/style.css +56 -0
  94. data/resources/code_sample.tt +2 -0
  95. data/resources/generators/dashboard/files/dashboard.html.tt +51 -0
  96. data/resources/generators/dashboard/files/dashboard.js +26 -0
  97. data/resources/generators/dashboard/templates/_test_report.html.haml +91 -0
  98. data/resources/generators/todo/templates/todo.md.tt +6 -0
  99. data/resources/generators/todo/todo_template.rb +1 -0
  100. data/samples/.gitignore +2 -0
  101. data/samples/_markdown.md +5 -0
  102. data/samples/bootstrap.sh +2 -0
  103. data/samples/clone.sh +2 -0
  104. data/samples/code2doc.sh +5 -0
  105. data/samples/default_bootstrap.rb +7 -0
  106. data/samples/detect.sh +2 -0
  107. data/samples/exec.sh +2 -0
  108. data/samples/omnitest.yaml +24 -0
  109. data/samples/omnitest_simple.yaml +8 -0
  110. data/samples/scripts/bootstrap +3 -0
  111. data/samples/show.sh +4 -0
  112. data/samples/skeptic.yaml +13 -0
  113. data/samples/skeptic_simple.yaml +9 -0
  114. data/samples/test.sh +2 -0
  115. data/samples/tests/omnitest/validators.rb +23 -0
  116. data/samples/verify.sh +3 -0
  117. data/scripts/bootstrap.ps1 +7 -0
  118. data/scripts/run_script.sh +4 -0
  119. data/skeptic.yaml +26 -0
  120. data/spec/fabricators/project_fabricator.rb +19 -0
  121. data/spec/fabricators/scenario_fabricator.rb +6 -0
  122. data/spec/fabricators/test_manifest_fabricator.rb +41 -0
  123. data/spec/fabricators/validator_fabricator.rb +12 -0
  124. data/spec/fixtures/factorial.py +18 -0
  125. data/spec/fixtures/omnitest.yaml +11 -0
  126. data/spec/fixtures/skeptic.yaml +16 -0
  127. data/spec/fixtures/src-doc/_scenario.md.erb +1 -0
  128. data/spec/fixtures/src-doc/quine.md.erb +20 -0
  129. data/spec/omnitest/cli_spec.rb +38 -0
  130. data/spec/omnitest/configuration_spec.rb +25 -0
  131. data/spec/omnitest/documentation_generator_spec.rb +59 -0
  132. data/spec/omnitest/file_finder_spec.rb +21 -0
  133. data/spec/omnitest/project_spec.rb +65 -0
  134. data/spec/omnitest_spec.rb +13 -0
  135. data/spec/spec_helper.rb +32 -0
  136. data/spec/thor_spy.rb +66 -0
  137. data/tests/omnitest/bootstrap_validations.rb +7 -0
  138. data/tests/omnitest/show_validations.rb +22 -0
  139. data/yard_macros.rb +25 -0
  140. metadata +470 -0
@@ -0,0 +1,297 @@
1
+ require 'thor'
2
+
3
+ require 'omnitest'
4
+ require 'omnitest/command'
5
+ require 'omnitest/command/generate'
6
+ require 'omnitest/psychic/cli'
7
+ require 'omnitest/skeptic/cli'
8
+
9
+ module Omnitest
10
+ module Command
11
+ class Generate
12
+ autoload :Dashboard, 'omnitest/command/generators/dashboard'
13
+ autoload :Code2Doc, 'omnitest/command/generators/code2doc'
14
+ autoload :Documentation, 'omnitest/command/generators/documentation'
15
+ end
16
+ end
17
+
18
+ module CLI
19
+ class BaseCLI < Omnitest::Core::CLI
20
+ # The maximum number of concurrent instances that can run--which is a bit
21
+ # high
22
+ MAX_CONCURRENCY = 9999
23
+
24
+ # Constructs a new instance.
25
+ def initialize(*args)
26
+ super
27
+ $stdout.sync = true
28
+ end
29
+
30
+ protected
31
+
32
+ # Convert a Thor Option object to a hash so we can copy options from
33
+ # other commands.
34
+ #
35
+ # @param [Thor::Option] an option object
36
+ # @return [Hash] the options as a hash
37
+ # @api private
38
+ def self.option_to_hash(option)
39
+ [
40
+ :banner, :default, :description, :enum, :name,
41
+ :required, :type, :aliases, :group, :hide, :lazy_default
42
+ ].each_with_object({}) do | option_type, options_hash |
43
+ options_hash[option_type] = option.send(option_type)
44
+ end
45
+ end
46
+
47
+ # Ensure the any failing commands exit non-zero.
48
+ #
49
+ # @return [true] you die always on failure
50
+ # @api private
51
+ def self.exit_on_failure?
52
+ true
53
+ end
54
+
55
+ # @return [Logger] the common logger
56
+ # @api private
57
+ def logger
58
+ Omnitest.logger
59
+ end
60
+
61
+ # Update and finalize options for logging, concurrency, and other concerns.
62
+ #
63
+ # @api private
64
+ def update_config!
65
+ Omnitest.update_config!(@options)
66
+ end
67
+
68
+ # If auto_init option is active, invoke the init generator.
69
+ #
70
+ # @api private
71
+ def ensure_initialized
72
+ end
73
+
74
+ def duration(total)
75
+ total = 0 if total.nil?
76
+ minutes = (total / 60).to_i
77
+ seconds = (total - (minutes * 60))
78
+ format('(%dm%.2fs)', minutes, seconds)
79
+ end
80
+ end
81
+
82
+ class CrosstaskCLI < BaseCLI
83
+ desc 'clone [PROJECT|REGEXP|all]', 'Fetches the projects from version control'
84
+ method_option :concurrency,
85
+ aliases: '-c',
86
+ type: :numeric,
87
+ lazy_default: MAX_CONCURRENCY,
88
+ desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
89
+ Run the task against all matching instances concurrently. Only N
90
+ instances will run at the same time if a number is given.
91
+ DESC
92
+ method_option :log_level,
93
+ aliases: '-l',
94
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
95
+ method_option :file,
96
+ aliases: '-f',
97
+ desc: 'The Omnitest project set file',
98
+ default: 'omnitest.yaml'
99
+ def clone(*args)
100
+ update_config!
101
+ Omnitest.clone(*args)
102
+ end
103
+
104
+ desc 'workflow <name> [PROJECT|REGEXP|all]', 'Run the workflow against each project'
105
+ method_option :concurrency,
106
+ aliases: '-c',
107
+ type: :numeric,
108
+ lazy_default: MAX_CONCURRENCY,
109
+ desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
110
+ Run the task against all matching instances concurrently. Only N
111
+ instances will run at the same time if a number is given.
112
+ DESC
113
+ method_option :log_level,
114
+ aliases: '-l',
115
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
116
+ method_option :file,
117
+ aliases: '-f',
118
+ desc: 'The Omnitest project set file',
119
+ default: 'omnitest.yaml'
120
+ method_option :travis, type: :boolean, desc: "Enable/disable delegation to travis-build, if it's available"
121
+ def workflow(name, project_regex = 'all')
122
+ abort 'A workflow name is required' if args.empty?
123
+ update_config!
124
+ Omnitest.workflow(project_regex, name)
125
+ end
126
+
127
+ Psychic::CLI.commands.each do | action, command |
128
+ next if action == 'workflow' # We've customized it a bit
129
+
130
+ enhanced_banner = "#{action} [PROJECT|REGEXP|all]"
131
+ desc enhanced_banner, command.description
132
+ long_desc command.long_description
133
+ method_option :file,
134
+ aliases: '-f',
135
+ desc: 'The Omnitest project set file',
136
+ default: 'omnitest.yaml'
137
+ method_option :travis, type: :boolean, desc: "Enable/disable delegation to travis-build, if it's available"
138
+ command.options.select do | name, option |
139
+ method_option name, option_to_hash(option)
140
+ end
141
+ define_method(action) do |*args|
142
+ update_config!
143
+ Omnitest.public_send(action, *args)
144
+ end
145
+ end
146
+ end
147
+
148
+ class CrossdocCLI < BaseCLI
149
+ register Command::Generate::Dashboard, 'dashboard', 'dashboard', 'Create a report dashboard'
150
+ tasks['dashboard'].options = Command::Generate::Dashboard.class_options
151
+
152
+ register Command::Generate::Code2Doc, 'code2doc', 'code2doc [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
153
+ 'Generates documenation from sample code for one or more scenarios'
154
+ tasks['code2doc'].options = Command::Generate::Code2Doc.class_options
155
+
156
+ register Command::Generate::Documentation, 'generate', 'generate', 'Generates documentation, reports or other files from templates'
157
+ tasks['generate'].options = Command::Generate::Documentation.class_options
158
+ tasks['generate'].long_description = <<-eos
159
+ Generates documentation, reports or other files from templates. The templates may use Thor actions and Padrino helpers
160
+ in order to inject data from Omnitest test runs, code samples, or other sources.
161
+
162
+ Available templates: #{Command::Generate::Documentation.generator_names.join(', ')}
163
+ You may also run it against a directory containing a template with the --source option.
164
+ eos
165
+ end
166
+
167
+ class OmnitestCLI < CrosstaskCLI # rubocop:disable ClassLength
168
+ def self.filter_options
169
+ method_option :failed,
170
+ type: :boolean,
171
+ desc: 'Only list tests that failed / passed'
172
+ method_option :skipped,
173
+ type: :boolean,
174
+ desc: 'Only list tests that were skipped / executed'
175
+ method_option :samples,
176
+ type: :boolean,
177
+ desc: 'Only list tests that have sample code / do not have sample code'
178
+ end
179
+
180
+ Skeptic::CLI.commands.each do | action, command |
181
+ enhanced_banner = "#{action} [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]"
182
+ desc enhanced_banner, command.description
183
+ long_desc command.long_description
184
+ method_option :file,
185
+ aliases: '-f',
186
+ desc: 'The Omnitest project set file',
187
+ default: 'omnitest.yaml'
188
+ command.options.select do | name, option |
189
+ method_option name, option_to_hash(option)
190
+ end
191
+ define_method action do |*args|
192
+ update_config!
193
+ Omnitest.public_send(action, *args)
194
+ end
195
+ end
196
+
197
+ desc 'list [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]', 'Lists one or more scenarios'
198
+ method_option :log_level,
199
+ aliases: '-l',
200
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
201
+ method_option :format,
202
+ desc: 'List output format',
203
+ enum: %w(text markdown json yaml),
204
+ default: 'text'
205
+ method_option :file,
206
+ aliases: '-f',
207
+ desc: 'The Omnitest project set file',
208
+ default: 'omnitest.yaml'
209
+ method_option :skeptic,
210
+ aliases: '-s',
211
+ desc: 'The Skeptic test manifest file',
212
+ default: 'skeptic.yaml'
213
+ method_option :test_dir,
214
+ aliases: '-t',
215
+ desc: 'The Omnitest test directory',
216
+ default: 'tests/omnitest'
217
+ method_option :source,
218
+ desc: 'Display the path to source code in the list?',
219
+ type: :boolean
220
+ filter_options
221
+ def list(*args)
222
+ update_config!
223
+ perform('list', 'list', args, options)
224
+ end
225
+
226
+ desc 'show [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]', 'Show detailed status for one or more scenarios'
227
+ method_option :log_level,
228
+ aliases: '-l',
229
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
230
+ method_option :format,
231
+ desc: 'List output format',
232
+ enum: %w(text markdown json yaml),
233
+ default: 'text'
234
+ method_option :file,
235
+ aliases: '-f',
236
+ desc: 'The Omnitest project set file',
237
+ default: 'omnitest.yaml'
238
+ method_option :skeptic,
239
+ aliases: '-s',
240
+ desc: 'The Skeptic test manifest file',
241
+ default: 'skeptic.yaml'
242
+ method_option :source,
243
+ desc: 'Display the source code for the sample'
244
+ method_option :test_dir,
245
+ aliases: '-t',
246
+ desc: 'The Omnitest test directory',
247
+ default: 'tests/omnitest'
248
+ filter_options
249
+ def show(*args)
250
+ update_config!
251
+ perform('show', 'show', args, options)
252
+ end
253
+
254
+ desc 'test [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
255
+ 'Test (clone, bootstrap, exec, and verify) one or more scenarios'
256
+ long_desc <<-DESC
257
+ The scenario states are in order: cloned, bootstrapped, executed, verified.
258
+ Test changes the state of one or more scenarios executes
259
+ the actions for each state up to verify.
260
+ DESC
261
+ method_option :concurrency,
262
+ aliases: '-c',
263
+ type: :numeric,
264
+ lazy_default: MAX_CONCURRENCY,
265
+ desc: <<-DESC.gsub(/^\s+/, '').gsub(/\n/, ' ')
266
+ Run a test against all matching instances concurrently. Only N
267
+ instances will run at the same time if a number is given.
268
+ DESC
269
+ method_option :log_level,
270
+ aliases: '-l',
271
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
272
+ method_option :file,
273
+ aliases: '-f',
274
+ desc: 'The Omnitest project set file',
275
+ default: 'omnitest.yaml'
276
+ method_option :skeptic,
277
+ aliases: '-s',
278
+ desc: 'The Skeptic test manifest file',
279
+ default: 'skeptic.yaml'
280
+ method_option :test_dir,
281
+ aliases: '-t',
282
+ desc: 'The Omnitest test directory',
283
+ default: 'tests/omnitest'
284
+ def test(*args)
285
+ update_config!
286
+ action_options = options.dup
287
+ perform('test', 'test', args, action_options)
288
+ end
289
+
290
+ desc 'version', "Print Omnitest's version information"
291
+ def version
292
+ puts "Omnitest version #{Omnitest::VERSION}"
293
+ end
294
+ map %w(-v --version) => :version
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,103 @@
1
+ require 'thread'
2
+ require 'English'
3
+
4
+ module Omnitest
5
+ module Command
6
+ class Base # rubocop:disable ClassLength
7
+ include Core::DefaultLogger
8
+ include Omnitest::Core::Logging
9
+ include Omnitest::Core::FileSystem
10
+
11
+ # Contstructs a new Command object.
12
+ #
13
+ # @param cmd_args [Array] remainder of the arguments from processed ARGV
14
+ # @param cmd_options [Hash] hash of Thor options
15
+ # @param options [Hash] configuration options
16
+ # @option options [String] :action action to take, usually corresponding
17
+ # to the subcommand name (default: `nil`)
18
+ # @option options [proc] :help a callable that displays help for the
19
+ # command
20
+ # @option options [Config] :test_dir a Config object (default: `nil`)
21
+ # @option options [Loader] :loader a Loader object (default: `nil`)
22
+ # @option options [String] :shell a Thor shell object
23
+ def initialize(action, cmd_args, cmd_options, options = {})
24
+ @action = action
25
+ @args = cmd_args
26
+ @options = cmd_options
27
+ @help = options.fetch(:help, -> { 'No help provided' })
28
+ @project_set_file = options.fetch('file', nil)
29
+ @skeptic_file = options.fetch('skeptic', nil)
30
+ @loader = options.fetch(:loader, nil)
31
+ @shell = options.fetch(:shell)
32
+ @queue = Queue.new
33
+ end
34
+
35
+ private
36
+
37
+ # @return [Array] remainder of the arguments from processed ARGV
38
+ # @api private
39
+ attr_reader :args
40
+
41
+ # @return [Hash] hash of Thor options
42
+ # @api private
43
+ attr_reader :options
44
+
45
+ # @return [proc] a callable that displays help for the command
46
+ # @api private
47
+ attr_reader :help
48
+
49
+ # @return [Thor::Shell] a Thor shell object
50
+ # @api private
51
+ attr_reader :shell
52
+
53
+ # @return [String] the action to perform
54
+ # @api private
55
+ attr_reader :action
56
+
57
+ def setup
58
+ Omnitest.setup
59
+ end
60
+
61
+ def project_set_file
62
+ @project_set_file ||= Omnitest.configuration.file
63
+ @project_set_file
64
+ end
65
+
66
+ # Emit an error message, display contextual help and then exit with a
67
+ # non-zero exit code.
68
+ #
69
+ # **Note** This method calls exit and will not return.
70
+ #
71
+ # @param msg [String] error message
72
+ # @api private
73
+ def die(msg)
74
+ logger.error "\n#{msg}\n\n"
75
+ help.call
76
+ exit 1
77
+ end
78
+
79
+ def select_projects(project_regexp = 'all', options = {})
80
+ projects = Omnitest.filter_projects(project_regexp, options)
81
+ die "No projects matching regex `#{project_regexp}', known projects: #{Omnitest.projects.map(&:name)}" if projects.empty?
82
+ projects
83
+ end
84
+
85
+ # Return an array on scenarios whos name matches the regular expression,
86
+ # the full instance name, or the `"all"` literal.
87
+ #
88
+ # @param arg [String] an instance name, a regular expression, the literal
89
+ # `"all"`, or `nil`
90
+ # @return [Array<Instance>] an array of scenarios
91
+ # @api private
92
+ def parse_subcommand(project_regexp = 'all', scenario_regexp = 'all', options = {})
93
+ scenarios = Omnitest.scenarios(project_regexp, scenario_regexp, options)
94
+ die "No scenarios for regex `#{scenario_regexp}', try running `omnitest list'" if scenarios.empty?
95
+ scenarios
96
+ rescue RegexpError => e
97
+ die 'Invalid Ruby regular expression, ' \
98
+ 'you may need to single quote the argument. ' \
99
+ "Please try again or consult http://rubular.com/ (#{e.message})"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,29 @@
1
+ module Omnitest
2
+ module Command
3
+ class Generate < Thor
4
+ namespace :generate
5
+
6
+ autoload :Dashboard, 'omnitest/command/generators/dashboard'
7
+ register Dashboard, 'dashboard', 'dashboard', 'Create a report dashboard'
8
+ tasks['dashboard'].options = Dashboard.class_options
9
+
10
+ autoload :Code2Doc, 'omnitest/command/generators/code2doc'
11
+ register Code2Doc, 'code2doc', 'code2doc [PROJECT|REGEXP|all] [SCENARIO|REGEXP|all]',
12
+ 'Generates documenation from sample code for one or more scenarios'
13
+ tasks['code2doc'].options = Command::Generate::Code2Doc.class_options
14
+
15
+ autoload :Documentation, 'omnitest/command/generators/documentation'
16
+ register Documentation, 'generate', 'generate', 'Generates documentation, reports or other files from templates'
17
+ tasks['generate'].options = Documentation.class_options
18
+ tasks['generate'].long_description = <<-eos
19
+ Generates documentation, reports or other files from templates. The templates may use Thor actions and Padrino helpers
20
+ in order to inject data from Omnitest test runs, code samples, or other sources.
21
+
22
+ Available templates: #{Command::Generate::Documentation.generator_names.join(', ')}
23
+ You may also run it against a directory containing a template with the --source option.
24
+ eos
25
+
26
+ # FIXME: Help shows unwanted usage, e.g. "omnitest omnitest:command:report:code2_doc"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,79 @@
1
+ require 'json'
2
+ require 'omnitest/reporters'
3
+ require 'omnitest/documentation_generator'
4
+
5
+ module Omnitest
6
+ module Command
7
+ class Generate
8
+ class Code2Doc < Thor::Group
9
+ include Core::DefaultLogger
10
+ include Omnitest::Core::Logging
11
+ include Thor::Actions
12
+ include Omnitest::Core::FileSystem
13
+ include Omnitest::Core::Util::String
14
+
15
+ class_option :log_level,
16
+ aliases: '-l',
17
+ desc: 'Set the log level (debug, info, warn, error, fatal)'
18
+ class_option :file,
19
+ aliases: '-f',
20
+ desc: 'The Omnitest project set file',
21
+ default: 'omnitest.yaml'
22
+ class_option :skeptic,
23
+ aliases: '-s',
24
+ desc: 'The Skeptic test manifest file',
25
+ default: 'skeptic.yaml'
26
+ class_option :format,
27
+ aliases: '-f',
28
+ enum: %w(md rst),
29
+ default: 'md',
30
+ desc: 'Target documentation format'
31
+ class_option :target_dir,
32
+ aliases: '-d',
33
+ default: 'docs/',
34
+ desc: 'The target directory where documentation for generated documentation.'
35
+ class_option :source_files, type: :array
36
+
37
+ class_option :destination, default: 'docs/'
38
+
39
+ argument :project_regexp, default: 'all'
40
+ argument :scenario_regexp, default: 'all'
41
+
42
+ def setup
43
+ Omnitest.update_config!(options)
44
+ Omnitest.setup
45
+ @scenarios = Omnitest.scenarios(project_regexp, scenario_regexp, options)
46
+ abort "No scenarios for regex `#{scenario_regexp}', try running `omnitest list'" if @scenarios.empty?
47
+ end
48
+
49
+ def set_destination_root
50
+ self.destination_root = options[:destination]
51
+ end
52
+
53
+ def source_files
54
+ @source_files = @scenarios.map do |scenario|
55
+ [scenario.slug, scenario.absolute_source_file]
56
+ end
57
+ end
58
+
59
+ def code2doc
60
+ @source_files.each do |slug, source_file|
61
+ if source_file.nil?
62
+ warn "No code sample available for #{slug}, no documentation will be generated."
63
+ next
64
+ end
65
+
66
+ target_file_name = slug + ".#{options[:format]}"
67
+
68
+ begin
69
+ doc = Omnitest::DocumentationGenerator.new.code2doc(source_file)
70
+ create_file(target_file_name, doc)
71
+ rescue Omnitest::Psychic::Code2Doc::CommentStyles::UnknownStyleError
72
+ warn "Could not generated documentation for #{source_file}, because the language couldn't be detected."
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end