cobra_commander 0.9.1 → 0.12.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/.github/workflows/ci.yml +17 -6
- data/.github/workflows/release.yml +20 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +25 -1
- data/Gemfile +0 -1
- data/README.md +3 -4
- data/cobra_commander.gemspec +6 -4
- data/gemfiles/bundler1.gemfile +7 -0
- data/gemfiles/bundler2.gemfile +7 -0
- data/lib/cobra_commander/change.rb +2 -2
- data/lib/cobra_commander/cli/filters.rb +30 -0
- data/lib/cobra_commander/cli.rb +23 -26
- data/lib/cobra_commander/dependencies/bundler.rb +2 -2
- data/lib/cobra_commander/executor/concurrent.rb +51 -0
- data/lib/cobra_commander/executor/context.rb +47 -0
- data/lib/cobra_commander/executor.rb +6 -11
- data/lib/cobra_commander/output/ascii_tree.rb +2 -0
- data/lib/cobra_commander/output/interactive_printer.rb +32 -0
- data/lib/cobra_commander/output/markdown_printer.rb +24 -0
- data/lib/cobra_commander/output.rb +2 -0
- data/lib/cobra_commander/umbrella.rb +3 -3
- data/lib/cobra_commander/version.rb +1 -1
- metadata +57 -25
- data/.travis.yml +0 -12
- data/lib/cobra_commander/executor/component_exec.rb +0 -33
- data/lib/cobra_commander/executor/multi_exec.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8461ea231fa9be478360d33fbadfb8983512172687831ac7c17ac1f927614200
|
4
|
+
data.tar.gz: 0b36b28eadecb6e0bc6e7ee8c3e6db951f7dc7d74be67c91b97659dc7bd52c5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39a0956db1750d63553d87e4d13ad75246f4f4633b3d6a42de621c45f11a515506ab5f0d7f14343d61f183d03df7e8218dee8f93a439da023e442d70c7f3b681
|
7
|
+
data.tar.gz: 227acbdb961e2903cdaacd44ed4bdd7b07a48e7298737bbe5b6228bd28df8aa6c7aea6a6949de2a3eea999287b633e9bfcd32b7b9e108e3f7f4fcaa7385e2806
|
data/.github/workflows/ci.yml
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
name: CI
|
2
2
|
|
3
|
-
on:
|
3
|
+
on: push
|
4
4
|
|
5
5
|
jobs:
|
6
6
|
test:
|
7
7
|
name: Tests
|
8
8
|
runs-on: ubuntu-latest
|
9
9
|
strategy:
|
10
|
+
fail-fast: false
|
10
11
|
matrix:
|
11
12
|
ruby:
|
12
13
|
- "2.5"
|
13
14
|
- "2.6"
|
15
|
+
- "2.7"
|
16
|
+
- "3.0"
|
17
|
+
bundler:
|
18
|
+
- "1"
|
19
|
+
- "2"
|
20
|
+
env:
|
21
|
+
BUNDLE_GEMFILE: gemfiles/bundler${{ matrix.bundler }}.gemfile
|
14
22
|
steps:
|
15
23
|
- uses: actions/checkout@v2
|
16
|
-
-
|
17
|
-
uses: ruby/setup-ruby@v1
|
24
|
+
- uses: ruby/setup-ruby@v1
|
18
25
|
with:
|
19
26
|
ruby-version: ${{ matrix.ruby }}
|
20
|
-
bundler:
|
27
|
+
bundler: ${{ matrix.bundler }}
|
21
28
|
bundler-cache: true
|
29
|
+
- name: Install bundler v1 # Even if we're testing bundler v2, we need v1 available because the fixture components have it in their Gemfile.locks
|
30
|
+
run: gem install bundler -v "~> 1" --no-document
|
22
31
|
- name: Install Graphviz
|
23
32
|
run: sudo apt -qq install graphviz
|
24
33
|
- name: Run tests
|
@@ -28,8 +37,10 @@ jobs:
|
|
28
37
|
runs-on: ubuntu-latest
|
29
38
|
steps:
|
30
39
|
- uses: actions/checkout@v2
|
31
|
-
-
|
32
|
-
|
40
|
+
- uses: ruby/setup-ruby@v1
|
41
|
+
with:
|
42
|
+
ruby-version: 3.0
|
43
|
+
- uses: reviewdog/action-rubocop@v1
|
33
44
|
with:
|
34
45
|
rubocop_version: 0.88.0
|
35
46
|
filter_mode: nofilter
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Publish Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
tags:
|
8
|
+
- v*
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v1
|
14
|
+
- name: Release Gem
|
15
|
+
uses: cadwallion/publish-rubygems-action@master
|
16
|
+
if: contains(github.ref, 'refs/tags/v')
|
17
|
+
env:
|
18
|
+
GITHUB_TOKEN: ${{ secrets.github_token }}
|
19
|
+
RUBYGEMS_API_KEY: ${{ secrets.rubygems_api_key }}
|
20
|
+
RELEASE_COMMAND: rake release
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,9 +2,33 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## Version 0.12.0 - 2021-09-21
|
6
|
+
|
7
|
+
* Add interactive UI and Markdown output to `cobra exec` [#63](https://github.com/powerhome/cobra_commander/pull/63)
|
8
|
+
* Add `--self` and `--no-self` filters to `cobra exec` and `cobra ls`, defaults to `--self` [#61](https://github.com/powerhome/cobra_commander/pull/61)
|
9
|
+
|
10
|
+
## Version 0.11.0 - 2021-04-23
|
11
|
+
|
12
|
+
* Add concurrency limit to multi exec [#57](https://github.com/powerhome/cobra_commander/pull/57)
|
13
|
+
* Ruby 3.0 compatibility [#55](https://github.com/powerhome/cobra_commander/pull/55)
|
14
|
+
|
15
|
+
## Version 0.10.0 - 2021-02-25
|
16
|
+
|
17
|
+
* Add support for Bundler 2 [#54](https://github.com/powerhome/cobra_commander/pull/54)
|
18
|
+
* Add support for Ruby 2.7 [#53](https://github.com/powerhome/cobra_commander/pull/53)
|
19
|
+
|
20
|
+
## Version 0.9.2 -
|
21
|
+
|
22
|
+
* Another fix for binstubs [#51](https://github.com/powerhome/cobra_commander/pull/51)
|
23
|
+
|
24
|
+
## Version 0.9.1 -
|
25
|
+
|
26
|
+
* Replace bundler encapsulation violation by LockfileParser [#48](https://github.com/powerhome/cobra_commander/pull/48)
|
27
|
+
* Fix bundle binstubs [#50](https://github.com/powerhome/cobra_commander/pull/50)
|
28
|
+
|
5
29
|
## Version 0.9.0 - 2020-08-26
|
6
30
|
|
7
|
-
* Add support for parallel task execution to `cobra exec
|
31
|
+
* Add support for parallel task execution to `cobra exec` [#49](https://github.com/powerhome/cobra_commander/pull/49)
|
8
32
|
|
9
33
|
## Version 0.8.1 - 2020-07-29
|
10
34
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,11 +2,10 @@
|
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/cobra_commander)
|
4
4
|
[](https://rubygems.org/gems/cobra_commander)
|
5
|
-
[](https://gemnasium.com/github.com/powerhome/cobra_commander)
|
5
|
+
[](https://github.com/powerhome/cobra_commander/actions/workflows/ci.yml)
|
6
|
+
[](https://codeclimate.com/github/powerhome/cobra_commander/maintainability)
|
8
7
|
|
9
|
-
Tools for working with Component Based Rails Apps (see
|
8
|
+
Tools for working with Component Based Rails Apps (see https://cbra.info/). Includes tools for graphing both Ruby and Javascript components in an application and their relationships, as well as selectively testing components based on changes made.
|
10
9
|
|
11
10
|
## Installation
|
12
11
|
|
data/cobra_commander.gemspec
CHANGED
@@ -33,17 +33,19 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
34
34
|
spec.require_paths = ["lib"]
|
35
35
|
|
36
|
-
spec.add_dependency "bundler"
|
36
|
+
spec.add_dependency "bundler"
|
37
|
+
spec.add_dependency "concurrent-ruby", "~> 1.1"
|
37
38
|
spec.add_dependency "ruby-graphviz", "~> 1.2.3"
|
38
39
|
spec.add_dependency "thor", ["< 2.0", ">= 0.18.1"]
|
39
|
-
spec.add_dependency "tty-command", "~> 0.
|
40
|
+
spec.add_dependency "tty-command", "~> 0.10.0"
|
41
|
+
spec.add_dependency "tty-prompt", "~> 0.23.1"
|
40
42
|
spec.add_dependency "tty-spinner", "~> 0.9.3"
|
41
43
|
|
42
44
|
spec.add_development_dependency "aruba", "~> 0.14.2"
|
43
|
-
spec.add_development_dependency "bundler"
|
45
|
+
spec.add_development_dependency "bundler"
|
44
46
|
spec.add_development_dependency "guard-rspec"
|
45
47
|
spec.add_development_dependency "pry"
|
46
|
-
spec.add_development_dependency "rake", "
|
48
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
47
49
|
spec.add_development_dependency "rspec", "~> 3.5"
|
48
50
|
spec.add_development_dependency "rubocop", "0.88.0"
|
49
51
|
end
|
@@ -66,13 +66,13 @@ module CobraCommander
|
|
66
66
|
|
67
67
|
def directly_affected_components
|
68
68
|
puts "<<< Directly affected components >>>"
|
69
|
-
@affected.directly.each { |component| puts display(component) }
|
69
|
+
@affected.directly.each { |component| puts display(**component) }
|
70
70
|
puts blank_line
|
71
71
|
end
|
72
72
|
|
73
73
|
def transitively_affected_components
|
74
74
|
puts "<<< Transitively affected components >>>"
|
75
|
-
@affected.transitively.each { |component| puts display(component) }
|
75
|
+
@affected.transitively.each { |component| puts display(**component) }
|
76
76
|
puts blank_line
|
77
77
|
end
|
78
78
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CobraCommander
|
4
|
+
# @private
|
5
|
+
class CLI
|
6
|
+
private_class_method def self.filter_options(dependents:, dependencies:)
|
7
|
+
method_option :dependencies, type: :boolean, aliases: "-d", desc: dependencies
|
8
|
+
method_option :dependents, type: :boolean, aliases: "-D", desc: dependents
|
9
|
+
method_option :self, type: :boolean, default: true, desc: "Include the own component"
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def find_component(name)
|
15
|
+
return umbrella.root unless name
|
16
|
+
|
17
|
+
umbrella.find(name) || error("Component #{name} not found, try one of `cobra ls`") || exit(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
def components_filtered(component_name)
|
21
|
+
return umbrella.components unless component_name
|
22
|
+
|
23
|
+
component = find_component(component_name)
|
24
|
+
components = options.self ? [component] : []
|
25
|
+
components.concat component.deep_dependencies if options.dependencies
|
26
|
+
components.concat component.deep_dependents if options.dependents
|
27
|
+
components
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/cobra_commander/cli.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "thor"
|
4
4
|
require "fileutils"
|
5
|
+
require "concurrent-ruby"
|
5
6
|
|
6
7
|
require "cobra_commander"
|
7
8
|
require "cobra_commander/affected"
|
@@ -12,6 +13,10 @@ require "cobra_commander/output"
|
|
12
13
|
module CobraCommander
|
13
14
|
# Implements the tool's CLI
|
14
15
|
class CLI < Thor
|
16
|
+
require "cobra_commander/cli/filters"
|
17
|
+
|
18
|
+
DEFAULT_CONCURRENCY = (Concurrent.processor_count / 2.0).ceil
|
19
|
+
|
15
20
|
class_option :app, default: Dir.pwd, aliases: "-a", type: :string
|
16
21
|
class_option :js, default: false, type: :boolean, desc: "Consider only the JS dependency graph"
|
17
22
|
class_option :ruby, default: false, type: :boolean, desc: "Consider only the Ruby dependency graph"
|
@@ -22,10 +27,8 @@ module CobraCommander
|
|
22
27
|
end
|
23
28
|
|
24
29
|
desc "ls [component]", "Lists the components in the context of a given component or umbrella"
|
25
|
-
|
26
|
-
|
27
|
-
method_option :dependents, type: :boolean, aliases: "-D",
|
28
|
-
desc: "Run the command on each dependency of a given component"
|
30
|
+
filter_options dependents: "Lists all dependents of a given component",
|
31
|
+
dependencies: "Lists all dependencies of a given component"
|
29
32
|
method_option :total, type: :boolean, aliases: "-t", desc: "Prints the total count of components"
|
30
33
|
def ls(component = nil)
|
31
34
|
components = components_filtered(component)
|
@@ -34,13 +37,24 @@ module CobraCommander
|
|
34
37
|
|
35
38
|
desc "exec [component] <command>", "Executes the command in the context of a given component or set thereof. " \
|
36
39
|
"Defaults to all components."
|
37
|
-
|
38
|
-
|
40
|
+
filter_options dependents: "Run the command on each dependent of a given component",
|
41
|
+
dependencies: "Run the command on each dependency of a given component"
|
42
|
+
method_option :concurrency, type: :numeric, default: DEFAULT_CONCURRENCY, aliases: "-c",
|
43
|
+
desc: "Max number of jobs to run concurrently"
|
44
|
+
method_option :interactive, type: :boolean, default: true, aliases: "-i",
|
45
|
+
desc: "Runs in interactive mode to allow the user to inspect the output of each component"
|
39
46
|
def exec(command_or_component, command = nil)
|
40
|
-
CobraCommander::Executor.exec(
|
41
|
-
components_filtered(command && command_or_component),
|
42
|
-
command || command_or_component
|
47
|
+
results = CobraCommander::Executor.exec(
|
48
|
+
components: components_filtered(command && command_or_component),
|
49
|
+
command: command || command_or_component,
|
50
|
+
concurrency: options.concurrency,
|
51
|
+
status_output: $stderr
|
43
52
|
)
|
53
|
+
if options.interactive && results.size > 1
|
54
|
+
CobraCommander::Output::InteractivePrinter.run(results, $stdout)
|
55
|
+
else
|
56
|
+
CobraCommander::Output::MarkdownPrinter.run(results, $stdout)
|
57
|
+
end
|
44
58
|
end
|
45
59
|
|
46
60
|
desc "tree [component]", "Prints the dependency tree of a given component or umbrella"
|
@@ -74,22 +88,5 @@ module CobraCommander
|
|
74
88
|
def umbrella
|
75
89
|
@umbrella ||= CobraCommander.umbrella(options.app, yarn: options.js, bundler: options.ruby)
|
76
90
|
end
|
77
|
-
|
78
|
-
def find_component(name)
|
79
|
-
return umbrella.root unless name
|
80
|
-
|
81
|
-
umbrella.find(name) || error("Component #{name} not found, try one of `cobra ls`") || exit(1)
|
82
|
-
end
|
83
|
-
|
84
|
-
def components_filtered(component_name)
|
85
|
-
return umbrella.components unless component_name
|
86
|
-
|
87
|
-
component = find_component(component_name)
|
88
|
-
|
89
|
-
return component.deep_dependencies if options.dependencies
|
90
|
-
return component.deep_dependents if options.dependents
|
91
|
-
|
92
|
-
[component]
|
93
|
-
end
|
94
91
|
end
|
95
92
|
end
|
@@ -11,8 +11,8 @@ module CobraCommander
|
|
11
11
|
attr_reader :path
|
12
12
|
|
13
13
|
def initialize(root)
|
14
|
-
@root = root
|
15
|
-
@path =
|
14
|
+
@root = Pathname.new(root)
|
15
|
+
@path = @root.join("Gemfile.lock").realpath
|
16
16
|
end
|
17
17
|
|
18
18
|
def dependencies
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-spinner"
|
4
|
+
require "concurrent-ruby"
|
5
|
+
|
6
|
+
module CobraCommander
|
7
|
+
module Executor
|
8
|
+
# Execute a command on multiple components concurrently
|
9
|
+
class Concurrent
|
10
|
+
def initialize(components, concurrency:, spin_output:)
|
11
|
+
@components = components
|
12
|
+
@multi = TTY::Spinner::Multi.new(":spinner :task", output: spin_output)
|
13
|
+
@semaphore = ::Concurrent::Semaphore.new(concurrency)
|
14
|
+
end
|
15
|
+
|
16
|
+
def exec(command)
|
17
|
+
@multi.top_spinner.update(task: "Running #{command}")
|
18
|
+
@results = []
|
19
|
+
@components.each do |component|
|
20
|
+
register_job(component, command)
|
21
|
+
end
|
22
|
+
@multi.auto_spin
|
23
|
+
@results
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def pastel
|
29
|
+
@pastel ||= Pastel.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def spinner_options
|
33
|
+
@spinner_options ||= {
|
34
|
+
format: :bouncing,
|
35
|
+
success_mark: pastel.green("[DONE]"),
|
36
|
+
error_mark: pastel.red("[ERROR]"),
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def register_job(component, command)
|
41
|
+
@multi.register(":spinner #{component.name}", **spinner_options) do |spinner|
|
42
|
+
@semaphore.acquire
|
43
|
+
context = Context.new(component, command)
|
44
|
+
context.success? ? spinner.success : spinner.error
|
45
|
+
@results << context
|
46
|
+
@semaphore.release
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "tty-command"
|
4
|
+
|
5
|
+
module CobraCommander
|
6
|
+
module Executor
|
7
|
+
class Context
|
8
|
+
attr_reader :component, :command
|
9
|
+
|
10
|
+
def initialize(component, command)
|
11
|
+
@component = component
|
12
|
+
@command = command
|
13
|
+
@tty = TTY::Command.new(pty: true, printer: :null, stderr: :stdout)
|
14
|
+
end
|
15
|
+
|
16
|
+
def results
|
17
|
+
@results ||= @component.root_paths.map do |path|
|
18
|
+
isolate_bundle do
|
19
|
+
@tty.run!(command, chdir: path)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def component_name
|
25
|
+
component.name
|
26
|
+
end
|
27
|
+
|
28
|
+
def success?
|
29
|
+
results.all?(&:success?)
|
30
|
+
end
|
31
|
+
|
32
|
+
def output
|
33
|
+
results.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def isolate_bundle(&block)
|
39
|
+
if Bundler.respond_to?(:with_unbundled_env)
|
40
|
+
Bundler.with_unbundled_env(&block)
|
41
|
+
else
|
42
|
+
Bundler.with_clean_env(&block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,19 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "executor/
|
4
|
-
require_relative "executor/
|
3
|
+
require_relative "executor/context"
|
4
|
+
require_relative "executor/concurrent"
|
5
5
|
|
6
6
|
module CobraCommander
|
7
|
-
# Execute
|
7
|
+
# Execute a command on all given components
|
8
8
|
module Executor
|
9
|
-
def self.exec(components
|
10
|
-
components
|
11
|
-
|
12
|
-
ComponentExec.new(components.first)
|
13
|
-
else
|
14
|
-
MultiExec.new(components)
|
15
|
-
end
|
16
|
-
exec.run(command, output: output, spin_output: status_output)
|
9
|
+
def self.exec(components:, command:, concurrency:, status_output:)
|
10
|
+
Concurrent.new(components, concurrency: concurrency, spin_output: status_output)
|
11
|
+
.exec(command)
|
17
12
|
end
|
18
13
|
end
|
19
14
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pastel"
|
4
|
+
require "tty-prompt"
|
5
|
+
|
6
|
+
module CobraCommander
|
7
|
+
module Output
|
8
|
+
# Runs an interactive output printer
|
9
|
+
module InteractivePrinter
|
10
|
+
pastel = Pastel.new
|
11
|
+
SUCCESS = "#{pastel.green("✔")} %s".freeze
|
12
|
+
ERROR = "#{pastel.red("✖")} %s".freeze
|
13
|
+
BYE = pastel.decorate("👋 Bye!", :white, :on_black, :bold).freeze
|
14
|
+
|
15
|
+
def self.run(contexts, output)
|
16
|
+
prompt = TTY::Prompt.new
|
17
|
+
context_options = contexts.reduce({}) do |options, context|
|
18
|
+
template = context.success? ? SUCCESS : ERROR
|
19
|
+
options.merge(
|
20
|
+
format(template, context.component_name) => context
|
21
|
+
)
|
22
|
+
end
|
23
|
+
loop do
|
24
|
+
context = prompt.select("Print output?", context_options)
|
25
|
+
output.puts context.output
|
26
|
+
end
|
27
|
+
rescue TTY::Reader::InputInterrupt
|
28
|
+
output.puts "\n\n", BYE
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pastel"
|
4
|
+
require "tty-prompt"
|
5
|
+
|
6
|
+
module CobraCommander
|
7
|
+
module Output
|
8
|
+
# Prints the given CobraCommander::Executor::Context to [output] collection in markdown
|
9
|
+
module MarkdownPrinter
|
10
|
+
SUCCESS = "\n## ✔ %s\n".freeze
|
11
|
+
ERROR = "\n## ✖ %s\n".freeze
|
12
|
+
OUTPUT = "\n```\n$ %s\n\n%s\n```\n".freeze
|
13
|
+
|
14
|
+
def self.run(contexts, output)
|
15
|
+
contexts.each do |context|
|
16
|
+
template = context.success? ? SUCCESS : ERROR
|
17
|
+
|
18
|
+
output.print format(template, context.component_name)
|
19
|
+
output.print format(OUTPUT, context.command, context.output)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -29,9 +29,9 @@ module CobraCommander
|
|
29
29
|
|
30
30
|
def add_source(key, source)
|
31
31
|
@root_component.add_source key, source.path, source.dependencies
|
32
|
-
source.components.each do |
|
33
|
-
@components[name] ||= Component.new(self, name)
|
34
|
-
@components[name].add_source key, path, dependencies
|
32
|
+
source.components.each do |component|
|
33
|
+
@components[component[:name]] ||= Component.new(self, component[:name])
|
34
|
+
@components[component[:name]].add_source key, component[:path], component[:dependencies]
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cobra_commander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Langfeld
|
@@ -10,22 +10,36 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2021-09-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: concurrent-ruby
|
17
31
|
requirement: !ruby/object:Gem::Requirement
|
18
32
|
requirements:
|
19
33
|
- - "~>"
|
20
34
|
- !ruby/object:Gem::Version
|
21
|
-
version: '1.
|
35
|
+
version: '1.1'
|
22
36
|
type: :runtime
|
23
37
|
prerelease: false
|
24
38
|
version_requirements: !ruby/object:Gem::Requirement
|
25
39
|
requirements:
|
26
40
|
- - "~>"
|
27
41
|
- !ruby/object:Gem::Version
|
28
|
-
version: '1.
|
42
|
+
version: '1.1'
|
29
43
|
- !ruby/object:Gem::Dependency
|
30
44
|
name: ruby-graphviz
|
31
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,36 +58,50 @@ dependencies:
|
|
44
58
|
name: thor
|
45
59
|
requirement: !ruby/object:Gem::Requirement
|
46
60
|
requirements:
|
47
|
-
- - "<"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '2.0'
|
50
61
|
- - ">="
|
51
62
|
- !ruby/object:Gem::Version
|
52
63
|
version: 0.18.1
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.0'
|
53
67
|
type: :runtime
|
54
68
|
prerelease: false
|
55
69
|
version_requirements: !ruby/object:Gem::Requirement
|
56
70
|
requirements:
|
57
|
-
- - "<"
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
version: '2.0'
|
60
71
|
- - ">="
|
61
72
|
- !ruby/object:Gem::Version
|
62
73
|
version: 0.18.1
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.0'
|
63
77
|
- !ruby/object:Gem::Dependency
|
64
78
|
name: tty-command
|
65
79
|
requirement: !ruby/object:Gem::Requirement
|
66
80
|
requirements:
|
67
81
|
- - "~>"
|
68
82
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0.
|
83
|
+
version: 0.10.0
|
70
84
|
type: :runtime
|
71
85
|
prerelease: false
|
72
86
|
version_requirements: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
88
|
- - "~>"
|
75
89
|
- !ruby/object:Gem::Version
|
76
|
-
version: 0.
|
90
|
+
version: 0.10.0
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: tty-prompt
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 0.23.1
|
98
|
+
type: :runtime
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.23.1
|
77
105
|
- !ruby/object:Gem::Dependency
|
78
106
|
name: tty-spinner
|
79
107
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,16 +134,16 @@ dependencies:
|
|
106
134
|
name: bundler
|
107
135
|
requirement: !ruby/object:Gem::Requirement
|
108
136
|
requirements:
|
109
|
-
- - "
|
137
|
+
- - ">="
|
110
138
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
139
|
+
version: '0'
|
112
140
|
type: :development
|
113
141
|
prerelease: false
|
114
142
|
version_requirements: !ruby/object:Gem::Requirement
|
115
143
|
requirements:
|
116
|
-
- - "
|
144
|
+
- - ">="
|
117
145
|
- !ruby/object:Gem::Version
|
118
|
-
version: '
|
146
|
+
version: '0'
|
119
147
|
- !ruby/object:Gem::Dependency
|
120
148
|
name: guard-rspec
|
121
149
|
requirement: !ruby/object:Gem::Requirement
|
@@ -148,16 +176,16 @@ dependencies:
|
|
148
176
|
name: rake
|
149
177
|
requirement: !ruby/object:Gem::Requirement
|
150
178
|
requirements:
|
151
|
-
- - "
|
179
|
+
- - ">="
|
152
180
|
- !ruby/object:Gem::Version
|
153
|
-
version:
|
181
|
+
version: 12.3.3
|
154
182
|
type: :development
|
155
183
|
prerelease: false
|
156
184
|
version_requirements: !ruby/object:Gem::Requirement
|
157
185
|
requirements:
|
158
|
-
- - "
|
186
|
+
- - ">="
|
159
187
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
188
|
+
version: 12.3.3
|
161
189
|
- !ruby/object:Gem::Dependency
|
162
190
|
name: rspec
|
163
191
|
requirement: !ruby/object:Gem::Requirement
|
@@ -201,10 +229,10 @@ extra_rdoc_files: []
|
|
201
229
|
files:
|
202
230
|
- ".editorconfig"
|
203
231
|
- ".github/workflows/ci.yml"
|
232
|
+
- ".github/workflows/release.yml"
|
204
233
|
- ".gitignore"
|
205
234
|
- ".rspec"
|
206
235
|
- ".rubocop.yml"
|
207
|
-
- ".travis.yml"
|
208
236
|
- CHANGELOG.md
|
209
237
|
- CODE_OF_CONDUCT.md
|
210
238
|
- Gemfile
|
@@ -217,10 +245,13 @@ files:
|
|
217
245
|
- bin/setup
|
218
246
|
- cobra_commander.gemspec
|
219
247
|
- exe/cobra
|
248
|
+
- gemfiles/bundler1.gemfile
|
249
|
+
- gemfiles/bundler2.gemfile
|
220
250
|
- lib/cobra_commander.rb
|
221
251
|
- lib/cobra_commander/affected.rb
|
222
252
|
- lib/cobra_commander/change.rb
|
223
253
|
- lib/cobra_commander/cli.rb
|
254
|
+
- lib/cobra_commander/cli/filters.rb
|
224
255
|
- lib/cobra_commander/component.rb
|
225
256
|
- lib/cobra_commander/dependencies.rb
|
226
257
|
- lib/cobra_commander/dependencies/bundler.rb
|
@@ -228,12 +259,14 @@ files:
|
|
228
259
|
- lib/cobra_commander/dependencies/yarn/package_repo.rb
|
229
260
|
- lib/cobra_commander/dependencies/yarn_workspace.rb
|
230
261
|
- lib/cobra_commander/executor.rb
|
231
|
-
- lib/cobra_commander/executor/
|
232
|
-
- lib/cobra_commander/executor/
|
262
|
+
- lib/cobra_commander/executor/concurrent.rb
|
263
|
+
- lib/cobra_commander/executor/context.rb
|
233
264
|
- lib/cobra_commander/output.rb
|
234
265
|
- lib/cobra_commander/output/ascii_tree.rb
|
235
266
|
- lib/cobra_commander/output/flat_list.rb
|
236
267
|
- lib/cobra_commander/output/graph_viz.rb
|
268
|
+
- lib/cobra_commander/output/interactive_printer.rb
|
269
|
+
- lib/cobra_commander/output/markdown_printer.rb
|
237
270
|
- lib/cobra_commander/umbrella.rb
|
238
271
|
- lib/cobra_commander/version.rb
|
239
272
|
- renovate.json
|
@@ -256,8 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
256
289
|
- !ruby/object:Gem::Version
|
257
290
|
version: '0'
|
258
291
|
requirements: []
|
259
|
-
|
260
|
-
rubygems_version: 2.7.3
|
292
|
+
rubygems_version: 3.0.3
|
261
293
|
signing_key:
|
262
294
|
specification_version: 4
|
263
295
|
summary: Tools for working with Component Based Rails Apps
|
data/.travis.yml
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
sudo: true
|
2
|
-
language: ruby
|
3
|
-
before_install:
|
4
|
-
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
|
5
|
-
- gem install bundler:"$BUNDLER_VERSION"
|
6
|
-
- sudo apt-get -qq install graphviz
|
7
|
-
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.13.0
|
8
|
-
- export PATH="$HOME/.yarn/bin:$PATH"
|
9
|
-
rvm:
|
10
|
-
- 2.5.1
|
11
|
-
env:
|
12
|
-
- BUNDLER_VERSION=1.17.3
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "tty-command"
|
4
|
-
|
5
|
-
module CobraCommander
|
6
|
-
module Executor
|
7
|
-
# Execute a command on a single component
|
8
|
-
class ComponentExec
|
9
|
-
def initialize(component)
|
10
|
-
@component = component
|
11
|
-
end
|
12
|
-
|
13
|
-
def run(command, output: $stdout, **cmd_options)
|
14
|
-
tty = TTY::Command.new(pty: true, printer: :quiet, output: output)
|
15
|
-
isolate_bundle do
|
16
|
-
@component.root_paths.all? do |path|
|
17
|
-
tty.run!(command, chdir: path, **cmd_options).success?
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def isolate_bundle(&block)
|
25
|
-
if Bundler.respond_to?(:with_unbundled_env)
|
26
|
-
Bundler.with_unbundled_env(&block)
|
27
|
-
else
|
28
|
-
Bundler.with_clean_env(&block)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "tty-spinner"
|
4
|
-
|
5
|
-
require_relative "component_exec"
|
6
|
-
|
7
|
-
module CobraCommander
|
8
|
-
module Executor
|
9
|
-
# Executes a command on multiple components simultaniously
|
10
|
-
class MultiExec
|
11
|
-
def initialize(components)
|
12
|
-
@components = components
|
13
|
-
end
|
14
|
-
|
15
|
-
def run(command, output: $stdout, spin_output: $stderr, only_output_on_error: true, **cmd_options)
|
16
|
-
cmmd_output = StringIO.new
|
17
|
-
multi = TTY::Spinner::Multi.new("Running #{command}", output: spin_output)
|
18
|
-
@components.each do |component|
|
19
|
-
component_exec(multi, component, command, only_output_on_error: only_output_on_error,
|
20
|
-
stderr: :stdout, output: cmmd_output,
|
21
|
-
**cmd_options)
|
22
|
-
end
|
23
|
-
multi.auto_spin
|
24
|
-
output << cmmd_output.string
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def component_exec(multi, component, command, **options)
|
31
|
-
exec = ComponentExec.new(component)
|
32
|
-
multi.register(*spinner(component.name)) do |spin|
|
33
|
-
exec.run(command, **options) ? spin.success : spin.error
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def spinner(title)
|
38
|
-
pastel = Pastel.new
|
39
|
-
[":spinner #{title}", { format: :bouncing,
|
40
|
-
success_mark: pastel.green("[DONE]"),
|
41
|
-
error_mark: pastel.red("[ERROR]"), },]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|