Skip to content

Commit

Permalink
Enable use of Github Enterprise, and fix review command flags
Browse files Browse the repository at this point in the history
Closes #46, #41, #42, #43, #44

LGTM given by: @nhance

Squashed commit of the following:

commit 0e10c209bde4be993c59e2b0fce68982a1bb2f16
Author: Valentino <valentino@reenhanced.com>
Date:   Wed Oct 16 08:35:37 2013 -0400

    Update fetching of comments for new API

commit 0457f72
Author: Valentino <valentino@reenhanced.com>
Date:   Wed Oct 16 08:15:54 2013 -0400

    Include pull request title in squashed merge message

commit 99e1dd6
Author: Valentino <valentino@reenhanced.com>
Date:   Wed Oct 16 08:11:24 2013 -0400

    Cleanup duplicate content in readme, and add a LGTM option

commit 51c3406
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 15 15:16:55 2013 -0400

    [fix] Update to github_api gem caused issue merging comments

commit 6822f78
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 15 15:07:52 2013 -0400

    Updated Readme for new setup command options for local and enterprise

commit 8a79ffd
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 15 11:07:39 2013 -0400

    Initial additions to setup command for project-specific and enterprise

commit 1a15364
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 15 08:36:00 2013 -0400

    Refactor for pull request comments

commit eb16110
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 15 08:11:59 2013 -0400

    [fix] Review flags not being passed

commit d2097cc
Author: Valentino <valentino@reenhanced.com>
Date:   Thu Oct 10 10:37:48 2013 -0400

    [fix] need to move review flags into scope of command

commit 7fa5e39
Author: Valentino <valentino@reenhanced.com>
Date:   Thu Oct 10 10:17:26 2013 -0400

    Don't yet upgrade github_api gem

commit 3a9dca0
Author: Valentino <valentino@reenhanced.com>
Date:   Thu Oct 10 09:09:50 2013 -0400

    Updated readme with instructions on setting up GitHub Enterprise accounts

commit 7842156
Merge: aec25db a8ca369
Author: Valentino <valentino@reenhanced.com>
Date:   Thu Oct 10 08:55:28 2013 -0400

    Merge remote-tracking branch 'origin/master' into vs-github-enterprise

commit aec25db
Author: Valentino <valentino@reenhanced.com>
Date:   Thu Oct 10 08:53:35 2013 -0400

    [fix] Github endpoint and site urls, review command using custom title and message flags, and upgrade gems

commit 7b7b706
Author: Valentino <valentino@reenhanced.com>
Date:   Wed Oct 9 14:26:13 2013 -0400

    Display git commands as they run, and add flags for review title and message

commit 2d4cda5
Author: Valentino <valentino@reenhanced.com>
Date:   Tue Oct 1 14:34:23 2013 -0400

    Enable use of Github Enterprise accounts
  • Loading branch information
Valentino committed Oct 16, 2013
1 parent a8ca369 commit 800874d
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Gemfile
@@ -1,2 +1,2 @@
source :rubygems
source 'https://rubygems.org'
gemspec
56 changes: 31 additions & 25 deletions Gemfile.lock
@@ -1,49 +1,55 @@
PATH
remote: .
specs:
git_reflow (0.3.2)
colorize (= 0.5.8)
github_api (= 0.7.0)
gli (= 2.1.0)
git_reflow (0.3.3)
colorize (= 0.6.0)
github_api (= 0.10.2)
gli (= 2.8.1)
highline
httpclient

