github_pulley 0.1.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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in eschews.gemspec
4
+ gemspec
5
+ gem "octokit"
6
+ gem "optitron"
data/README.markdown ADDED
@@ -0,0 +1,32 @@
1
+ # GithubPulley
2
+ ### A ruby gem for creating github pull requests
3
+
4
+ This gem serves no other purpose but to allow github users
5
+ to quickly attach a branch to an issue via a pull request.
6
+ A feature which is currently only available via the API.
7
+
8
+ ### Why
9
+
10
+ Our goal is to use GitHub issues for code reviews and tracking stories. In other words
11
+ we want to eschew using Pivotal Tracker until we're big enough to care.
12
+
13
+ ### Install
14
+
15
+ gem install github-pulley
16
+
17
+ ### Use
18
+
19
+ cd /myproject
20
+ git co -b some_new_feature
21
+ # Add the feature
22
+ git ci -am "Added the ability to send emails"
23
+ pulley attach 4 # push and attach this branch to issue #4
24
+
25
+ Later someone can review the pull request, and merge the code(which also closes
26
+ the issue)
27
+
28
+ ### Respecting Forking
29
+
30
+ This gem respects the github forking process. It assumes that if you fork
31
+ a repository, the remote will be named 'upstream', and pull requests
32
+ will be sent to the upstream repository if it exists.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/pulley ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+ require 'github_pulley'
4
+
5
+ class Runner < Optitron::CLI
6
+
7
+ def pulley
8
+ @pulley ||= GithubPulley.new
9
+ end
10
+
11
+ desc "Attach a branch to an issue with a pull request"
12
+ arg_types :numeric
13
+ def attach(issue)
14
+ pulley.attach_pull_request_to_issue(issue)
15
+ end
16
+
17
+ desc "Create a pull request for the current branch"
18
+ arg_types :string
19
+ opt 'body', :type => :string
20
+ def create(title)
21
+ pulley.create_pull_request(title, params['body'])
22
+ end
23
+
24
+ desc "Get a list of my open issues"
25
+ def open
26
+ pulley.get_open_issues
27
+ end
28
+
29
+ end
30
+
31
+ begin
32
+ Runner.dispatch
33
+ rescue GithubPulley::Error => e
34
+ puts e.message
35
+ rescue Octokit::Error => e
36
+ puts e.message
37
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "github_pulley/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "github_pulley"
7
+ s.version = GithubPulley::VERSION
8
+ s.authors = ["Mark Percival"]
9
+ s.email = ["m@mdp.im"]
10
+ s.homepage = "https://github.com/mdp/pulley"
11
+ s.summary = "Work with Github Issues and Pull Requests"
12
+ s.description = %q{We're small and trying to eschew the use of a bigger project tracker}
13
+
14
+ s.rubyforge_project = "pulley"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ s.add_runtime_dependency 'json'
21
+ s.add_runtime_dependency 'octokit', "= 0.6.4"
22
+ end
@@ -0,0 +1,118 @@
1
+ module GithubPulley
2
+ class Base
3
+ def initialize
4
+ @octokit = Octokit::Client.new(:login => github_user, :token => github_token)
5
+ end
6
+
7
+ def get_open_issues(opts={})
8
+ # Listing by assignee seems to be broken
9
+ all_open_issues.each do |issue|
10
+ print_issue(issue)
11
+ end
12
+ end
13
+
14
+ def attach_pull_request_to_issue(issue, opts={})
15
+ opts = {
16
+ :base => 'master',
17
+ :head => "#{upstream_user||origin_user}:#{current_branch}",
18
+ :branch => current_branch
19
+ }.merge(opts)
20
+ puts "Pushing to #{opts[:branch]} on 'origin'"
21
+ `git push origin #{opts[:branch]}`
22
+ pull_to = forked_from || origin_repo
23
+ # @octokit.create_pull_request_for_issue(repo, base, head, issue, options={})
24
+ # Returns nil if successfull
25
+ @octokit.create_pull_request_for_issue(pull_to, opts[:base], opts[:head], issue)
26
+
27
+ issue_details = @octokit.issue(repo, issue)
28
+ print_issue(issue_details, "Attached to")
29
+ end
30
+
31
+ def create_pull_request(title, body='', opts={})
32
+ opts = {
33
+ :base => 'master',
34
+ :head => "#{upstream_user||origin_user}:#{current_branch}",
35
+ :branch => current_branch
36
+ }.merge(opts)
37
+ puts "Pushing to #{opts[:branch]} on 'origin'"
38
+ `git push origin #{opts[:branch]}`
39
+ pull_to = forked_from || origin_repo
40
+ @octokit.create_pull_request(pull_to, opts[:base], opts[:head], title, body)
41
+ # Returns nil if successfull
42
+ puts "Created new pull request"
43
+ end
44
+
45
+ private
46
+
47
+ def all_open_issues
48
+ @octokit.get("/api/v2/json/issues/list/#{Octokit::Repository.new(repo)}/open")['issues']
49
+ end
50
+
51
+ def github_user
52
+ @github_user ||= `git config github.user`.strip
53
+ raise Error, "Please set github.user" if @github_user.empty?
54
+ @github_user
55
+ end
56
+
57
+ def github_token
58
+ @github_token ||= `git config github.token`.strip
59
+ raise Error, "Please set github.token" if @github_token.empty?
60
+ @github_token
61
+ end
62
+
63
+ def current_branch
64
+ `git name-rev HEAD 2> /dev/null | awk "{ print \\$2 }"`.strip
65
+ end
66
+
67
+ def forked_from
68
+ @octokit.repository(origin_repo)['source']
69
+ end
70
+
71
+ def repo
72
+ @repo ||= upstream_repo || origin_repo
73
+ end
74
+
75
+ def upstream_repo
76
+ unless @upstream_repo
77
+ if r = git('config remote.upstream.url')
78
+ @upstream_repo = r[/\:(.+)\.git$/, 1]
79
+ else
80
+ nil
81
+ end
82
+ end
83
+ @upstream_repo
84
+ end
85
+
86
+ def origin_repo
87
+ unless @origin_repo
88
+ unless r = git('config remote.origin.url')
89
+ raise Error, "Can't find remote 'origin'"
90
+ end
91
+ @origin_repo = r[/\:(.+)\.git$/, 1]
92
+ end
93
+ @origin_repo
94
+ end
95
+
96
+ def origin_user
97
+ origin_repo[/(.+)\/.+/, 1]
98
+ end
99
+
100
+ def upstream_user
101
+ upstream_repo[/(.+)\/.+/, 1] if upstream_repo
102
+ end
103
+
104
+ def print_issue(issue, prefix_msg)
105
+ puts "#{prefix_msg}: ##{issue.number} - #{issue.title}"
106
+ end
107
+
108
+ def git(cmd)
109
+ result = `git #{cmd}`.strip
110
+ if result.length == 0
111
+ false
112
+ else
113
+ result
114
+ end
115
+ end
116
+
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module GithubPulley
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module GithubPulley
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ require "optitron"
2
+ require "octokit"
3
+ require "github_pulley/base"
4
+ require "github_pulley/version"
5
+ require "github_pulley/exception"
6
+
7
+ module GithubPulley
8
+ class << self
9
+ # Alias for GithubPulley::Base.new
10
+ def new
11
+ GithubPulley::Base.new
12
+ end
13
+
14
+ def method_missing(method, *args, &block)
15
+ return super unless new.respond_to?(method)
16
+ new.send(method, *args, &block)
17
+ end
18
+
19
+ def respond_to?(method, include_private=false)
20
+ new.respond_to?(method, include_private) || super(method, include_private)
21
+ end
22
+ end
23
+ end
24
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github_pulley
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Mark Percival
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-02 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: json
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: octokit
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - "="
42
+ - !ruby/object:Gem::Version
43
+ hash: 15
44
+ segments:
45
+ - 0
46
+ - 6
47
+ - 4
48
+ version: 0.6.4
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ description: We're small and trying to eschew the use of a bigger project tracker
52
+ email:
53
+ - m@mdp.im
54
+ executables:
55
+ - pulley
56
+ extensions: []
57
+
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - .gitignore
62
+ - Gemfile
63
+ - README.markdown
64
+ - Rakefile
65
+ - bin/pulley
66
+ - github_pulley.gemspec
67
+ - lib/github_pulley.rb
68
+ - lib/github_pulley/base.rb
69
+ - lib/github_pulley/exception.rb
70
+ - lib/github_pulley/version.rb
71
+ has_rdoc: true
72
+ homepage: https://github.com/mdp/pulley
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project: pulley
101
+ rubygems_version: 1.6.2
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Work with Github Issues and Pull Requests
105
+ test_files: []
106
+