thegarage-gitx 2.5.1 → 2.6.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/lib/thegarage/gitx/cli/github.rb +133 -0
- data/lib/thegarage/gitx/cli/integrate_command.rb +10 -0
- data/lib/thegarage/gitx/cli/review_command.rb +3 -126
- data/lib/thegarage/gitx/version.rb +1 -1
- data/spec/thegarage/gitx/cli/integrate_command_spec.rb +100 -11
- data/spec/thegarage/gitx/cli/review_command_spec.rb +2 -1
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a1472845b75ae2e8f0c0a41c0ff1d19eda8813af
         | 
| 4 | 
            +
              data.tar.gz: bbd73d4d28d3d416c3ede2ab3b4334feaae97030
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: cc00306173a80368159b1a29cd92ce1b14f00fb11b8f6cae0c08bdda557bb4e1749610bec58f22db924c39f27d4b433788ff902772a14202007ecd2d29785492
         | 
| 7 | 
            +
              data.tar.gz: e9b309a00bae2aef338e1fc05af23618f2be9553cd850252c04b3456f0a8e4664fbe536970c05a0819b3d8b2ee12aa8f2f598fa778bb0e05408d768535eb13c3
         | 
| @@ -0,0 +1,133 @@ | |
| 1 | 
            +
            require 'octokit'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Thegarage
         | 
| 4 | 
            +
              module Gitx
         | 
| 5 | 
            +
                module Cli
         | 
| 6 | 
            +
                  module Github
         | 
| 7 | 
            +
                    CLIENT_URL = 'https://github.com/thegarage/thegarage-gitx'
         | 
| 8 | 
            +
                    PULL_REQUEST_FOOTER = <<-EOS.dedent
         | 
| 9 | 
            +
                      # Pull Request Protips(tm):
         | 
| 10 | 
            +
                      # * Include description of how this change accomplishes the task at hand.
         | 
| 11 | 
            +
                      # * Use GitHub flavored Markdown http://github.github.com/github-flavored-markdown/
         | 
| 12 | 
            +
                      # * Review CONTRIBUTING.md for recommendations of artifacts, links, images, screencasts, etc.
         | 
| 13 | 
            +
                      #
         | 
| 14 | 
            +
                      # This footer will automatically be stripped from the pull request description
         | 
| 15 | 
            +
                    EOS
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    def find_or_create_pull_request(branch)
         | 
| 18 | 
            +
                      pull_request = find_pull_request(branch)
         | 
| 19 | 
            +
                      pull_request ||= begin
         | 
| 20 | 
            +
                        UpdateCommand.new.update
         | 
| 21 | 
            +
                        pull_request = create_pull_request(branch)
         | 
| 22 | 
            +
                        say 'Created pull request: '
         | 
| 23 | 
            +
                        say pull_request.html_url, :green
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                        pull_request
         | 
| 26 | 
            +
                      end
         | 
| 27 | 
            +
                      pull_request
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    # @return [Sawyer::Resource] data structure of pull request info if found
         | 
| 31 | 
            +
                    # @return nil if no pull request found
         | 
| 32 | 
            +
                    def find_pull_request(branch)
         | 
| 33 | 
            +
                      head_reference = "#{github_organization}:#{branch}"
         | 
| 34 | 
            +
                      params = {
         | 
| 35 | 
            +
                        head: head_reference,
         | 
| 36 | 
            +
                        state: 'open'
         | 
| 37 | 
            +
                      }
         | 
| 38 | 
            +
                      pull_requests = github_client.pull_requests(github_slug, params)
         | 
| 39 | 
            +
                      pull_requests.first
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    # @see http://developer.github.com/v3/pulls/
         | 
| 43 | 
            +
                    def create_pull_request(branch)
         | 
| 44 | 
            +
                      say "Creating pull request for "
         | 
| 45 | 
            +
                      say "#{branch} ", :green
         | 
| 46 | 
            +
                      say "against "
         | 
| 47 | 
            +
                      say "#{Thegarage::Gitx::BASE_BRANCH} ", :green
         | 
| 48 | 
            +
                      say "in "
         | 
| 49 | 
            +
                      say github_slug, :green
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                      title = branch
         | 
| 52 | 
            +
                      body = pull_request_body(branch)
         | 
| 53 | 
            +
                      github_client.create_pull_request(github_slug, Thegarage::Gitx::BASE_BRANCH, branch, title, body)
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    def pull_request_body(branch)
         | 