GEM
remote: http://rubygems.org/
remote: https://rubygems.org/
specs:
colorize (0.5.8)
faraday (0.8.4)
multipart-post (~> 1.1)
addressable (2.3.5)
colorize (0.6.0)
faraday (0.8.8)
multipart-post (~> 1.2.0)
git (1.2.5)
github_api (0.7.0)
faraday (~> 0.8.1)
hashie (~> 1.2.0)
multi_json (~> 1.3)
nokogiri (~> 1.5.2)
github_api (0.10.2)
addressable
faraday (~> 0.8.7)
hashie (>= 1.2)
multi_json (~> 1.4)
nokogiri (~> 1.6.0)
oauth2
gli (2.1.0)
hashie (1.2.0)
highline (1.6.18)
gli (2.8.1)
hashie (2.0.5)
highline (1.6.19)
httpauth (0.2.0)
httpclient (2.2.7)
httpclient (2.3.4.1)
jeweler (1.8.4)
bundler (~> 1.0)
git (>= 1.2.5)
rake
rdoc
json (1.7.5)
jwt (0.1.5)
multi_json (>= 1.0)
multi_json (1.7.2)
multipart-post (1.1.5)
nokogiri (1.5.6)
oauth2 (0.8.0)
jwt (0.1.8)
multi_json (>= 1.5)
mini_portile (0.5.1)
multi_json (1.8.2)
multi_xml (0.5.5)
multipart-post (1.2.0)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
oauth2 (0.9.2)
faraday (~> 0.8)
httpauth (~> 0.1)
httpauth (~> 0.2)
jwt (~> 0.1.4)
multi_json (~> 1.0)
multi_xml (~> 0.5)
rack (~> 1.2)
rack (1.4.1)
rack (1.5.2)
rake (0.9.2.2)
rdoc (3.12)
json (~> 1.4)
Expand Down
18 changes: 16 additions & 2 deletions README.rdoc
Expand Up @@ -51,8 +51,6 @@ or
$ gem install git_reflow

=== Setup
git reflow setup

On your first install, you'll need to setup your Github credentials. These are used only to get an oauth token that's stored in your global git config.
We use the Github credentials so we can create pull requests from the command line.

Expand All @@ -68,6 +66,22 @@ It looks like this:

This is safe to run multiple times. We don't care.

=== Usage with Github Enterprise
To use GitReflow with a GitHub Enterprise account, there are some additional switches available to the GitReflow setup command. You should be able to use GitReflow for both your Enterprise and non-Enterprise repositories. Because of this, there are a few scenarios that may apply to your usage of GitReflow:

You use a GitHub Enterprise account for the majority of your repositories:
git reflow setup --enterprise
After this, anytime you want to use GitReflow with project that uses a regular GitHub account:
cd replace_with_your_non_enterprise_project_path
git reflow setup --local
This will setup your project's git config with the OAuth token generated from the credentials you provide

If you only use GitHub Enterprise for a select few repositories, you'll first want to setup GitReflow as normal:
git reflow setup
Then for your Enterprise projects, you have to setup GitReflow for each one:
cd replace_with_your_enterprise_project_path
git reflow setup --enterprise --local

=== Starting a feature branch
git reflow start

Expand Down
6 changes: 3 additions & 3 deletions git_reflow.gemspec
Expand Up @@ -24,11 +24,11 @@ spec = Gem::Specification.new do |s|
s.add_development_dependency('rdoc')
s.add_development_dependency('jeweler')

s.add_dependency('colorize', '0.5.8')
s.add_dependency('gli', '2.1.0')
s.add_dependency('colorize', '0.6.0')
s.add_dependency('gli', '2.8.1')
s.add_dependency('highline')
s.add_dependency('httpclient')
s.add_dependency('github_api', '0.7.0')
s.add_dependency('github_api', '0.10.2')

s.post_install_message = "You need to setup your GitHub OAuth token\nPlease run 'git-reflow setup'"
end
135 changes: 104 additions & 31 deletions lib/git_reflow.rb
@@ -1,27 +1,59 @@
require 'rubygems'
require 'git_reflow/version.rb'
require 'open-uri'
require "highline/import"
require 'httpclient'
require 'github_api'
require 'json/pure'
require 'colorize'

require 'git_reflow/version.rb' unless defined?(GitReflow::VERSION)

module GitReflow
extend self

LGTM = /lgtm|looks good to me|:\+1:|:thumbsup:/i
LGTM = /lgtm|looks good to me|:\+1:|:thumbsup:|:shipit:/i

def setup(options = {})
project_only = options.delete(:project_only)
using_enterprise = options.delete(:enterprise)
gh_site_url = github_site_url
gh_api_endpoint = github_api_endpoint

if using_enterprise
gh_site_url = ask("Please enter your Enterprise site URL (e.g. https://github.company.com):")
gh_api_endpoint = ask("Please enter your Enterprise API endpoint (e.g. https://github.company.com/api/v3):")
end

if project_only
set_github_site_url(gh_site_url, local: true)
set_github_api_endpoint(gh_api_endpoint, local: true)
else
set_github_site_url(gh_site_url)
set_github_api_endpoint(gh_api_endpoint)
end

