gocardless/coach

View on GitHub
bin/coach

Summary

Maintainability
Test Coverage
#!/usr/bin/env ruby

require "coach/cli/provider_finder"
require "coach/version"
require "commander"

module Coach
  class CLI
    extend Commander::Methods

    class << self
      # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
      def run
        program :version, Coach::VERSION
        program :description,
                "Coach's CLI to help understand the provide/require graph made up of " \
                "all the middleware chains you've built using Coach.\n" \
                "  More information at: https://github.com/gocardless/coach#coach-cli."
        program :help_formatter, :compact

        never_trace!

        command "find-provider" do |c|
          c.syntax = "bundle exec coach find-provider"
          c.description =
            "Given the name of a Coach middleware and a value that it requires, it " \
            "outputs the name of the middleware that provides it."

          c.action do |args, _|
            load_config_environment

            middleware_name, value_name = *args
            raise ArgumentError, "middleware_name and value_name required" unless middleware_name && value_name

            result = Coach::Cli::ProviderFinder.new(args[0], args[1]).find_provider

            puts "Value `#{value_name}` is provided to `#{middleware_name}` by:\n\n"
            puts result.to_a.join("\n")
          end
        end

        command "find-chain" do |c|
          c.syntax = "bundle exec coach find-chain"
          c.description =
            "Given the name of a Coach middleware and a value it requires, " \
            "it outputs the chains of middleware between the specified middleware " \
            "and the one that provides the required value."

          c.action do |args, _|
            load_config_environment

            middleware_name, value_name = *args
            raise ArgumentError, "middleware_name and value_name required" unless middleware_name && value_name

            chains = Coach::Cli::ProviderFinder.new(middleware_name, value_name).find_chain

            if chains.size > 1
              puts "Value `#{value_name}` is provided to `#{middleware_name}` " \
                "by multiple middleware chains:\n\n"
            else
              puts "Value `#{value_name}` is provided to `#{middleware_name}` by:\n\n"
            end

            formatted_chains = chains.map do |chain|
              chain.join(" -> ")
            end.join("\n---\n")

            puts formatted_chains
          end
        end

        run!
      end
      # rubocop:enable Metrics/AbcSize, Metrics/MethodLength

      def load_config_environment
        require File.join(Dir.pwd, "config/environment")
      rescue LoadError
        puts <<~ERR
          Could not load your Rails app
          =============================

          Currently the coach CLI assumes you have a config/environment.rb file that
          we can load. We believe this is true of Rails apps in general.

          Please raise an issue if that's not the case!

          https://github.com/gocardless/coach/issues
        ERR
        exit 1
      end
    end
  end
end

Coach::CLI.run