| 57 | 
            +
                      changelog = run_cmd "git log #{Thegarage::Gitx::BASE_BRANCH}...#{branch} --no-merges --pretty=format:'* %s%n%b'"
         | 
| 58 | 
            +
                      description = options[:description]
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      description_template = []
         | 
| 61 | 
            +
                      description_template << "#{description}\n" if description
         | 
| 62 | 
            +
                      description_template << '### Changelog'
         | 
| 63 | 
            +
                      description_template << changelog
         | 
| 64 | 
            +
                      description_template << PULL_REQUEST_FOOTER
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                      body = ask_editor(description_template.join("\n"), repo.config['core.editor'])
         | 
| 67 | 
            +
                      body.gsub(PULL_REQUEST_FOOTER, '').chomp.strip
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    # token is cached in local git config for future use
         | 
| 71 | 
            +
                    # @return [String] auth token stored in git (current repo, user config or installed global settings)
         | 
| 72 | 
            +
                    # @see http://developer.github.com/v3/oauth/#scopes
         | 
| 73 | 
            +
                    # @see http://developer.github.com/v3/#user-agent-required
         | 
| 74 | 
            +
                    def authorization_token
         | 
| 75 | 
            +
                      auth_token = repo.config['thegarage.gitx.githubauthtoken']
         | 
| 76 | 
            +
                      return auth_token unless auth_token.to_s.blank?
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      auth_token = create_authorization
         | 
| 79 | 
            +
                      repo.config['thegarage.gitx.githubauthtoken'] = auth_token
         | 
| 80 | 
            +
                      auth_token
         | 
| 81 | 
            +
                    end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    def create_authorization
         | 
| 84 | 
            +
                      password = ask("Github password for #{username}: ", :echo => false)
         | 
| 85 | 
            +
                      say ''
         | 
| 86 | 
            +
                      client = Octokit::Client.new(login: username, password: password)
         | 
| 87 | 
            +
                      response = client.create_authorization(authorization_request_options)
         | 
| 88 | 
            +
                      response.token
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                    def authorization_request_options
         | 
| 92 | 
            +
                      timestamp = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
         | 
| 93 | 
            +
                      client_name = "The Garage Git eXtensions - #{github_slug} #{timestamp}"
         | 
| 94 | 
            +
                      options = {
         | 
| 95 | 
            +
                        :scopes => ['repo'],
         | 
| 96 | 
            +
                        :note => client_name,
         | 
| 97 | 
            +
                        :note_url => CLIENT_URL
         | 
| 98 | 
            +
                      }
         | 
| 99 | 
            +
                      two_factor_auth_token = ask("Github two factor authorization token (if enabled): ", :echo => false)
         | 
| 100 | 
            +
                      say ''
         | 
| 101 | 
            +
                      options[:headers] = {'X-GitHub-OTP' => two_factor_auth_token} if two_factor_auth_token
         | 
| 102 | 
            +
                      options
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                    def github_client
         | 
| 106 | 
            +
                      @client ||= Octokit::Client.new(:access_token => authorization_token)
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                    # @return [String] github username (ex: 'wireframe') of the current github.user
         | 
| 110 | 
            +
                    # @raise error if github.user is not configured
         | 
| 111 | 
            +
                    def username
         | 
| 112 | 
            +
                      username = repo.config['github.user']
         | 
| 113 | 
            +
                      fail "Github user not configured.  Run: `git config --global github.user 'me@email.com'`" unless username
         | 
| 114 | 
            +
                      username
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                    # @return the github slug for the current repository's remote origin url.
         | 
| 118 | 
            +
                    # @example
         | 
| 119 | 
            +
                    #   git@github.com:socialcast/thegarage/gitx.git #=> thegarage/gitx
         | 
| 120 | 
            +
                    # @example
         | 
| 121 | 
            +
                    #   https://github.com/socialcast/thegarage/gitx.git #=> thegarage/gitx
         | 
| 122 | 
            +
                    def github_slug
         | 
| 123 | 
            +
                      remote = repo.config['remote.origin.url']
         | 
| 124 | 
            +
                      remote.to_s.gsub(/\.git$/,'').split(/[:\/]/).last(2).join('/')
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                    def github_organization
         | 
| 128 | 
            +
                      github_slug.split('/').first
         | 
| 129 | 
            +
                    end
         | 
| 130 | 
            +
                  end
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
            end
         | 
