cob 0.0.15
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 +7 -0
- data/bin/cob +6 -0
- data/lib/cob.rb +62 -0
- data/lib/credentials.rb +83 -0
- data/lib/git.rb +27 -0
- data/lib/local_cob.rb +15 -0
- data/lib/navigator.rb +64 -0
- data/lib/paginator.rb +74 -0
- data/lib/remote_cob.rb +61 -0
- data/lib/string_refinements.rb +9 -0
- data/lib/version.rb +5 -0
- metadata +95 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 698e8f72857d8052c532614332d07903b44e4b4da52a85debfcaf46745a3109d
         | 
| 4 | 
            +
              data.tar.gz: c88940d9ac79e2bbdce31572d53ab1bb1b465ab680bd835fd69d34e15ac49161
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 3d084dc142c8613fe784d70507705390538a3472271e747212f26699779e8b11656298e03227931be9ad55b0cdf00c52535f7eaf25ff479d8ac1f7a0c922c54b
         | 
| 7 | 
            +
              data.tar.gz: 877eb16d44a54f1221d221d6d7e7f3f69347d125be7af500002c0e6093be8bba64212a8a5453bcbd6b2a59f408b7cd9fe2f7f8bfe92bafe5b902ab0b2a1e6cc7
         | 
    
        data/bin/cob
    ADDED
    
    
    
        data/lib/cob.rb
    ADDED
    
    | @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            # !/usr/bin/env ruby
         | 
| 2 | 
            +
            # frozen_string_literal: true
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # _________  ________ __________
         | 
| 6 | 
            +
            # \_   ___ \ \_____  \\______   \
         | 
| 7 | 
            +
            # /    \  \/  /   |   \|    |  _/
         | 
| 8 | 
            +
            # \     \____/    |    \    |   \
         | 
| 9 | 
            +
            #  \______  /\_______  /______  /
         | 
| 10 | 
            +
            #         \/         \/       \/
         | 
| 11 | 
            +
            #
         | 
| 12 | 
            +
            # The ULTIMATE "cob" tool with a total of 3 distinct usages.
         | 
| 13 | 
            +
            # examples:
         | 
| 14 | 
            +
            #   $ cob                                                     # queries github and gives you a list of issues to pick from
         | 
| 15 | 
            +
            #   $ cob 2837                                                # queries github and checks out the matching issue using "cob" style formating
         | 
| 16 | 
            +
            #   $ cob "my string with #hashes and, other: . punctuations" # instant cob
         | 
| 17 | 
            +
            #   $ cob some sentence without special characters            # instant cob
         | 
| 18 | 
            +
            #
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            require_relative './git.rb'
         | 
| 21 | 
            +
            require_relative './local_cob.rb'
         | 
| 22 | 
            +
            require_relative './string_refinements.rb'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            using StringRefinements
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            module Cob
         | 
| 27 | 
            +
              class << self
         | 
| 28 | 
            +
                def run(args)
         | 
| 29 | 
            +
                  @args = args
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  if (@args.length == 1 && !@args[0].all_digits?) || @args.length > 1
         | 
| 32 | 
            +
                    run_local
         | 
| 33 | 
            +
                    exit 0
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  run_remote
         | 
| 37 | 
            +
                rescue Interrupt
         | 
| 38 | 
            +
                  exit 1
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                private
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def run_local
         | 
| 44 | 
            +
                  LocalCOB.run
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def run_remote
         | 
| 48 | 
            +
                  require 'json'
         | 
| 49 | 
            +
                  require 'fileutils'
         | 
| 50 | 
            +
                  require 'tty-prompt'
         | 
| 51 | 
            +
                  require_relative './credentials.rb'
         | 
| 52 | 
            +
                  require_relative './paginator.rb'
         | 
| 53 | 
            +
                  require_relative './navigator.rb'
         | 
| 54 | 
            +
                  require_relative './remote_cob.rb'
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  RemoteCOB::Selection.run && exit(0) if @args.empty?
         | 
| 57 | 
            +
                  RemoteCOB::Fire.run      && exit(0) if @args.length == 1
         | 
| 58 | 
            +
                rescue Interrupt
         | 
| 59 | 
            +
                  exit 1
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
    
        data/lib/credentials.rb
    ADDED
    
    | @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            # class to handle the credentials
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # usage:
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            # c = Credentials.new
         | 
| 9 | 
            +
            # c.username
         | 
| 10 | 
            +
            # c.pa_token
         | 
| 11 | 
            +
            #
         | 
| 12 | 
            +
            class Credentials
         | 
