mattboldt/guac

View on GitHub
lib/guac/commands/setup.rb

Summary

Maintainability
A
1 hr
Test Coverage
require_relative '../config'
require_relative '../repo'
require 'yaml'
require 'colorize'

module Guac
  module Commands
    class Setup

      PROMPT_QUEUE = %i(
        prompt_repos
        prompt_branch_aliases
        prompt_pull_strategy
        prompt_default_branch
      ).freeze

      def initialize(options, thor)
        @options = options
        @config = Guac::Config.configs
        @defaults = Guac::Config.defaults
        @thor = thor
      end

      def execute(_input: $stdin, output: $stdout)
        @output = output
        @output.puts "\nšŸ„‘ Welcome to the tableside Guac builder šŸ„‘\n".green

        @body = @defaults.dup
        @body.merge!(@config) unless @config.nil?

        PROMPT_QUEUE.each do |prompt|
          send(prompt)
          @output.puts "\n"
        end

        Guac::Config.save_configs(@body)
        @output.puts "šŸ„‘ Config saved in ~/.guacrc šŸ„‘\n".bold.green
        @output.puts Guac::Config.configs.to_yaml
      end

      private

      def prompt_repos
        @output.puts 'Git Repos (separated by spaces)'.bold.blue
        @output.puts 'Input absolute paths or drag & drop folders here (e.g. ~/Repos/one ~/Repos/two)'
        result = @thor.ask('Repos:'.bold, required: true)
        dirs = result.split(/ \s*/)
        validate_repos(dirs)

        @body[:repos] = dirs.map do |r|
          {
            dir: r,
            name: r.split('/').last,
          }
        end
      end

      def prompt_branch_aliases
        @output.puts 'Git branch aliases'.bold.blue
        @output.puts 'Input format: `branch_name:branch_name_alias`'
        result = @thor.yes?('Would you like to configure aliases? (y/n)'.bold)
        return unless result

        @body[:repos].each do |repo|
          result = @thor.ask("Alias for `#{repo[:name].colorize(:blue)}`:")
          next unless valid_result?(result)

          repo[:branch_aliases] = parse_branch_aliases(result)
        end
      end

      def prompt_pull_strategy
        @output.puts 'Pull strategy'.bold.blue
        @output.puts "Default: `#{@defaults[:pull_strategy].bold}`"
        result = @thor.ask('Enter strategy or press return for default:'.bold)

        @body[:pull_strategy] = result if valid_result?(result)
      end

      def prompt_default_branch
        @output.puts "Default branch".bold.blue
        @output.puts "Default: `#{@defaults[:default_branch].bold}`"
        result = @thor.ask('Enter branch or press return for default:'.bold)

        @body[:default_branch] = result if valid_result?(result)
      end

      def valid_result?(result)
        result && !result.strip.empty?
      end

      def parse_branch_aliases(result)
        branch_pairs = result.split(/ \s*/)
        {}.tap do |obj|
          branch_pairs.each do |pair|
            branches = pair.split(':')
            obj[branches[0]] = branches[1]
          end
        end
      end

      def validate_repos(dirs)
        return if Guac::Repo.valid?(dirs)

        error = "1 or more directories could not be found, or are not git repos!".yellow.bold
        raise Guac::Commands::Error, error
      end
    end
  end
end