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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/cobra_commander.gemspec +15 -20
  3. data/docs/CHANGELOG.md +10 -0
  4. data/lib/cobra_commander/affected.rb +6 -41
  5. data/lib/cobra_commander/cli/filters.rb +1 -1
  6. data/lib/cobra_commander/cli/output/ascii_tree.rb +2 -2
  7. data/lib/cobra_commander/cli/output/change.rb +12 -52
  8. data/lib/cobra_commander/cli.rb +21 -30
  9. data/lib/cobra_commander/component.rb +29 -0
  10. data/lib/cobra_commander/executor/buffered_printer.rb +41 -0
  11. data/lib/cobra_commander/executor/command.rb +22 -45
  12. data/lib/cobra_commander/executor/isolated_pty.rb +20 -0
  13. data/lib/cobra_commander/executor/output_prompt.rb +59 -0
  14. data/lib/cobra_commander/executor/package_criteria.rb +0 -3
  15. data/lib/cobra_commander/executor/run_script.rb +25 -0
  16. data/lib/cobra_commander/executor/script.rb +16 -30
  17. data/lib/cobra_commander/executor/worker_pool.rb +104 -0
  18. data/lib/cobra_commander/executor.rb +33 -31
  19. data/lib/cobra_commander/git_changed.rb +2 -2
  20. data/lib/cobra_commander/package.rb +5 -1
  21. data/lib/cobra_commander/source.rb +13 -2
  22. data/lib/cobra_commander/version.rb +1 -1
  23. metadata +48 -89
  24. data/.gitignore +0 -16
  25. data/.rspec +0 -3
  26. data/.rubocop.yml +0 -8
  27. data/Gemfile +0 -12
  28. data/Guardfile +0 -14
  29. data/Rakefile +0 -10
  30. data/bin/console +0 -15
  31. data/bin/setup +0 -8
  32. data/doc/dependency_decisions.yml +0 -9
  33. data/lib/cobra_commander/executor/execution.rb +0 -52
  34. data/lib/cobra_commander/executor/interactive_printer.rb +0 -53
  35. data/lib/cobra_commander/executor/job.rb +0 -51
  36. data/lib/cobra_commander/executor/markdown_printer.rb +0 -21
  37. data/lib/cobra_commander/executor/spinners.rb +0 -40
  38. 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
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rubocop/rake_task"
5
- require "rspec/core/rake_task"
6
-
7
- RSpec::Core::RakeTask.new(:spec)
8
- RuboCop::RakeTask.new(:rubocop)
9
-
10
- task default: %i[spec rubocop]
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,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -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
data/mkdocs.yml DELETED
@@ -1,8 +0,0 @@
1
- site_name: Cobra Commander
2
- site_description: Cobra Commander Documentation
3
- repo_url: https://github.com/powerhome/cobra_commander
4
- nav:
5
- - "Home": "README.md"
6
- - "Changelog": "CHANGELOG.md"
7
- plugins:
8
- - techdocs-core