| 13 | 
            +
              def initialize
         | 
| 14 | 
            +
                @config_file = ENV['GITHUB_CREDENTIALS_FILE'] ||
         | 
| 15 | 
            +
                               "#{ENV['HOME']}/.cob/github_credentials.json"
         | 
| 16 | 
            +
                @config = parse_config
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def username
         | 
| 20 | 
            +
                # USERNAME
         | 
| 21 | 
            +
                @config['username'] || prompt_username
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def pa_token
         | 
| 25 | 
            +
                # PA_TOKEN
         | 
| 26 | 
            +
                @config['paToken'] || prompt_pa_token
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def overwrite_config
         | 
| 30 | 
            +
                File.write(@config_file, @config.to_json)
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def prompt_username
         | 
| 34 | 
            +
                prompt = TTY::Prompt.new(active_color: :cyan)
         | 
| 35 | 
            +
                username = prompt.ask('What is your github username?') do |q|
         | 
| 36 | 
            +
                  q.required true
         | 
| 37 | 
            +
                  q.modify   :lowercase
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                @config['username'] = username
         | 
| 41 | 
            +
                overwrite_config
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                username
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def prompt_pa_token
         | 
| 47 | 
            +
                prompt = TTY::Prompt.new(active_color: :cyan)
         | 
| 48 | 
            +
                token = prompt.ask('What is your github personal access token? You can get one from here: https://github.com/settings/tokens') do |q|
         | 
| 49 | 
            +
                  q.required true
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                @config['paToken'] = token
         | 
| 53 | 
            +
                overwrite_config
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                token
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def reset_config_file
         | 
| 59 | 
            +
                File.write(@config_file, '{}')
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              def ensure_config_file_is_created
         | 
| 63 | 
            +
                return if File.exist?(@config_file)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                segments = @config_file.split('/')
         | 
| 66 | 
            +
                paths    = segments[0..-2]
         | 
| 67 | 
            +
                file     = segments[-1]
         | 
| 68 | 
            +
                dir      = paths.join('/')
         | 
| 69 | 
            +
                FileUtils.mkdir_p(dir)
         | 
| 70 | 
            +
                FileUtils.touch(dir + '/' + file)
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                reset_config_file
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              private
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def parse_config
         | 
| 78 | 
            +
                JSON.parse(File.read(@config_file))
         | 
| 79 | 
            +
              rescue StandardError => e
         | 
| 80 | 
            +
                puts "Couldn't parse config file. Make sure the JSON is  correct:\n#{@config_file}"
         | 
| 81 | 
            +
                raise e
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
            end
         | 
    
        data/lib/git.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # this class interfaces with the local `git` command
         | 
| 4 | 
            +
            module Git
         | 
| 5 | 
            +
              class << self
         | 
| 6 | 
            +
                def remote
         | 
| 7 | 
            +
                  `git config --list | grep remote.origin.url`&.strip&.split(':')&.last
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def repository
         | 
| 11 | 
            +
                  remote.split('/').last.chomp('.git')
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def repository_owner
         | 
| 15 | 
            +
                  remote.split('/').first
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def checkout_branch(text)
         | 