| @@ -2,11 +2,13 @@ require 'thor' | |
| 2 2 | 
             
            require 'thegarage/gitx'
         | 
| 3 3 | 
             
            require 'thegarage/gitx/cli/base_command'
         | 
| 4 4 | 
             
            require 'thegarage/gitx/cli/update_command'
         | 
| 5 | 
            +
            require 'thegarage/gitx/cli/github'
         | 
| 5 6 |  | 
| 6 7 | 
             
            module Thegarage
         | 
| 7 8 | 
             
              module Gitx
         | 
| 8 9 | 
             
                module Cli
         | 
| 9 10 | 
             
                  class IntegrateCommand < BaseCommand
         | 
| 11 | 
            +
                    include Github
         | 
| 10 12 | 
             
                    desc 'integrate', 'integrate the current branch into one of the aggregate development branches (default = staging)'
         | 
| 11 13 | 
             
                    method_option :resume, :type => :string, :aliases => '-r', :desc => 'resume merging of feature-branch'
         | 
| 12 14 | 
             
                    def integrate(integration_branch = 'staging')
         | 
| @@ -23,6 +25,9 @@ module Thegarage | |
| 23 25 |  | 
| 24 26 | 
             
                      integrate_branch(branch, integration_branch) unless options[:resume]
         | 
| 25 27 | 
             
                      checkout_branch branch
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      pull_request = find_or_create_pull_request(branch)
         | 
| 30 | 
            +
                      create_integrate_comment(pull_request)
         | 
| 26 31 | 
             
                    end
         | 
| 27 32 |  | 
| 28 33 | 
             
                    private
         | 
| @@ -83,6 +88,11 @@ module Thegarage | |
| 83 88 | 
             
                      repo.create_branch(target_branch, Thegarage::Gitx::BASE_BRANCH)
         | 
| 84 89 | 
             
                      run_cmd "git push origin #{target_branch}:#{target_branch}"
         | 
| 85 90 | 
             
                    end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    def create_integrate_comment(pull_request)
         | 
| 93 | 
            +
                      comment = '[gitx] integrated into staging :twisted_rightwards_arrows:'
         | 
| 94 | 
            +
                      github_client.add_comment(github_slug, pull_request.number, comment)
         | 
| 95 | 
            +
                    end
         | 
| 86 96 | 
             
                  end
         | 
| 87 97 | 
             
                end
         | 
| 88 98 | 
             
              end
         | 
| @@ -2,21 +2,13 @@ require 'thor' | |
| 2 2 | 
             
            require 'thegarage/gitx'
         | 
| 3 3 | 
             
            require 'thegarage/gitx/cli/base_command'
         | 
| 4 4 | 
             
            require 'thegarage/gitx/cli/update_command'
         | 
| 5 | 
            -
            require ' | 
| 5 | 
            +
            require 'thegarage/gitx/cli/github'
         | 
| 6 6 |  | 
| 7 7 | 
             
            module Thegarage
         | 
| 8 8 | 
             
              module Gitx
         | 
| 9 9 | 
             
                module Cli
         | 
| 10 10 | 
             
                  class ReviewCommand < BaseCommand
         | 
| 11 | 
            -
                     | 
| 12 | 
            -
                    PULL_REQUEST_FOOTER = <<-EOS.dedent
         | 
| 13 | 
            -
                      # Pull Request Protips(tm):
         | 
| 14 | 
            -
                      # * Include description of how this change accomplishes the task at hand.
         | 
| 15 | 
            -
                      # * Use GitHub flavored Markdown http://github.github.com/github-flavored-markdown/
         | 
| 16 | 
            -
                      # * Review CONTRIBUTING.md for recommendations of artifacts, links, images, screencasts, etc.
         | 
| 17 | 
            -
                      #
         | 
| 18 | 
            -
                      # This footer will automatically be stripped from the pull request description
         | 
| 19 | 
            -
                    EOS
         | 
| 11 | 
            +
                    include Github
         | 
| 20 12 |  | 
| 21 13 | 
             
                    desc "review", "Create or update a pull request on github"
         | 
| 22 14 | 
             
                    method_option :description, :type => :string, :aliases => '-d', :desc => 'pull request description'
         | 
| @@ -29,6 +21,7 @@ module Thegarage | |
| 29 21 |  | 
| 30 22 | 
             
                      branch = current_branch.name
         | 
