sleeping_king_studios-tasks 0.1.0.rc.0
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 +7 -0
- data/CHANGELOG.md +26 -0
- data/DEVELOPMENT.md +50 -0
- data/LICENSE +22 -0
- data/README.md +405 -0
- data/lib/sleeping_king_studios/tasks.rb +27 -0
- data/lib/sleeping_king_studios/tasks/apps.rb +49 -0
- data/lib/sleeping_king_studios/tasks/apps/app_configuration.rb +68 -0
- data/lib/sleeping_king_studios/tasks/apps/applications_task.rb +28 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle.rb +8 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/install_runner.rb +21 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/install_task.rb +39 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/update_runner.rb +21 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/update_task.rb +39 -0
- data/lib/sleeping_king_studios/tasks/apps/ci.rb +8 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/results_reporter.rb +69 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rspec_task.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rspec_wrapper.rb +42 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rubocop_task.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rubocop_wrapper.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/simplecov_task.rb +68 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/step_wrapper.rb +49 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/steps_runner.rb +37 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/steps_task.rb +92 -0
- data/lib/sleeping_king_studios/tasks/ci.rb +8 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_parser.rb +118 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_results.rb +191 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_runner.rb +53 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_task.rb +47 -0
- data/lib/sleeping_king_studios/tasks/ci/results_helpers.rb +44 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_each_results.rb +118 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_each_task.rb +156 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_results.rb +126 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_runner.rb +62 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_task.rb +71 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_results.rb +80 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_runner.rb +46 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_task.rb +44 -0
- data/lib/sleeping_king_studios/tasks/ci/simplecov_results.rb +62 -0
- data/lib/sleeping_king_studios/tasks/ci/simplecov_task.rb +25 -0
- data/lib/sleeping_king_studios/tasks/ci/steps_runner.rb +69 -0
- data/lib/sleeping_king_studios/tasks/ci/steps_task.rb +93 -0
- data/lib/sleeping_king_studios/tasks/configuration.rb +114 -0
- data/lib/sleeping_king_studios/tasks/file.rb +8 -0
- data/lib/sleeping_king_studios/tasks/file/new_task.rb +238 -0
- data/lib/sleeping_king_studios/tasks/process_runner.rb +70 -0
- data/lib/sleeping_king_studios/tasks/task.rb +95 -0
- data/lib/sleeping_king_studios/tasks/task_group.rb +37 -0
- data/lib/sleeping_king_studios/tasks/version.rb +58 -0
- metadata +271 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rspec_runner.rb
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/ci'
|
6
|
+
require 'sleeping_king_studios/tasks/process_runner'
|
7
|
+
|
8
|
+
module SleepingKingStudios::Tasks::Ci
|
9
|
+
# Service object to run RSpec as an external process with the specified
|
10
|
+
# parameters.
|
11
|
+
class RSpecRunner < SleepingKingStudios::Tasks::ProcessRunner
|
12
|
+
def call env: {}, files: [], options: [], report: true
|
13
|
+
report = 'tmp/ci/rspec.json' if report && !report.is_a?(String)
|
14
|
+
command =
|
15
|
+
build_command(
|
16
|
+
:env => env,
|
17
|
+
:files => files,
|
18
|
+
:options => options,
|
19
|
+
:report => report
|
20
|
+
) # end build_command
|
21
|
+
|
22
|
+
stream_process(command)
|
23
|
+
|
24
|
+
report ? load_report(:report => report) : {}
|
25
|
+
end # method call
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def base_command
|
30
|
+
'bundle exec rspec'
|
31
|
+
end # method base_command
|
32
|
+
|
33
|
+
def build_options files:, options:, report:, **_kwargs
|
34
|
+
options += ['--format=json', "--out=#{report}"] if report
|
35
|
+
|
36
|
+
super :files => files, :options => options
|
37
|
+
end # method build_options
|
38
|
+
|
39
|
+
def load_report report:
|
40
|
+
raw = File.read report
|
41
|
+
|
42
|
+
return {} if raw.empty?
|
43
|
+
|
44
|
+
json = JSON.parse raw
|
45
|
+
hsh = json['summary']
|
46
|
+
|
47
|
+
hsh['error_count'] = parse_errors(json['summary_line'])
|
48
|
+
|
49
|
+
hsh
|
50
|
+
rescue
|
51
|
+
{}
|
52
|
+
end # method load_report
|
53
|
+
|
54
|
+
def parse_errors summary
|
55
|
+
return 0 unless summary && !summary.empty?
|
56
|
+
|
57
|
+
match = summary.match(/(?<digits>\d+) error/)
|
58
|
+
|
59
|
+
match ? match[:digits].to_i : 0
|
60
|
+
end # method parse_errors
|
61
|
+
end # class
|
62
|
+
end # module
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rspec_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/ci/rspec_results'
|
5
|
+
require 'sleeping_king_studios/tasks/ci/rspec_runner'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Ci
|
8
|
+
# Defines a Thor task for running the full RSpec test suite.
|
9
|
+
class RSpecTask < SleepingKingStudios::Tasks::Task
|
10
|
+
def self.description
|
11
|
+
'Runs the RSpec test suite.'
|
12
|
+
end # class method description
|
13
|
+
|
14
|
+
def self.task_name
|
15
|
+
'rspec'
|
16
|
+
end # class method task_name
|
17
|
+
|
18
|
+
option :coverage,
|
19
|
+
:type => :boolean,
|
20
|
+
:desc => 'Enable or disable coverage with SimpleCov, if available.'
|
21
|
+
option :gemfile,
|
22
|
+
:type => :string,
|
23
|
+
:desc => 'The Gemfile used to run the specs.',
|
24
|
+
:default => ENV['BUNDLE_GEMFILE']
|
25
|
+
option :quiet,
|
26
|
+
:aliases => '-q',
|
27
|
+
:type => :boolean,
|
28
|
+
:default => false,
|
29
|
+
:desc => 'Do not write spec results to STDOUT.'
|
30
|
+
option :raw,
|
31
|
+
:aliases => '-r',
|
32
|
+
:type => :boolean,
|
33
|
+
:default => false,
|
34
|
+
:desc => 'Return a Hash instead of a results object.'
|
35
|
+
|
36
|
+
def call *files
|
37
|
+
results = rspec_runner(files.empty?).call(:files => files)
|
38
|
+
|
39
|
+
raw? ? results : RSpecResults.new(results)
|
40
|
+
end # method call
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def default_gemfile
|
45
|
+
File.join(Dir.pwd, 'Gemfile')
|
46
|
+
end # method default_gemfile
|
47
|
+
|
48
|
+
def gemfile
|
49
|
+
return options['gemfile'] if options.key?('gemfile')
|
50
|
+
|
51
|
+
gemfile = ENV['BUNDLE_GEMFILE']
|
52
|
+
|
53
|
+
return gemfile if gemfile && gemfile != default_gemfile
|
54
|
+
|
55
|
+
nil
|
56
|
+
end # method gemfile
|
57
|
+
|
58
|
+
def rspec_runner default_coverage = true
|
59
|
+
coverage = options.fetch('coverage', default_coverage)
|
60
|
+
|
61
|
+
env = options.fetch('__env__', {})
|
62
|
+
env[:bundle_gemfile] = gemfile if gemfile
|
63
|
+
env[:coverage] = false unless coverage
|
64
|
+
|
65
|
+
opts = %w(--color --tty)
|
66
|
+
opts << '--format=documentation' unless quiet?
|
67
|
+
|
68
|
+
RSpecRunner.new(:env => env, :options => opts)
|
69
|
+
end # method rspec_runner
|
70
|
+
end # class
|
71
|
+
end # module
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rubocop_results.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
|
5
|
+
module SleepingKingStudios::Tasks::Ci
|
6
|
+
# Encapsulates the results of a RuboCop call.
|
7
|
+
class RuboCopResults
|
8
|
+
# @param results [Hash] The raw results of the RuboCop call.
|
9
|
+
def initialize results
|
10
|
+
@results = results
|
11
|
+
end # constructor
|
12
|
+
|
13
|
+
# @param other [RSpecResults] The other results object to compare.
|
14
|
+
#
|
15
|
+
# @return [Boolean] True if the results are equal, otherwise false.
|
16
|
+
def == other
|
17
|
+
if other.is_a?(Hash)
|
18
|
+
empty? ? other.empty? : to_h == other
|
19
|
+
elsif other.is_a?(RuboCopResults)
|
20
|
+
to_h == other.to_h
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end # if-elsif-else
|
24
|
+
end # method ==
|
25
|
+
|
26
|
+
# @return [Boolean] True if there are no inspected files, otherwise false.
|
27
|
+
def empty?
|
28
|
+
inspected_file_count.zero?
|
29
|
+
end # method empty?
|
30
|
+
|
31
|
+
# @return [Boolean] True if there are any offenses, otherwise false.
|
32
|
+
def failing?
|
33
|
+
!offense_count.zero?
|
34
|
+
end # method failing?
|
35
|
+
|
36
|
+
# @return [Integer] The number of inspected files.
|
37
|
+
def inspected_file_count
|
38
|
+
@results.fetch('inspected_file_count', 0)
|
39
|
+
end # method inspected_file_count
|
40
|
+
|
41
|
+
# Adds the given result values and returns a new results object with the
|
42
|
+
# sums.
|
43
|
+
#
|
44
|
+
# @param other [RuboCopResults] The results to add.
|
45
|
+
#
|
46
|
+
# @return [RuboCopResults] The total results.
|
47
|
+
def merge other
|
48
|
+
self.class.new(
|
49
|
+
'inspected_file_count' =>
|
50
|
+
inspected_file_count + other.inspected_file_count,
|
51
|
+
'offense_count' => offense_count + other.offense_count
|
52
|
+
) # end new
|
53
|
+
end # method merge
|
54
|
+
|
55
|
+
# @return [Integer] The number of detected offenses.
|
56
|
+
def offense_count
|
57
|
+
@results.fetch('offense_count', 0)
|
58
|
+
end # method offense_count
|
59
|
+
|
60
|
+
# @return [Boolean] False.
|
61
|
+
def pending?
|
62
|
+
false
|
63
|
+
end # method pending?
|
64
|
+
|
65
|
+
# @return [Hash] The hash representation of the results.
|
66
|
+
def to_h
|
67
|
+
{
|
68
|
+
'inspected_file_count' => inspected_file_count,
|
69
|
+
'offense_count' => offense_count
|
70
|
+
} # end hash
|
71
|
+
end # method to_h
|
72
|
+
|
73
|
+
# @return [String] The string representation of the results.
|
74
|
+
def to_s
|
75
|
+
str = "#{inspected_file_count} files inspected"
|
76
|
+
|
77
|
+
str << ", #{offense_count} offenses"
|
78
|
+
end # method to_s
|
79
|
+
end # class
|
80
|
+
end # module
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rubocop_runner.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/process_runner'
|
5
|
+
|
6
|
+
module SleepingKingStudios::Tasks::Ci
|
7
|
+
# Service object to run RuboCop as an external process with the specified
|
8
|
+
# parameters.
|
9
|
+
class RuboCopRunner < SleepingKingStudios::Tasks::ProcessRunner
|
10
|
+
def call env: {}, files: [], options: [], report: true
|
11
|
+
report = 'tmp/ci/rubocop.json' if report && !report.is_a?(String)
|
12
|
+
command =
|
13
|
+
build_command(
|
14
|
+
:env => env,
|
15
|
+
:files => files,
|
16
|
+
:options => options,
|
17
|
+
:report => report
|
18
|
+
) # end build_command
|
19
|
+
|
20
|
+
stream_process(command)
|
21
|
+
|
22
|
+
report ? load_report(:report => report) : {}
|
23
|
+
end # method call
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def base_command
|
28
|
+
'bundle exec rubocop'
|
29
|
+
end # method base_command
|
30
|
+
|
31
|
+
def build_options files:, options:, report:, **_kwargs
|
32
|
+
options += ['--format=json', "--out=#{report}"] if report
|
33
|
+
|
34
|
+
super :files => files, :options => options
|
35
|
+
end # method build_options
|
36
|
+
|
37
|
+
def load_report report:
|
38
|
+
raw = File.read report
|
39
|
+
json = JSON.parse raw
|
40
|
+
|
41
|
+
json['summary']
|
42
|
+
rescue
|
43
|
+
{}
|
44
|
+
end # method load_report
|
45
|
+
end # class
|
46
|
+
end # module
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rubocop_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/ci/rubocop_results'
|
5
|
+
require 'sleeping_king_studios/tasks/ci/rubocop_runner'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Ci
|
8
|
+
# Defines a Thor task for running the RuboCop linter.
|
9
|
+
class RuboCopTask < SleepingKingStudios::Tasks::Task
|
10
|
+
def self.description
|
11
|
+
'Runs the RuboCop linter.'
|
12
|
+
end # class method description
|
13
|
+
|
14
|
+
def self.task_name
|
15
|
+
'rubocop'
|
16
|
+
end # class method task_name
|
17
|
+
|
18
|
+
option :quiet,
|
19
|
+
:aliases => '-q',
|
20
|
+
:type => :boolean,
|
21
|
+
:default => false,
|
22
|
+
:desc => 'Do not write lint results to STDOUT.'
|
23
|
+
option :raw,
|
24
|
+
:aliases => '-r',
|
25
|
+
:type => :boolean,
|
26
|
+
:default => false,
|
27
|
+
:desc => 'Return a Hash instead of a results object.'
|
28
|
+
|
29
|
+
def call *files
|
30
|
+
results = rubocop_runner.call(:files => files)
|
31
|
+
|
32
|
+
raw? ? results : RuboCopResults.new(results)
|
33
|
+
end # method call
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def rubocop_runner
|
38
|
+
opts = %w(--color)
|
39
|
+
opts << '--format=progress' unless quiet?
|
40
|
+
|
41
|
+
RuboCopRunner.new(:options => opts)
|
42
|
+
end # method rubocop_runner
|
43
|
+
end # class
|
44
|
+
end # module
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/simplecov_results.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools/toolbox/delegator'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/ci'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Ci
|
8
|
+
# Encapsulates the results of aggregated SimpleCov data.
|
9
|
+
class SimpleCovResults
|
10
|
+
extend SleepingKingStudios::Tools::Toolbox::Delegator
|
11
|
+
|
12
|
+
# @param results [SimpleCov::Result] The raw results of the SimpleCov call.
|
13
|
+
def initialize results
|
14
|
+
@results = results
|
15
|
+
end # constructor
|
16
|
+
|
17
|
+
delegate \
|
18
|
+
:covered_lines,
|
19
|
+
:covered_percent,
|
20
|
+
:missed_lines,
|
21
|
+
:total_lines,
|
22
|
+
:to => :@results
|
23
|
+
|
24
|
+
# @return [Boolean] True if there are no covered lines, otherwise false.
|
25
|
+
def empty?
|
26
|
+
covered_lines.zero?
|
27
|
+
end # method empty?
|
28
|
+
|
29
|
+
# @return [Boolean] True if the covered percentage is less than or equal to
|
30
|
+
# the configured value, otherwise false.
|
31
|
+
def failing?
|
32
|
+
covered_percent.round(1) <= failing_percent.round(1)
|
33
|
+
end # method failing?
|
34
|
+
|
35
|
+
# @return [Float] If the covered percentage is less than or equal to this
|
36
|
+
# value, the result is failing.
|
37
|
+
def failing_percent
|
38
|
+
90.0
|
39
|
+
end # method failing_percent
|
40
|
+
|
41
|
+
# @return [Boolean] True if the covered percentage is less than or equal to
|
42
|
+
# the configured value, otherwise false.
|
43
|
+
def pending?
|
44
|
+
!failing? && covered_percent.round(1) <= pending_percent.round(1)
|
45
|
+
end # method pending?
|
46
|
+
|
47
|
+
# @return [Float] If the covered percentage is less than or equal to this
|
48
|
+
# value, the result is pending.
|
49
|
+
def pending_percent
|
50
|
+
95.0
|
51
|
+
end # method failing_percent
|
52
|
+
|
53
|
+
# @return [String] The string representation of the results.
|
54
|
+
def to_s
|
55
|
+
str = "#{covered_percent.round(2)}% coverage"
|
56
|
+
|
57
|
+
str << ", #{missed_lines} missed lines"
|
58
|
+
|
59
|
+
str << ", #{total_lines} total lines"
|
60
|
+
end # method to_s
|
61
|
+
end # class
|
62
|
+
end # module
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/simplecov_task.rb
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/ci'
|
6
|
+
require 'sleeping_king_studios/tasks/ci/simplecov_results'
|
7
|
+
|
8
|
+
module SleepingKingStudios::Tasks::Ci
|
9
|
+
# Defines a Thor task for aggregating SimpleCov results.
|
10
|
+
class SimpleCovTask < SleepingKingStudios::Tasks::Task
|
11
|
+
def self.description
|
12
|
+
'Aggregates the SimpleCov results.'
|
13
|
+
end # class method description
|
14
|
+
|
15
|
+
def self.task_name
|
16
|
+
'simplecov'
|
17
|
+
end # class method task_name
|
18
|
+
|
19
|
+
def call *_args
|
20
|
+
results = ::SimpleCov.result
|
21
|
+
|
22
|
+
SimpleCovResults.new(results)
|
23
|
+
end # method call
|
24
|
+
end # class
|
25
|
+
end # module
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/steps_runner.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
|
5
|
+
module SleepingKingStudios::Tasks::Ci
|
6
|
+
# Abstract base class for running a sequence of tasks from a configured list.
|
7
|
+
class StepsRunner < SleepingKingStudios::Tasks::Task
|
8
|
+
def call *args
|
9
|
+
results = {}
|
10
|
+
|
11
|
+
filtered_steps.each do |name, config|
|
12
|
+
next if skip_step?(name, config)
|
13
|
+
|
14
|
+
title = config.fetch(:title, name)
|
15
|
+
|
16
|
+
results[title] = call_step(config, args)
|
17
|
+
end # reduce
|
18
|
+
|
19
|
+
results
|
20
|
+
end # method call
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def ci_steps
|
25
|
+
[]
|
26
|
+
end # method ci_steps
|
27
|
+
|
28
|
+
def call_step config, args
|
29
|
+
class_name = config[:class]
|
30
|
+
require_path = config.fetch(:require, require_path(class_name))
|
31
|
+
|
32
|
+
require require_path if require_path
|
33
|
+
|
34
|
+
step_class = Object.const_get(class_name)
|
35
|
+
instance = step_class.new(options)
|
36
|
+
|
37
|
+
instance.call(*args)
|
38
|
+
end # method call_step
|
39
|
+
|
40
|
+
# rubocop:disable Metrics/AbcSize
|
41
|
+
def filtered_steps
|
42
|
+
filtered = ci_steps
|
43
|
+
|
44
|
+
if options.key?('except') && !options['except'].empty?
|
45
|
+
filtered =
|
46
|
+
filtered.reject { |key, _| options['except'].include?(key.to_s) }
|
47
|
+
end # if
|
48
|
+
|
49
|
+
if options.key?('only') && !options['only'].empty?
|
50
|
+
filtered =
|
51
|
+
filtered.select { |key, _| options['only'].include?(key.to_s) }
|
52
|
+
end # if
|
53
|
+
|
54
|
+
filtered
|
55
|
+
end # method filtered_steps
|
56
|
+
# rubocop:enable Metrics/AbcSize
|
57
|
+
|
58
|
+
def require_path class_name
|
59
|
+
class_name.
|
60
|
+
split('::').
|
61
|
+
map { |str| tools.string.underscore(str) }.
|
62
|
+
join '/'
|
63
|
+
end # method require_path
|
64
|
+
|
65
|
+
def skip_step? _name, _config
|
66
|
+
false
|
67
|
+
end # method skip_step?
|
68
|
+
end # class
|
69
|
+
end # module
|