def setup
gh_user = ask("Please enter your GitHub username: ")
gh_password = ask("Please enter your GitHub password (we do NOT store this): ") { |q| q.echo = false }

begin
github = Github.new :basic_auth => "#{gh_user}:#{gh_password}"

github = Github.new do |config|
config.basic_auth = "#{gh_user}:#{gh_password}"
config.endpoint = GitReflow.github_api_endpoint
config.site = GitReflow.github_site_url
config.adapter = :net_http
config.ssl = {:verify => false}
end

authorization = github.oauth.create 'scopes' => ['repo']
oauth_token = authorization[:token]
set_oauth_token(oauth_token)
rescue

if project_only
set_oauth_token(oauth_token, local: true)
else
set_oauth_token(oauth_token)
end
rescue StandardError => e
puts "\nInvalid username or password"
else
puts "\nYour GitHub account was successfully setup!"
Expand All @@ -48,10 +80,10 @@ def review(options = {})
begin
puts push_current_branch
pull_request = github.pull_requests.create(remote_user, remote_repo_name,
'title' => options['title'],
'body' => options['body'],
'head' => "#{remote_user}:#{current_branch}",
'base' => options['base'])
'title' => options['title'],
'body' => options['body'],
'head' => "#{remote_user}:#{current_branch}",
'base' => options['base'])

puts "Successfully created pull request ##{pull_request.number}: #{pull_request.title}\nPull Request URL: #{pull_request.html_url}\n"
ask_to_open_in_browser(pull_request.html_url)
Expand Down Expand Up @@ -86,9 +118,10 @@ def deliver(options = {})
has_comments = has_pull_request_comments?(existing_pull_request)

# if there any comment_authors left, then they haven't given a lgtm after the last commit
if (has_comments and open_comment_authors.empty?) or options['skip-lgtm']
lgtm_authors = comment_authors_for_pull_request(existing_pull_request, :with => LGTM)
commit_message = existing_pull_request[:body] || get_first_commit_message
if (has_comments and open_comment_authors.empty?) or options['skip_lgtm']
lgtm_authors = comment_authors_for_pull_request(existing_pull_request, :with => LGTM)
commit_message = existing_pull_request[:title] || ""
commit_message << (existing_pull_request[:body] || get_first_commit_message)
puts "Merging pull request ##{existing_pull_request.number}: '#{existing_pull_request.title}', from '#{existing_pull_request.head.label}' into '#{existing_pull_request.base.label}'"

update_destination(options['base'])
Expand All @@ -97,15 +130,16 @@ def deliver(options = {})
:pull_request_number => existing_pull_request.number,
:message => "\nCloses ##{existing_pull_request.number}\n\nLGTM given by: @#{lgtm_authors.join(', @')}\n")
append_to_squashed_commit_message(commit_message)
puts "git commit".colorize(:green)
committed = system('git commit')

if committed
puts "Merge complete!"
deploy_and_cleanup = ask "Would you like to push this branch to your remote repo and cleanup your feature branch? "
if deploy_and_cleanup =~ /^y/i
puts `git push origin #{options['base']}`
puts `git push origin :#{feature_branch}`
puts `git branch -D #{feature_branch}`
run_command_with_label "git push origin #{options['base']}"
run_command_with_label "git push origin :#{feature_branch}"
run_command_with_label "git branch -D #{feature_branch}"
puts "Nice job buddy."
end
else
Expand All @@ -126,10 +160,40 @@ def deliver(options = {})
end

def github
@github ||= Github.new :oauth_token => get_oauth_token
@github ||= Github.new do |config|
config.oauth_token = GitReflow.github_oauth_token
config.endpoint = GitReflow.github_api_endpoint
config.site = GitReflow.github_site_url
end
end

def github_api_endpoint
endpoint = `git config --get github.endpoint`.strip
(endpoint.length > 0) ? endpoint : Github::Configuration::DEFAULT_ENDPOINT
end

def get_oauth_token
def set_github_api_endpoint(api_endpoint, options = {local: false})
if options[:local]
`git config --replace-all github.endpoint #{api_endpoint}`
else
`git config --global --replace-all github.endpoint #{api_endpoint}`
end
end