| 31 23 | 
             
                      pull_request = find_or_create_pull_request(branch)
         | 
| 24 | 
            +
                      create_bump_comment(pull_request) if options[:bump]
         | 
| 32 25 | 
             
                      assign_pull_request(pull_request) if options[:assignee]
         | 
| 33 26 |  | 
| 34 27 | 
             
                      run_cmd "open #{pull_request.html_url}" if options[:open]
         | 
| @@ -36,70 +29,6 @@ module Thegarage | |
| 36 29 |  | 
| 37 30 | 
             
                    private
         | 
| 38 31 |  | 
| 39 | 
            -
                    def find_or_create_pull_request(branch)
         | 
| 40 | 
            -
                      pull_request = find_pull_request(branch)
         | 
| 41 | 
            -
                      if pull_request
         | 
| 42 | 
            -
                        create_bump_comment(pull_request) if options[:bump]
         | 
| 43 | 
            -
                        pull_request
         | 
| 44 | 
            -
                      else
         | 
| 45 | 
            -
                        UpdateCommand.new.update
         | 
| 46 | 
            -
                        pull_request = create_pull_request(branch)
         | 
| 47 | 
            -
                        say 'Pull request created: '
         | 
| 48 | 
            -
                        say pull_request.html_url, :green
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                        pull_request
         | 
| 51 | 
            -
                      end
         | 
| 52 | 
            -
                    end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                    # token is cached in local git config for future use
         | 
| 55 | 
            -
                    # @return [String] auth token stored in git (current repo, user config or installed global settings)
         | 
| 56 | 
            -
                    # @see http://developer.github.com/v3/oauth/#scopes
         | 
| 57 | 
            -
                    # @see http://developer.github.com/v3/#user-agent-required
         | 
| 58 | 
            -
                    def authorization_token
         | 
| 59 | 
            -
                      auth_token = repo.config['thegarage.gitx.githubauthtoken']
         | 
| 60 | 
            -
                      return auth_token unless auth_token.to_s.blank?
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                      auth_token = create_authorization
         | 
| 63 | 
            -
                      repo.config['thegarage.gitx.githubauthtoken'] = auth_token
         | 
| 64 | 
            -
                      auth_token
         | 
| 65 | 
            -
                    end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                    def create_authorization
         | 
| 68 | 
            -
                      password = ask("Github password for #{username}: ", :echo => false)
         | 
| 69 | 
            -
                      say ''
         | 
| 70 | 
            -
                      client = Octokit::Client.new(login: username, password: password)
         | 
| 71 | 
            -
                      response = client.create_authorization(authorization_request_options)
         | 
| 72 | 
            -
                      response.token
         | 
| 73 | 
            -
                    end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                    def authorization_request_options
         | 
| 76 | 
            -
                      timestamp = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S%z')
         | 
| 77 | 
            -
                      client_name = "The Garage Git eXtensions - #{github_slug} #{timestamp}"
         | 
| 78 | 
            -
                      options = {
         | 
| 79 | 
            -
                        :scopes => ['repo'],
         | 
| 80 | 
            -
                        :note => client_name,
         | 
| 81 | 
            -
                        :note_url => CLIENT_URL
         | 
| 82 | 
            -
                      }
         | 
| 83 | 
            -
                      two_factor_auth_token = ask("Github two factor authorization token (if enabled): ", :echo => false)
         | 
| 84 | 
            -
                      say ''
         | 
| 85 | 
            -
                      options[:headers] = {'X-GitHub-OTP' => two_factor_auth_token} if two_factor_auth_token
         | 
| 86 | 
            -
                      options
         | 
| 87 | 
            -
                    end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                    # @see http://developer.github.com/v3/pulls/
         | 
| 90 | 
            -
                    def create_pull_request(branch)
         | 
| 91 | 
            -
                      say "Creating pull request for "
         | 
| 92 | 
            -
                      say "#{branch} ", :green
         | 
| 93 | 
            -
                      say "against "
         | 
| 94 | 
            -
                      say "#{Thegarage::Gitx::BASE_BRANCH} ", :green
         | 
| 95 | 
            -
                      say "in "
         | 
| 96 | 
            -
                      say github_slug, :green
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                      title = branch
         | 
| 99 | 
            -
                      body = pull_request_body(branch)
         | 
| 100 | 
            -
                      github_client.create_pull_request(github_slug, Thegarage::Gitx::BASE_BRANCH, branch, title, body)
         | 