| 19 | 
            +
                  branch = text.downcase.gsub(/[^a-zA-Z0-9#]+/, '_')
         | 
| 20 | 
            +
                  output = `git checkout -b #{branch} 2>&1`
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  if output.match?(/A branch named '#{branch}' already exists/)
         | 
| 23 | 
            +
                    `git checkout #{branch}`
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        data/lib/local_cob.rb
    ADDED
    
    | @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #  _                 _    ___ ___  ___
         | 
| 4 | 
            +
            # | |   ___  __ __ _| |  / __/ _ \| _ )
         | 
| 5 | 
            +
            # | |__/ _ \/ _/ _` | | | (_| (_) | _ \
         | 
| 6 | 
            +
            # |____\___/\__\__,_|_|  \___\___/|___/
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # This is the original COB
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            module LocalCOB
         | 
| 12 | 
            +
              def self.run
         | 
| 13 | 
            +
                Git.checkout_branch(ARGV.join(' '))
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
    
        data/lib/navigator.rb
    ADDED
    
    | @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # this class prompts the user for selection and shows "next..." and "prev..."
         | 
| 4 | 
            +
            # when the user can navigate to the next/prev pages.
         | 
| 5 | 
            +
            class Navigator
         | 
| 6 | 
            +
              def initialize(paginator)
         | 
| 7 | 
            +
                @paginator = paginator
         | 
| 8 | 
            +
                @active_index = 1
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def prompt_for_issue_selection
         | 
| 12 | 
            +
                prompt = TTY::Prompt.new(active_color: :cyan)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                if @paginator.no_issues?
         | 
| 15 | 
            +
                  puts 'No issues found.'
         | 
| 16 | 
            +
                  exit 0
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                @selected_index = prompt.select('Select issue:') do |menu|
         | 
| 20 | 
            +
                  menu.default @active_index
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  items.each.with_index(1) do |item, i|
         | 
| 23 | 
            +
                    menu.choice item.to_s, i
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                handle_selection
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def items
         | 
| 31 | 
            +
                ii = @paginator.formatted_issues
         | 
| 32 | 
            +
                ii = ['prev...'] + ii if show_prev?
         | 
| 33 | 
            +
                ii += ['next...'] if show_next?
         | 
| 34 | 
            +
                ii
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              private
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              def show_prev?
         | 
| 40 | 
            +
                @paginator.prev?
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def show_next?
         | 
| 44 | 
            +
                @paginator.next?
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              def handle_selection
         | 
| 48 | 
            +
                choice = items[@selected_index - 1]
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                return choice unless ['next...', 'prev...'].include? choice
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                if choice == 'next...'
         | 
| 53 | 
            +
                  @paginator.inc
         | 
| 54 | 
            +
                  @active_index = 1
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                if choice == 'prev...'
         | 
| 58 | 
            +
                  @paginator.dec
         | 
| 59 | 
            +
                  @active_index = [items.count, 1].max
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                prompt_for_issue_selection
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
            end
         | 
    
        data/lib/paginator.rb
    ADDED
    
    | @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # this class fetches and paginates the issues from github.com
         | 
| 4 | 
            +
            class Paginator
         | 
| 5 | 
            +
              attr_reader :page
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize(credentials)
         | 
| 8 | 
            +
                @credentials = credentials
         | 
| 9 | 
            +
                @page = 1
         | 
| 10 | 
            +
                @cache = {}
         | 
| 11 | 
            +
                @next = {}
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def issues
         | 
| 15 | 
            +
                @cache[@page] ||= begin
         | 
| 16 | 
            +
                  issues = fetch_issues
         | 
| 17 | 
            +
                  @next[@page] = issues.count.positive?
         | 
| 18 | 
            +
                  issues
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def no_issues?
         | 
| 23 | 
            +
                @page == 1 && issues.empty?
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def next?
         | 
| 27 | 
            +
                issues && @next[@page]
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def prev?
         | 
| 31 | 
            +
                @page > 1
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def format_issue(issue)
         | 
| 35 | 
            +
                "#{issue['number']} --- #{issue['title']}"
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def formatted_issues
         | 
| 39 | 
            +
                issues.map { |i| format_issue(i) }
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def dec
         | 
| 43 | 
            +
                @page = [@page - 1, 1].max
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def inc
         | 
| 47 | 
            +
                @page += 1
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              private
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def fetch_issues
         | 
| 53 | 
            +
                _header, body = http_get_issues.split("\r\n\r\n")
         | 
| 54 | 
            +
                data = JSON.parse(body)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                # TODO: move elsewhere
         | 
| 57 | 
            +
                if data.is_a?(Hash) && data['message'] == 'Bad credentials'
         | 
| 58 | 
            +
                  puts 'Your github credentials are wrong.'
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  @credentials.reset_config_file
         | 
| 61 | 
            +
                  exit 1
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                data.select { |i| i['pull_request'].nil? } # ignore pull requests
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def http_get_issues
         | 
| 68 | 
            +
                uname = @credentials.username
         | 
| 69 | 
            +
                token = @credentials.pa_token
         | 
| 70 | 
            +
                `curl -sS -i https://api.github.com/repos/#{Git.repository_owner}/#{Git.repository}/issues?page=#{@page} \
         | 
| 71 | 
            +
                      -u "#{uname}:#{token}" \
         | 
| 72 | 
            +
                      -H "Content-Type: application/json"`
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
    
        data/lib/remote_cob.rb
    ADDED
    
    | @@ -0,0 +1,61 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #
         | 
| 4 | 
            +
            #  ___               _          ___ ___  ___
         | 
| 5 | 
            +
            # | _ \___ _ __  ___| |_ ___   / __/ _ \| _ )
         | 
| 6 | 
            +
            # |   / -_) '  \/ _ \  _/ -_) | (_| (_) | _ \
         | 
| 7 | 
            +
            # |_|_\___|_|_|_\___/\__\___|  \___\___/|___/
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            # this module contain the remote commands
         | 
| 11 | 
            +
            module RemoteCOB
         | 
| 12 | 
            +
              def self.ensure_credentials_and_remote
         | 
| 13 | 
            +
                Credentials.new.ensure_config_file_is_created
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                unless Git.remote
         | 
| 16 | 
            +
                  puts 'could not find remote git repository'
         | 
| 17 | 
            +
                  exit 1
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                unless Git.repository_owner && Git.repository
         | 
| 21 | 
            +
                  puts "couldn't retreive repo and owner from remote: #{remote}"
         | 
| 22 | 
            +
                  exit 1
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              # This is the code for querying github issues and displaying
         | 
| 27 | 
            +
              # a select prompt to the user
         | 
| 28 | 
            +
              module Selection
         | 
| 29 | 
            +
                def self.run
         | 
| 30 | 
            +
                  RemoteCOB.ensure_credentials_and_remote
         | 
| 31 | 
            +
                  paginator = Paginator.new(Credentials.new)
         | 
| 32 | 
            +
                  issue = Navigator.new(paginator).prompt_for_issue_selection
         | 
| 33 | 
            +
                  Git.checkout_branch(issue)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              # This is the code for automatically checking out the matching issue in github
         | 
| 38 | 
            +
              module Fire
         | 
| 39 | 
            +
                def self.run
         | 
| 40 | 
            +
                  RemoteCOB.ensure_credentials_and_remote
         | 
| 41 | 
            +
                  issue_number = ARGV[0].to_i
         | 
| 42 | 
            +
                  paginator = Paginator.new(Credentials.new)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  while paginator.next?
         | 
| 45 | 
            +
                    issue = paginator.issues.detect { |i| i['number'] == issue_number }
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    if issue
         | 
| 48 | 
            +
                      Git.checkout_branch(paginator.format_issue(issue))
         | 
| 49 | 
            +
                      exit 0
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    puts "couldn't find issue on page: #{paginator.page}, fetching next..."
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    paginator.inc
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  puts "couldn't find issue on github."
         | 
| 58 | 
            +
                  exit 1
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
    
        data/lib/version.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: cob
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.15
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Yan
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2019-09-03 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: fileutils
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - ">="
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '0'
         | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - ">="
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: json
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '2.2'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '2.2'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: tty-prompt
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: 0.19.0
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: 0.19.0
         | 
| 55 | 
            +
            description: Format and checkout your branches
         | 
| 56 | 
            +
            email: yan@shiyason.com
         | 
| 57 | 
            +
            executables:
         | 
| 58 | 
            +
            - cob
         | 
| 59 | 
            +
            extensions: []
         | 
| 60 | 
            +
            extra_rdoc_files: []
         | 
| 61 | 
            +
            files:
         | 
| 62 | 
            +
            - bin/cob
         | 
| 63 | 
            +
            - lib/cob.rb
         | 
| 64 | 
            +
            - lib/credentials.rb
         | 
| 65 | 
            +
            - lib/git.rb
         | 
| 66 | 
            +
            - lib/local_cob.rb
         | 
| 67 | 
            +
            - lib/navigator.rb
         | 
| 68 | 
            +
            - lib/paginator.rb
         | 
| 69 | 
            +
            - lib/remote_cob.rb
         | 
| 70 | 
            +
            - lib/string_refinements.rb
         | 
| 71 | 
            +
            - lib/version.rb
         | 
| 72 | 
            +
            homepage: https://github.com/yanshiyason/cob
         | 
| 73 | 
            +
            licenses:
         | 
| 74 | 
            +
            - MIT
         | 
| 75 | 
            +
            metadata: {}
         | 
| 76 | 
            +
            post_install_message: 
         | 
| 77 | 
            +
            rdoc_options: []
         | 
| 78 | 
            +
            require_paths:
         | 
| 79 | 
            +
            - lib
         | 
| 80 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 81 | 
            +
              requirements:
         | 
| 82 | 
            +
              - - ">="
         | 
| 83 | 
            +
                - !ruby/object:Gem::Version
         | 
| 84 | 
            +
                  version: '0'
         | 
| 85 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
              requirements:
         | 
| 87 | 
            +
              - - ">="
         | 
| 88 | 
            +
                - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                  version: '0'
         | 
| 90 | 
            +
            requirements: []
         | 
| 91 | 
            +
            rubygems_version: 3.0.3
         | 
| 92 | 
            +
            signing_key: 
         | 
| 93 | 
            +
            specification_version: 4
         | 
| 94 | 
            +
            summary: Checkout github branches with style
         | 
| 95 | 
            +
            test_files: []
         |