cobra_commander 1.0.1 → 1.2.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 +4 -4
- data/cobra_commander.gemspec +15 -20
- data/docs/CHANGELOG.md +10 -0
- data/lib/cobra_commander/affected.rb +6 -41
- data/lib/cobra_commander/cli/filters.rb +1 -1
- data/lib/cobra_commander/cli/output/ascii_tree.rb +2 -2
- data/lib/cobra_commander/cli/output/change.rb +12 -52
- data/lib/cobra_commander/cli.rb +21 -30
- data/lib/cobra_commander/component.rb +29 -0
- data/lib/cobra_commander/executor/buffered_printer.rb +41 -0
- data/lib/cobra_commander/executor/command.rb +22 -45
- data/lib/cobra_commander/executor/isolated_pty.rb +20 -0
- data/lib/cobra_commander/executor/output_prompt.rb +59 -0
- data/lib/cobra_commander/executor/package_criteria.rb +0 -3
- data/lib/cobra_commander/executor/run_script.rb +25 -0
- data/lib/cobra_commander/executor/script.rb +16 -30
- data/lib/cobra_commander/executor/worker_pool.rb +104 -0
- data/lib/cobra_commander/executor.rb +33 -31
- data/lib/cobra_commander/git_changed.rb +2 -2
- data/lib/cobra_commander/package.rb +5 -1
- data/lib/cobra_commander/source.rb +13 -2
- data/lib/cobra_commander/version.rb +1 -1
- metadata +48 -89
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.rubocop.yml +0 -8
- data/Gemfile +0 -12
- data/Guardfile +0 -14
- data/Rakefile +0 -10
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/doc/dependency_decisions.yml +0 -9
- data/lib/cobra_commander/executor/execution.rb +0 -52
- data/lib/cobra_commander/executor/interactive_printer.rb +0 -53
- data/lib/cobra_commander/executor/job.rb +0 -51
- data/lib/cobra_commander/executor/markdown_printer.rb +0 -21
- data/lib/cobra_commander/executor/spinners.rb +0 -40
- data/mkdocs.yml +0 -8
data/Guardfile
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
guard :rspec, cmd: "bundle exec rspec" do
|
|
4
|
-
require "guard/rspec/dsl"
|
|
5
|
-
dsl = Guard::RSpec::Dsl.new(self)
|
|
6
|
-
|
|
7
|
-
rspec = dsl.rspec
|
|
8
|
-
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
9
|
-
watch(rspec.spec_support) { rspec.spec_dir }
|
|
10
|
-
watch(rspec.spec_files)
|
|
11
|
-
|
|
12
|
-
ruby = dsl.ruby
|
|
13
|
-
dsl.watch_spec_files_for(ruby.lib_files)
|
|
14
|
-
end
|
data/Rakefile
DELETED
data/bin/console
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "cobra_commander"
|
|
6
|
-
|
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
-
|
|
10
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
-
# require "pry"
|
|
12
|
-
# Pry.start
|
|
13
|
-
|
|
14
|
-
require "irb"
|
|
15
|
-
IRB.start
|
data/bin/setup
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
- - :inherit_from
|
|
3
|
-
- https://raw.githubusercontent.com/powerhome/oss-guide/master/license_rules.yml
|
|
4
|
-
- - :approve
|
|
5
|
-
- bundler
|
|
6
|
-
- :who: Carlos Palhares <carlos.palhares@powerhrg.com>
|
|
7
|
-
:why: 'Bundler <https://rubygems.org/gems/bundler/versions/1.17.3> is licensed under MIT, but license_finder sometimes fails to resolve that with 1.17.3.'
|
|
8
|
-
:versions: [1.17.3]
|
|
9
|
-
:when: 2022-11-02 20:36:55.617698000 Z
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "concurrent-ruby"
|
|
4
|
-
|
|
5
|
-
module CobraCommander
|
|
6
|
-
module Executor
|
|
7
|
-
# A threaded execution environment, limited by the number of given workers
|
|
8
|
-
class Execution < Hash
|
|
9
|
-
#
|
|
10
|
-
# @param jobs [Array<#call>] array of job objects
|
|
11
|
-
# @param workers [Integer] number of workers to process this execution
|
|
12
|
-
# @see CobraCommander::Executor::Job
|
|
13
|
-
def initialize(jobs, workers:)
|
|
14
|
-
super()
|
|
15
|
-
|
|
16
|
-
@executor = Concurrent::FixedThreadPool.new(workers, auto_terminate: true)
|
|
17
|
-
merge! create_futures(jobs)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Wait for all jobs to complete, returns a future with all execution futures
|
|
21
|
-
# @return [Concurrent::Promises::Future]
|
|
22
|
-
def wait
|
|
23
|
-
Concurrent::Promises.zip_futures_on(@executor, *values)
|
|
24
|
-
.tap(&:wait)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# The execution succeeds when all jobs succeeded
|
|
28
|
-
# @return [Boolean]
|
|
29
|
-
def success?
|
|
30
|
-
values.all?(&:fulfilled?)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def create_future(job)
|
|
36
|
-
Concurrent::Promises.future_on(@executor, job, &:call).then do |result|
|
|
37
|
-
status, output = result
|
|
38
|
-
case status
|
|
39
|
-
when :error then Concurrent::Promises.rejected_future(output)
|
|
40
|
-
when :success, :skip then Concurrent::Promises.fulfilled_future(output)
|
|
41
|
-
else
|
|
42
|
-
Concurrent::Promises.fulfilled_future(result)
|
|
43
|
-
end
|
|
44
|
-
end.flat
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def create_futures(jobs)
|
|
48
|
-
jobs.to_h { |job| [job, create_future(job)] }
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "pastel"
|
|
4
|
-
require "tty-prompt"
|
|
5
|
-
|
|
6
|
-
module CobraCommander
|
|
7
|
-
module Executor
|
|
8
|
-
# Runs an interactive output printer
|
|
9
|
-
class InteractivePrinter
|
|
10
|
-
pastel = Pastel.new
|
|
11
|
-
SUCCESS = "#{pastel.green('✔')} %s"
|
|
12
|
-
ERROR = "#{pastel.red('✖')} %s"
|
|
13
|
-
BYE = pastel.decorate("\n\n👋 Bye!", :white, :on_black, :bold).freeze
|
|
14
|
-
|
|
15
|
-
def self.run(execution, output)
|
|
16
|
-
new(execution).run(output)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def initialize(execution)
|
|
20
|
-
@prompt = TTY::Prompt.new
|
|
21
|
-
@execution = execution
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def run(output)
|
|
25
|
-
selected = nil
|
|
26
|
-
loop do
|
|
27
|
-
selected = @prompt.select("Print output?", options, default: options.key(selected))
|
|
28
|
-
output.puts selected.fulfilled? ? selected.value : selected.reason
|
|
29
|
-
end
|
|
30
|
-
rescue TTY::Reader::InputInterrupt
|
|
31
|
-
output.puts BYE
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def options
|
|
37
|
-
@options ||= @execution.sort { |*args| sort_results(*args.flatten) }
|
|
38
|
-
.reduce({}) do |options, (job, result)|
|
|
39
|
-
template = result.rejected? ? ERROR : SUCCESS
|
|
40
|
-
options.merge format(template, job.to_s) => result
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def sort_results(job_a, result_a, job_b, result_b)
|
|
45
|
-
if result_a.rejected? == result_b.rejected?
|
|
46
|
-
job_a.to_s <=> job_b.to_s
|
|
47
|
-
else
|
|
48
|
-
result_b.rejected? ? 1 : -1
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "tty-command"
|
|
4
|
-
|
|
5
|
-
module CobraCommander
|
|
6
|
-
module Executor
|
|
7
|
-
#
|
|
8
|
-
# This is a helper module to help jobs return valid errors and success outputs.
|
|
9
|
-
#
|
|
10
|
-
# A CobraCommander::Executor::Job is actually any object responding to #call, and returning
|
|
11
|
-
# valid error or success responses.
|
|
12
|
-
#
|
|
13
|
-
# An error is an array containint `:error` and the output (i.e.: [:error, "string output"]).
|
|
14
|
-
# A success is either an array containint `:success` and the output, or just the output
|
|
15
|
-
# (i.e.: [:error, "string output"] or just "string output").
|
|
16
|
-
#
|
|
17
|
-
module Job
|
|
18
|
-
def skip(reason)
|
|
19
|
-
[:skip, reason]
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def error(output)
|
|
23
|
-
[:error, output]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def success(output)
|
|
27
|
-
[:success, output]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def run_script(script, path)
|
|
31
|
-
result = isolate_bundle do
|
|
32
|
-
TTY::Command.new(pty: true, printer: :null)
|
|
33
|
-
.run!(script, chdir: path, err: :out)
|
|
34
|
-
end
|
|
35
|
-
return error(result.out) if result.failed?
|
|
36
|
-
|
|
37
|
-
success(result.out)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def isolate_bundle(&block)
|
|
43
|
-
if Bundler.respond_to?(:with_unbundled_env)
|
|
44
|
-
Bundler.with_unbundled_env(&block)
|
|
45
|
-
else
|
|
46
|
-
Bundler.with_clean_env(&block)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module CobraCommander
|
|
4
|
-
module Executor
|
|
5
|
-
# Prints the given CobraCommander::Executor::Context to [output] collection in markdown
|
|
6
|
-
module MarkdownPrinter
|
|
7
|
-
SUCCESS = "\n## ✔ %s\n"
|
|
8
|
-
ERROR = "\n## ✖ %s\n"
|
|
9
|
-
OUTPUT = "\n```\n\n%s\n```\n"
|
|
10
|
-
|
|
11
|
-
def self.run(execution, output)
|
|
12
|
-
execution.each do |job, result|
|
|
13
|
-
template = result.fulfilled? ? SUCCESS : ERROR
|
|
14
|
-
|
|
15
|
-
output.print format(template, job)
|
|
16
|
-
output.print format(OUTPUT, result.fulfilled? ? result.value : result.reason)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "pastel"
|
|
4
|
-
require "tty-spinner"
|
|
5
|
-
|
|
6
|
-
module CobraCommander
|
|
7
|
-
module Executor
|
|
8
|
-
class Spinners
|
|
9
|
-
pastel = ::Pastel.new
|
|
10
|
-
SPINNER_OPTIONS = {
|
|
11
|
-
format: :bouncing,
|
|
12
|
-
success_mark: pastel.green("[DONE]"),
|
|
13
|
-
error_mark: pastel.red("[ERROR]"),
|
|
14
|
-
}.freeze
|
|
15
|
-
|
|
16
|
-
def self.start(execution, output:)
|
|
17
|
-
new(execution, output: output).start
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def initialize(execution, output:)
|
|
21
|
-
@multi = TTY::Spinner::Multi.new(":spinner :task", output: output)
|
|
22
|
-
@multi.top_spinner.update(task: "Running")
|
|
23
|
-
execution.each { |job, result| register_spinner(job, result) }
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def start
|
|
27
|
-
@multi.auto_spin
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
def register_spinner(job, result)
|
|
33
|
-
@multi.register(":spinner #{job}", **SPINNER_OPTIONS) do |spinner|
|
|
34
|
-
result.on_fulfillment!(spinner) { |_, spin| spin.success }
|
|
35
|
-
.on_rejection!(spinner) { |_, spin| spin.error }
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|