| 101 | 
            -
                    end
         | 
| 102 | 
            -
             | 
| 103 32 | 
             
                    def assign_pull_request(pull_request)
         | 
| 104 33 | 
             
                      assignee = options[:assignee]
         | 
| 105 34 | 
             
                      say "Assigning pull request to "
         | 
| @@ -113,18 +42,6 @@ module Thegarage | |
| 113 42 | 
             
                      github_client.update_issue(github_slug, pull_request.number, title, body, options)
         | 
| 114 43 | 
             
                    end
         | 
| 115 44 |  | 
| 116 | 
            -
                    # @return [Sawyer::Resource] data structure of pull request info if found
         | 
| 117 | 
            -
                    # @return nil if no pull request found
         | 
| 118 | 
            -
                    def find_pull_request(branch)
         | 
| 119 | 
            -
                      head_reference = "#{github_organization}:#{branch}"
         | 
| 120 | 
            -
                      params = {
         | 
| 121 | 
            -
                        head: head_reference,
         | 
| 122 | 
            -
                        state: 'open'
         | 
| 123 | 
            -
                      }
         | 
| 124 | 
            -
                      pull_requests = github_client.pull_requests(github_slug, params)
         | 
| 125 | 
            -
                      pull_requests.first
         | 
| 126 | 
            -
                    end
         | 
| 127 | 
            -
             | 
| 128 45 | 
             
                    def create_bump_comment(pull_request)
         | 
| 129 46 | 
             
                      comment_template = []
         | 
| 130 47 | 
             
                      comment_template << '[gitx] review bump :tada:'
         | 
| @@ -135,46 +52,6 @@ module Thegarage | |
| 135 52 | 
             
                      comment = comment.chomp.strip
         | 
| 136 53 | 
             
                      github_client.add_comment(github_slug, pull_request.number, comment)
         | 
| 137 54 | 
             
                    end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                    def github_client
         | 
| 140 | 
            -
                      @client ||= Octokit::Client.new(:access_token => authorization_token)
         | 
| 141 | 
            -
                    end
         | 
| 142 | 
            -
             | 
| 143 | 
            -
                    # @return [String] github username (ex: 'wireframe') of the current github.user
         | 
| 144 | 
            -
                    # @raise error if github.user is not configured
         | 
| 145 | 
            -
                    def username
         | 
| 146 | 
            -
                      username = repo.config['github.user']
         | 
| 147 | 
            -
                      fail "Github user not configured.  Run: `git config --global github.user 'me@email.com'`" unless username
         | 
| 148 | 
            -
                      username
         | 
| 149 | 
            -
                    end
         | 
| 150 | 
            -
             | 
| 151 | 
            -
                    # @return the github slug for the current repository's remote origin url.
         | 
| 152 | 
            -
                    # @example
         | 
| 153 | 
            -
                    #   git@github.com:socialcast/thegarage/gitx.git #=> thegarage/gitx
         | 
| 154 | 
            -
                    # @example
         | 
| 155 | 
            -
                    #   https://github.com/socialcast/thegarage/gitx.git #=> thegarage/gitx
         | 
| 156 | 
            -
                    def github_slug
         | 
| 157 | 
            -
                      remote = repo.config['remote.origin.url']
         | 
| 158 | 
            -
                      remote.to_s.gsub(/\.git$/,'').split(/[:\/]/).last(2).join('/')
         | 
| 159 | 
            -
                    end
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                    def github_organization
         | 
| 162 | 
            -
                      github_slug.split('/').first
         | 
| 163 | 
            -
                    end
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                    def pull_request_body(branch)
         | 
| 166 | 
            -
                      changelog = run_cmd "git log #{Thegarage::Gitx::BASE_BRANCH}...#{branch} --no-merges --pretty=format:'* %s%n%b'"
         | 
| 167 | 
            -
                      description = options[:description]
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                      description_template = []
         | 
| 170 | 
            -
                      description_template << "#{description}\n" if description
         | 
| 171 | 
            -
                      description_template << '### Changelog'
         | 
| 172 | 
            -
                      description_template << changelog
         | 
| 173 | 
            -
                      description_template << PULL_REQUEST_FOOTER
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                      body = ask_editor(description_template.join("\n"), repo.config['core.editor'])
         | 
| 176 | 
            -
                      body.gsub(PULL_REQUEST_FOOTER, '').chomp.strip
         | 
| 177 | 
            -
                    end
         | 
