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,27 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools'
|
4
|
+
|
5
|
+
# Hic iacet Arthurus, rex quondam, rexque futurus.
|
6
|
+
module SleepingKingStudios
|
7
|
+
# Toolkit providing an encapsulation layer around the Thor CLI library, with
|
8
|
+
# predefined tasks for development and continuous integration.
|
9
|
+
module Tasks
|
10
|
+
autoload :Configuration, 'sleeping_king_studios/tasks/configuration'
|
11
|
+
autoload :Task, 'sleeping_king_studios/tasks/task'
|
12
|
+
autoload :TaskGroup, 'sleeping_king_studios/tasks/task_group'
|
13
|
+
|
14
|
+
def self.configuration
|
15
|
+
@configuration ||= SleepingKingStudios::Tasks::Configuration.new
|
16
|
+
end # class method configuration
|
17
|
+
|
18
|
+
def self.configure
|
19
|
+
yield configuration
|
20
|
+
end # class method configure
|
21
|
+
|
22
|
+
# The file path to the root of the gem directory.
|
23
|
+
def self.gem_path
|
24
|
+
@gem_path ||= __dir__.sub %r{/lib/sleeping_king_studios\z}, ''
|
25
|
+
end # class method gem_path
|
26
|
+
end # module
|
27
|
+
end # module
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps.rb
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks
|
8
|
+
# Thor tasks for semi-distributed applications.
|
9
|
+
module Apps
|
10
|
+
autoload :AppConfiguration,
|
11
|
+
'sleeping_king_studios/tasks/apps/app_configuration'
|
12
|
+
|
13
|
+
# rubocop:disable Metrics/MethodLength
|
14
|
+
def self.configuration
|
15
|
+
@configuration ||=
|
16
|
+
begin
|
17
|
+
tools = SleepingKingStudios::Tools::Toolbelt.instance
|
18
|
+
apps = load_configuration
|
19
|
+
hsh = Hash.new do |_, key|
|
20
|
+
SleepingKingStudios::Tasks::Apps::AppConfiguration.
|
21
|
+
new(:name => key.to_s)
|
22
|
+
end # hash
|
23
|
+
|
24
|
+
apps.each do |key, data|
|
25
|
+
name = key.to_s
|
26
|
+
data = tools.hash.convert_keys_to_symbols(data)
|
27
|
+
|
28
|
+
data[:name] ||= name
|
29
|
+
|
30
|
+
hsh[key] =
|
31
|
+
SleepingKingStudios::Tasks::Apps::AppConfiguration.new(data)
|
32
|
+
end # each
|
33
|
+
|
34
|
+
hsh
|
35
|
+
end # begin-end
|
36
|
+
end # class method configuration
|
37
|
+
# rubocop:enable Metrics/MethodLength
|
38
|
+
|
39
|
+
def self.load_configuration
|
40
|
+
config_file = SleepingKingStudios::Tasks.configuration.apps.config_file
|
41
|
+
raw = ::File.read(config_file)
|
42
|
+
|
43
|
+
YAML.safe_load raw
|
44
|
+
rescue
|
45
|
+
{}
|
46
|
+
end # class method load_configuration
|
47
|
+
class << self; private :load_configuration; end
|
48
|
+
end # module
|
49
|
+
end # module
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/app_configuration.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools/toolbox/configuration'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/apps'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Apps
|
8
|
+
# Application configuration options.
|
9
|
+
class AppConfiguration < SleepingKingStudios::Tools::Toolbox::Configuration
|
10
|
+
namespace :ci do
|
11
|
+
option :rspec, :default => {}
|
12
|
+
|
13
|
+
option :rubocop, :default => {}
|
14
|
+
|
15
|
+
option :simplecov, :default => {}
|
16
|
+
|
17
|
+
option :steps, :default =>
|
18
|
+
->() { SleepingKingStudios::Tasks.configuration.apps.ci.steps }
|
19
|
+
|
20
|
+
define_method :steps_with_options do
|
21
|
+
steps.each.with_object({}) do |step, hsh|
|
22
|
+
value = send(step)
|
23
|
+
|
24
|
+
next hsh[step] = false if value == false
|
25
|
+
|
26
|
+
default =
|
27
|
+
SleepingKingStudios::Tasks.configuration.apps.ci.send(step)
|
28
|
+
hsh[step] = default.merge(value)
|
29
|
+
end # each
|
30
|
+
end # method steps_with_options
|
31
|
+
end # namespace
|
32
|
+
|
33
|
+
define_method :default_source_files do
|
34
|
+
files = [
|
35
|
+
"apps/#{short_name}",
|
36
|
+
"apps/#{short_name}.rb",
|
37
|
+
"lib/#{short_name}",
|
38
|
+
"lib/#{short_name}.rb"
|
39
|
+
] # end files
|
40
|
+
|
41
|
+
files.select { |path| File.exist?(path) }
|
42
|
+
end # method default_source_files
|
43
|
+
|
44
|
+
define_method :default_spec_files do
|
45
|
+
files = ["apps/#{short_name}/spec", "spec/#{short_name}"]
|
46
|
+
|
47
|
+
files.select { |path| File.exist?(path) }
|
48
|
+
end # method default_spec_files
|
49
|
+
|
50
|
+
define_method :short_name do
|
51
|
+
# rubocop:disable Style/RedundantSelf
|
52
|
+
tools.string.underscore(self.name.gsub(/\s+/, '_'))
|
53
|
+
# rubocop:enable Style/RedundantSelf
|
54
|
+
end # define_method
|
55
|
+
|
56
|
+
define_method :tools do
|
57
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
58
|
+
end # method tools
|
59
|
+
|
60
|
+
option :gemfile, :default => 'Gemfile'
|
61
|
+
|
62
|
+
option :name
|
63
|
+
|
64
|
+
option :source_files, :default => ->() { default_source_files }
|
65
|
+
|
66
|
+
option :spec_files, :default => ->() { default_spec_files }
|
67
|
+
end # module
|
68
|
+
end # module
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/applications_task.rb
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/apps'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Apps
|
8
|
+
# Extension module with additional configuration for performing actions on a
|
9
|
+
# per-application basis.
|
10
|
+
module ApplicationsTask
|
11
|
+
private
|
12
|
+
|
13
|
+
def applications
|
14
|
+
SleepingKingStudios::Tasks::Apps.configuration
|
15
|
+
end # method applications
|
16
|
+
|
17
|
+
def filter_applications only: []
|
18
|
+
filtered = applications
|
19
|
+
|
20
|
+
if only && !only.empty?
|
21
|
+
normalized = only.map(&:to_s)
|
22
|
+
filtered = filtered.select { |key, _| normalized.include?(key) }
|
23
|
+
end # if
|
24
|
+
|
25
|
+
filtered
|
26
|
+
end # method filter_applications
|
27
|
+
end # class
|
28
|
+
end # module
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/bundle/install_runner.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/bundle'
|
4
|
+
require 'sleeping_king_studios/tasks/process_runner'
|
5
|
+
|
6
|
+
module SleepingKingStudios::Tasks::Apps::Bundle
|
7
|
+
# Service object to run bundle install as an external process.
|
8
|
+
class InstallRunner < SleepingKingStudios::Tasks::ProcessRunner
|
9
|
+
def call gemfile
|
10
|
+
command = build_command :env => { :bundle_gemfile => gemfile }
|
11
|
+
|
12
|
+
stream_process(command)
|
13
|
+
end # method call
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def base_command
|
18
|
+
'bundle install'
|
19
|
+
end # method base_command
|
20
|
+
end # module
|
21
|
+
end # module
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/bundle/install_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/applications_task'
|
4
|
+
require 'sleeping_king_studios/tasks/apps/bundle'
|
5
|
+
require 'sleeping_king_studios/tasks/apps/bundle/install_runner'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Apps::Bundle
|
8
|
+
# Defines a Thor task for installing gem dependencies for each application.
|
9
|
+
class InstallTask < SleepingKingStudios::Tasks::Task
|
10
|
+
include SleepingKingStudios::Tasks::Apps::ApplicationsTask
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'Installs the Ruby gem dependencies for each application.'
|
14
|
+
end # class method description
|
15
|
+
|
16
|
+
def call *applications
|
17
|
+
filtered = filter_applications(:only => applications)
|
18
|
+
|
19
|
+
gemfiles(filtered).each do |gemfile|
|
20
|
+
say %(\nInstalling gems for gemfile "#{gemfile}")
|
21
|
+
say '-' * 80
|
22
|
+
say "\n"
|
23
|
+
|
24
|
+
install_runner.call(gemfile)
|
25
|
+
end # each
|
26
|
+
end # method call
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def gemfiles applications
|
31
|
+
applications.map { |_, config| config.gemfile }.uniq
|
32
|
+
end # method gemfiles
|
33
|
+
|
34
|
+
def install_runner
|
35
|
+
@install_runner =
|
36
|
+
SleepingKingStudios::Tasks::Apps::Bundle::InstallRunner.new
|
37
|
+
end # method install_runner
|
38
|
+
end # module
|
39
|
+
end # module
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/bundle/update_runner.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/bundle'
|
4
|
+
require 'sleeping_king_studios/tasks/process_runner'
|
5
|
+
|
6
|
+
module SleepingKingStudios::Tasks::Apps::Bundle
|
7
|
+
# Service object to run bundle update as an external process.
|
8
|
+
class UpdateRunner < SleepingKingStudios::Tasks::ProcessRunner
|
9
|
+
def call gemfile
|
10
|
+
command = build_command :env => { :bundle_gemfile => gemfile }
|
11
|
+
|
12
|
+
stream_process(command)
|
13
|
+
end # method call
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def base_command
|
18
|
+
'bundle update'
|
19
|
+
end # method base_command
|
20
|
+
end # class
|
21
|
+
end # module
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/bundle/update_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/applications_task'
|
4
|
+
require 'sleeping_king_studios/tasks/apps/bundle'
|
5
|
+
require 'sleeping_king_studios/tasks/apps/bundle/update_runner'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Apps::Bundle
|
8
|
+
# Defines a Thor task for updating gem dependencies for each application.
|
9
|
+
class UpdateTask < SleepingKingStudios::Tasks::Task
|
10
|
+
include SleepingKingStudios::Tasks::Apps::ApplicationsTask
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
'Updates the Ruby gem dependencies for each application.'
|
14
|
+
end # class method description
|
15
|
+
|
16
|
+
def call *applications
|
17
|
+
filtered = filter_applications(:only => applications)
|
18
|
+
|
19
|
+
gemfiles(filtered).each do |gemfile|
|
20
|
+
say %(\nUpdating gems for gemfile "#{gemfile}")
|
21
|
+
say '-' * 80
|
22
|
+
say "\n"
|
23
|
+
|
24
|
+
update_runner.call(gemfile)
|
25
|
+
end # each
|
26
|
+
end # method call
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def gemfiles applications
|
31
|
+
applications.map { |_, config| config.gemfile }.uniq
|
32
|
+
end # method gemfiles
|
33
|
+
|
34
|
+
def update_runner
|
35
|
+
@update_runner =
|
36
|
+
SleepingKingStudios::Tasks::Apps::Bundle::UpdateRunner.new
|
37
|
+
end # method update_runner
|
38
|
+
end # class
|
39
|
+
end # module
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/ci/results_reporter.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools/toolbox/delegator'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/apps/ci'
|
6
|
+
require 'sleeping_king_studios/tasks/ci/results_helpers'
|
7
|
+
|
8
|
+
module SleepingKingStudios::Tasks::Apps::Ci
|
9
|
+
# Reports on the results of a multi-application continuous integration
|
10
|
+
# process, printing the step results grouped by application.
|
11
|
+
class ResultsReporter
|
12
|
+
extend SleepingKingStudios::Tools::Toolbox::Delegator
|
13
|
+
|
14
|
+
include SleepingKingStudios::Tasks::Ci::ResultsHelpers
|
15
|
+
|
16
|
+
delegate \
|
17
|
+
:applications,
|
18
|
+
:print_table,
|
19
|
+
:say,
|
20
|
+
:set_color,
|
21
|
+
:to => :@context
|
22
|
+
|
23
|
+
def initialize context
|
24
|
+
@context = context
|
25
|
+
end # method initialize
|
26
|
+
|
27
|
+
def call results
|
28
|
+
width = 1 + heading_width(results)
|
29
|
+
|
30
|
+
results.each do |application, app_results|
|
31
|
+
report_application application, app_results, :width => width
|
32
|
+
end # each
|
33
|
+
end # method call
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def heading_width results
|
38
|
+
results.reduce(0) do |memo, (_, hsh)|
|
39
|
+
[memo, *hsh.keys.map(&:size)].max
|
40
|
+
end # reduce
|
41
|
+
end # method heading_width
|
42
|
+
|
43
|
+
def generate_rows results, width:
|
44
|
+
results.map do |key, obj|
|
45
|
+
next nil if obj.nil?
|
46
|
+
|
47
|
+
badge = format(" %-#{width}.#{width}s", "#{key}:")
|
48
|
+
|
49
|
+
[set_color(badge, results_color(obj)), obj.to_s]
|
50
|
+
end. # rows
|
51
|
+
compact
|
52
|
+
end # method generate_rows
|
53
|
+
|
54
|
+
def report_application app_name, results, width:
|
55
|
+
config = applications.fetch(app_name, {})
|
56
|
+
app_name = config.fetch('name', app_name)
|
57
|
+
rows = generate_rows(results, :width => width)
|
58
|
+
|
59
|
+
return if rows.empty?
|
60
|
+
|
61
|
+
say "#{app_name}:"
|
62
|
+
say "\n"
|
63
|
+
|
64
|
+
print_table rows
|
65
|
+
|
66
|
+
say "\n"
|
67
|
+
end # method report_application
|
68
|
+
end # class
|
69
|
+
end # module
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/ci/rspec_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/apps/ci/steps_task'
|
5
|
+
|
6
|
+
module SleepingKingStudios::Tasks::Apps::Ci
|
7
|
+
# Defines a Thor task for running the RSpec test suite for each application.
|
8
|
+
class RSpecTask < SleepingKingStudios::Tasks::Task
|
9
|
+
def self.description
|
10
|
+
'Runs the RSpec test suite for each application.'
|
11
|
+
end # class method description
|
12
|
+
|
13
|
+
def self.task_name
|
14
|
+
'rspec'
|
15
|
+
end # class method task_name
|
16
|
+
|
17
|
+
option :quiet,
|
18
|
+
:aliases => '-q',
|
19
|
+
:type => :boolean,
|
20
|
+
:default => false,
|
21
|
+
:desc => 'Do not write spec results to STDOUT.'
|
22
|
+
|
23
|
+
def call *applications
|
24
|
+
SleepingKingStudios::Tasks::Apps::Ci::StepsTask.
|
25
|
+
new(options.merge('only' => %w(rspec))).
|
26
|
+
call(*applications)
|
27
|
+
end # method call
|
28
|
+
end # class
|
29
|
+
end # module
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/apps/ci/rspec_wrapper.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/apps/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/apps/ci/step_wrapper'
|
5
|
+
require 'sleeping_king_studios/tasks/ci/rspec_results'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Apps::Ci
|
8
|
+
# Wrapper class for calling an RSpec Ci task for a specific application.
|
9
|
+
class RSpecWrapper < SleepingKingStudios::Tasks::Apps::Ci::StepWrapper
|
10
|
+
def call application
|
11
|
+
super
|
12
|
+
|
13
|
+
if spec_files.empty?
|
14
|
+
return SleepingKingStudios::Tasks::Ci::RSpecResults.new({})
|
15
|
+
end # if
|
16
|
+
|
17
|
+
run_step(*spec_files)
|
18
|
+
end # method call
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def spec_files
|
23
|
+
SleepingKingStudios::Tasks::Apps.
|
24
|
+
configuration[current_application].
|
25
|
+
spec_files
|
26
|
+
end # method spec_files
|
27
|
+
|
28
|
+
def step_key
|
29
|
+
:rspec
|
30
|
+
end # method step_key
|
31
|
+
|
32
|
+
def step_options
|
33
|
+
gemfile = applications[current_application].fetch('gemfile', 'Gemfile')
|
34
|
+
|
35
|
+
super.merge(
|
36
|
+
'coverage' => true,
|
37
|
+
'gemfile' => gemfile,
|
38
|
+
'__env__' => { :app_name => current_application }
|
39
|
+
) # end merge
|
40
|
+
end # method step_options
|
41
|
+
end # class
|
42
|
+
end # module
|