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
         |