| 178 55 | 
             
                  end
         | 
| 179 56 | 
             
                end
         | 
| 180 57 | 
             
              end
         | 
| @@ -29,8 +29,10 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do | |
| 29 29 | 
             
                  allow(Thegarage::Gitx::Cli::UpdateCommand).to receive(:new).and_return(fake_update_command)
         | 
| 30 30 | 
             
                end
         | 
| 31 31 | 
             
                context 'when integration branch is ommitted and remote branch exists' do
         | 
| 32 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 32 33 | 
             
                  let(:remote_branch_names) { ['origin/staging'] }
         | 
| 33 34 | 
             
                  before do
         | 
| 35 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 34 36 | 
             
                    expect(fake_update_command).to receive(:update)
         | 
| 35 37 |  | 
| 36 38 | 
             
                    expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
         | 
| @@ -40,15 +42,70 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do | |
| 40 42 | 
             
                    expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
         | 
| 41 43 | 
             
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
         | 
| 42 44 |  | 
| 43 | 
            -
                     | 
| 45 | 
            +
                    stub_request(:post, /.*api.github.com.*/).to_return(:status => 201)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    VCR.use_cassette('pull_request_does_exist') do
         | 
| 48 | 
            +
                      cli.integrate
         | 
| 49 | 
            +
                    end
         | 
| 44 50 | 
             
                  end
         | 
| 45 51 | 
             
                  it 'defaults to staging branch' do
         | 
| 46 52 | 
             
                    should meet_expectations
         | 
| 47 53 | 
             
                  end
         | 
| 54 | 
            +
                  it 'posts comment to pull request' do
         | 
| 55 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments").
         | 
| 56 | 
            +
                      with(body: {body: '[gitx] integrated into staging :twisted_rightwards_arrows:'})
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                context 'when a pull request doesnt exist for the feature-branch' do
         | 
| 60 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 61 | 
            +
                  let(:changelog) { '* made some fixes' }
         | 
| 62 | 
            +
                  let(:new_pull_request) do
         | 