def github_site_url
site_url = `git config --get github.site`.strip
(site_url.length > 0) ? site_url : Github::Configuration::DEFAULT_SITE
end

def set_github_site_url(site_url, options = {local: false})
if options[:local]
`git config --replace-all github.site #{site_url}`
else
`git config --global --replace-all github.site #{site_url}`
end
end

def github_oauth_token
`git config --get github.oauth-token`.strip
end

Expand All @@ -155,32 +219,35 @@ def get_first_commit_message
`git log --pretty=format:"%s" --no-merges -n 1`.strip
end


def set_oauth_token(oauth_token)
`git config --global --replace-all github.oauth-token #{oauth_token}`
def set_oauth_token(oauth_token, options = {})
if options.delete(:local)
`git config --replace-all github.oauth-token #{oauth_token}`
else
`git config --global --replace-all github.oauth-token #{oauth_token}`
end
end

def push_current_branch
`git push origin #{current_branch}`
run_command_with_label "git push origin #{current_branch}"
end

def fetch_destination(destination_branch)
`git fetch origin #{destination_branch}`
run_command_with_label "git fetch origin #{destination_branch}"
end

def update_destination(destination_branch)
origin_branch = current_branch
`git checkout #{destination_branch}`
puts `git pull origin #{destination_branch}`
`git checkout #{origin_branch}`
run_command_with_label "git checkout #{destination_branch}"
run_command_with_label "git pull origin #{destination_branch}"
run_command_with_label "git checkout #{origin_branch}"
end

def merge_feature_branch(options = {})
options[:destination_branch] ||= 'master'
message = options[:message] || "\nCloses ##{options[:pull_request_number]}\n"

`git checkout #{options[:destination_branch]}`
puts `git merge --squash #{options[:feature_branch]}`
run_command_with_label "git checkout #{options[:destination_branch]}"
run_command_with_label "git merge --squash #{options[:feature_branch]}"
# append pull request number to commit message
append_to_squashed_commit_message(message)
end
Expand All @@ -204,10 +271,10 @@ def find_pull_request(options)
end

def pull_request_comments(pull_request)
comments = github.issues.comments.all remote_user, remote_repo_name, pull_request.number
review_comments = github.pull_requests.comments.all remote_user, remote_repo_name, pull_request.number
comments = github.issues.comments.all remote_user, remote_repo_name, issue_id: pull_request.number
review_comments = github.pull_requests.comments.all remote_user, remote_repo_name, request_id: pull_request.number

review_comments + comments
review_comments.to_a + comments.to_a
end

def has_pull_request_comments?(pull_request)
Expand Down Expand Up @@ -297,4 +364,10 @@ def ask_to_open_in_browser(url)
end
end
end

def run_command_with_label(command, options = {})
label_color = options.delete(:color) || :green
puts command.colorize(label_color)
puts `#{command}`
end
end
27 changes: 11 additions & 16 deletions lib/git_reflow/commands/review.rb
Expand Up @@ -3,23 +3,18 @@
command :review do |c|
c.desc 'push your latest feature branch changes to your remote repo and create a pull request against the destination branch'
c.arg_name '[destination_branch] - the branch you want to merge your feature branch into'
c.flag [:t, :title], default_value: 'last commit message'
c.flag [:m, :message], default_value: 'title'
c.action do |global_options,options,args|
review_options = {'base' => nil, 'title' => nil, 'body' => nil}
case args.length
when 3
review_options['base'] = args[0]
review_options['title'] = args[1]
review_options['body'] = args[2]
when 2
review_options['base'] = args[0]
review_options['title'] = args[1]
review_options['body'] = review_options['title']
when 1
review_options['base'] = args[0]
review_options['title'] = review_options['body'] = GitReflow.get_first_commit_message
else
review_options['title'] = review_options['body'] = GitReflow.get_first_commit_message
end
review_options = {
'base' => args[0],
'title' => global_options[:title],
'body' => global_options[:message]
}

This comment has been minimized.

Copy link
@esposito

esposito May 15, 2014

Contributor

The title and mesage options don't seem to be working. Maybe they should be fetched from options instead of global_options as they are defined on the review command as opposed to the global namespace?


review_options['title'] ||= GitReflow.get_first_commit_message
review_options['body'] ||= review_options['title']

GitReflow.review review_options
end
end

0 comments on commit 800874d

Please sign in to comment.