| 63 | 
            +
                    {
         | 
| 64 | 
            +
                      html_url: "https://path/to/html/pull/request",
         | 
| 65 | 
            +
                      issue_url: "https://api/path/to/issue/url",
         | 
| 66 | 
            +
                      number: 10,
         | 
| 67 | 
            +
                      head: {
         | 
| 68 | 
            +
                        ref: "branch_name"
         | 
| 69 | 
            +
                      }
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  before do
         | 
| 73 | 
            +
                    allow(cli).to receive(:ask_editor).and_return('description')
         | 
| 74 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 75 | 
            +
                    expect(fake_update_command).to receive(:update).twice
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
         | 
| 78 | 
            +
                    expect(cli).to receive(:run_cmd).with("git branch -D staging", allow_failure: true).ordered
         | 
| 79 | 
            +
                    expect(cli).to receive(:run_cmd).with("git checkout staging").ordered
         | 
| 80 | 
            +
                    expect(cli).to receive(:run_cmd).with("git merge feature-branch").ordered
         | 
| 81 | 
            +
                    expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
         | 
| 82 | 
            +
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    expect(cli).to receive(:run_cmd).with("git log master...feature-branch --no-merges --pretty=format:'* %s%n%b'").and_return("2013-01-01 did some stuff").ordered
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    stub_request(:post, 'https://api.github.com/repos/thegarage/thegarage-gitx/pulls').to_return(:status => 201, :body => new_pull_request.to_json, :headers => {'Content-Type' => 'application/json'})
         | 
| 87 | 
            +
                    stub_request(:post, 'https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments').to_return(:status => 201)
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    VCR.use_cassette('pull_request_does_not_exist') do
         | 
| 90 | 
            +
                      cli.integrate
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
                  it 'creates github pull request' do
         | 
| 94 | 
            +
                    should meet_expectations
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                  it 'creates github comment for integration' do
         | 
| 97 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments").
         | 
| 98 | 
            +
                      with(body: {body: '[gitx] integrated into staging :twisted_rightwards_arrows:'})
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
                  it 'runs expected commands' do
         | 
| 101 | 
            +
                    should meet_expectations
         | 
| 102 | 
            +
                  end
         | 
| 48 103 | 
             
                end
         | 
| 49 104 | 
             
                context 'when staging branch does not exist remotely' do
         | 
| 105 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 50 106 | 
             
                  let(:remote_branch_names) { [] }
         | 
| 51 107 | 
             
                  before do
         | 
| 108 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 52 109 | 
             
                    expect(fake_update_command).to receive(:update)
         | 
| 53 110 |  | 
| 54 111 | 
             
                    expect(repo).to receive(:create_branch).with('staging', 'master')
         | 
| @@ -62,15 +119,24 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do | |
| 62 119 | 
             
                    expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
         | 
| 63 120 | 
             
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
         | 
| 64 121 |  | 
| 65 | 
            -
                     | 
| 122 | 
            +
                    stub_request(:post, /.*api.github.com.*/).to_return(:status => 201)
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                    VCR.use_cassette('pull_request_does_exist') do
         | 
| 125 | 
            +
                      cli.integrate
         | 
| 126 | 
            +
                    end
         | 
| 66 127 | 
             
                  end
         | 
| 67 128 | 
             
                  it 'creates remote aggregate branch' do
         | 
| 68 129 | 
             
                    should meet_expectations
         | 
| 69 130 | 
             
                  end
         | 
| 131 | 
            +
                  it 'posts comment to pull request' do
         | 
| 132 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments")
         | 
| 133 | 
            +
                  end
         | 
| 70 134 | 
             
                end
         | 
| 71 135 | 
             
                context 'when integration branch == prototype and remote branch exists' do
         | 
| 136 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 72 137 | 
             
                  let(:remote_branch_names) { ['origin/prototype'] }
         | 
| 73 138 | 
             
                  before do
         | 
| 139 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 74 140 | 
             
                    expect(fake_update_command).to receive(:update)
         | 
| 75 141 |  | 
| 76 142 | 
             
                    expect(cli).to receive(:run_cmd).with("git fetch origin").ordered
         | 
| @@ -80,11 +146,18 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do | |
| 80 146 | 
             
                    expect(cli).to receive(:run_cmd).with("git push origin HEAD").ordered
         | 
| 81 147 | 
             
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
         | 
| 82 148 |  | 
| 83 | 
            -
                     | 
| 149 | 
            +
                    stub_request(:post, /.*api.github.com.*/).to_return(:status => 201)
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                    VCR.use_cassette('pull_request_does_exist') do
         | 
| 152 | 
            +
                      cli.integrate 'prototype'
         | 
| 153 | 
            +
                    end
         | 
| 84 154 | 
             
                  end
         | 
| 85 155 | 
             
                  it 'runs expected commands' do
         | 
| 86 156 | 
             
                    should meet_expectations
         | 
| 87 157 | 
             
                  end
         | 
| 158 | 
            +
                  it 'posts comment to pull request' do
         | 
| 159 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments")
         | 
| 160 | 
            +
                  end
         | 
| 88 161 | 
             
                end
         | 
| 89 162 | 
             
                context 'when integration branch is not an aggregate branch' do
         | 
| 90 163 | 
             
                  it 'raises an error' do
         | 
| @@ -125,41 +198,57 @@ describe Thegarage::Gitx::Cli::IntegrateCommand do | |
| 125 198 | 
             
                    }
         | 
| 126 199 | 
             
                  end
         | 
| 127 200 | 
             
                  let(:repo) { cli.send(:repo) }
         | 
| 201 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 128 202 | 
             
                  before do
         | 
| 203 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 204 | 
            +
             | 
| 129 205 | 
             
                    expect(fake_update_command).to receive(:update)
         | 
| 130 206 |  | 
| 131 207 | 
             
                    expect(cli).not_to receive(:run_cmd).with("git branch -D staging")
         | 
| 132 208 | 
             
                    expect(cli).not_to receive(:run_cmd).with("git push origin HEAD")
         | 
| 133 209 | 
             
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch")
         | 
| 134 210 |  | 
| 135 | 
            -
                     | 
| 211 | 
            +
                    stub_request(:post, /.*api.github.com.*/).to_return(:status => 201)
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                    VCR.use_cassette('pull_request_does_exist') do
         | 
| 214 | 
            +
                      cli.integrate
         | 
| 215 | 
            +
                    end
         | 
| 136 216 | 
             
                  end
         | 
| 137 217 | 
             
                  it 'does not delete local staging branch' do
         | 
| 138 218 | 
             
                    should meet_expectations
         | 
| 139 219 | 
             
                  end
         | 
| 220 | 
            +
                  it 'posts comment to pull request' do
         | 
| 221 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments")
         | 
| 222 | 
            +
                  end
         | 
| 140 223 | 
             
                end
         | 
| 141 224 | 
             
                context 'with --resume "feature-branch" flag when feature-branch does not exist' do
         | 
| 142 225 | 
             
                  let(:options) do
         | 
| 143 226 | 
             
                    {
         | 
| 144 | 
            -
                      resume: 'feature-branch'
         | 
| 227 | 
            +
                      resume: 'invalid-feature-branch'
         | 
| 145 228 | 
             
                    }
         | 
| 146 229 | 
             
                  end
         | 
| 147 | 
            -
                  let(: | 
| 148 | 
            -
                  let(: | 
| 149 | 
            -
                  let(:local_branch_names) { ['another-feature-branch'] }
         | 
| 230 | 
            +
                  let(:local_branch_names) { ['feature-branch'] }
         | 
| 231 | 
            +
                  let(:authorization_token) { '123123' }
         | 
| 150 232 | 
             
                  before do
         | 
| 233 | 
            +
                    allow(cli).to receive(:authorization_token).and_return(authorization_token)
         | 
| 151 234 | 
             
                    expect(fake_update_command).to receive(:update)
         | 
| 152 | 
            -
                    expect(cli).to receive(:ask).and_return(' | 
| 235 | 
            +
                    expect(cli).to receive(:ask).and_return('feature-branch')
         | 
| 153 236 |  | 
| 154 237 | 
             
                    expect(cli).not_to receive(:run_cmd).with("git branch -D staging")
         | 
| 155 238 | 
             
                    expect(cli).not_to receive(:run_cmd).with("git push origin HEAD")
         | 
| 156 | 
            -
                    expect(cli).to receive(:run_cmd).with("git checkout  | 
| 239 | 
            +
                    expect(cli).to receive(:run_cmd).with("git checkout feature-branch").ordered
         | 
| 157 240 |  | 
| 158 | 
            -
                     | 
| 241 | 
            +
                    stub_request(:post, /.*api.github.com.*/).to_return(:status => 201)
         | 
| 242 | 
            +
                    VCR.use_cassette('pull_request_does_exist') do
         | 
| 243 | 
            +
                      cli.integrate
         | 
| 244 | 
            +
                    end
         | 
| 159 245 | 
             
                  end
         | 
| 160 246 | 
             
                  it 'asks user for feature-branch name' do
         | 
| 161 247 | 
             
                    should meet_expectations
         | 
| 162 248 | 
             
                  end
         | 
| 249 | 
            +
                  it 'posts comment to pull request' do
         | 
| 250 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments")
         | 
| 251 | 
            +
                  end
         | 
| 163 252 | 
             
                end
         | 
| 164 253 | 
             
              end
         | 
| 165 254 | 
             
            end
         | 
| @@ -133,7 +133,8 @@ describe Thegarage::Gitx::Cli::ReviewCommand do | |
| 133 133 | 
             
                    end
         | 
| 134 134 | 
             
                  end
         | 
| 135 135 | 
             
                  it 'posts comment to github' do
         | 
| 136 | 
            -
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments")
         | 
| 136 | 
            +
                    expect(WebMock).to have_requested(:post, "https://api.github.com/repos/thegarage/thegarage-gitx/issues/10/comments").
         | 
| 137 | 
            +
                      with(body: {body: 'comment description'})
         | 
| 137 138 | 
             
                  end
         | 
| 138 139 | 
             
                end
         | 
| 139 140 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: thegarage-gitx
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.6.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Ryan Sonnek
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014-09- | 
| 11 | 
            +
            date: 2014-09-29 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rugged
         | 
| @@ -263,6 +263,7 @@ files: | |
| 263 263 | 
             
            - lib/thegarage/gitx/cli/base_command.rb
         | 
| 264 264 | 
             
            - lib/thegarage/gitx/cli/buildtag_command.rb
         | 
| 265 265 | 
             
            - lib/thegarage/gitx/cli/cleanup_command.rb
         | 
| 266 | 
            +
            - lib/thegarage/gitx/cli/github.rb
         | 
| 266 267 | 
             
            - lib/thegarage/gitx/cli/integrate_command.rb
         | 
| 267 268 | 
             
            - lib/thegarage/gitx/cli/nuke_command.rb
         | 
| 268 269 | 
             
            - lib/thegarage/gitx/cli/release_command.rb
         |