wheelbarrow 0.0.1

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.
@@ -0,0 +1,36 @@
1
+ # Wheelbarrow
2
+
3
+ [![Codeship Status for LuckyThirteen/wheelbarrow](https://www.codeship.io/projects/5f0d9af0-33fe-0132-f9b7-7a72371aeacb/status)](https://www.codeship.io/projects/40700)
4
+
5
+ [![Code Climate](https://codeclimate.com/github/LuckyThirteen/wheelbarrow/badges/gpa.svg)](https://codeclimate.com/github/LuckyThirteen/wheelbarrow)
6
+
7
+ ## About
8
+ Wheelbarrow is a command line utility for sending BitBucket pull requests.
9
+
10
+ ## Installation
11
+ `gem install wheelbarrow`
12
+
13
+ ## Setup
14
+ You need to create an OAuth consumer in BitBucket.
15
+
16
+ When you invoke the command for the first time, it will:
17
+ * ask for your OAuth consumer key
18
+ * ask for your OAuth consumer secret
19
+ * open the OAuth authorization page in the browser
20
+ * ask for the OAuth verification code
21
+ * save your OAuth creditentials in `~/.wheelbarrow/config.yml`
22
+
23
+ ## Usage
24
+
25
+ Usage:
26
+ git bb-pull-request
27
+
28
+ Options:
29
+ -t, [--title=TITLE] # Pull request title
30
+ # Default: [last commit message]
31
+ -d, [--description=DESCRIPTION] # Pull request description
32
+ -b, [--target-branch=TARGET_BRANCH] # Target branch for the pull request
33
+ # Default: master
34
+
35
+ ## License
36
+ [GNU GPL v3](https://github.com/LuckyThirteen/wheelbarrow/blob/master/LICENSE)
@@ -0,0 +1,30 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ desc 'Run specs'
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.verbose = false
8
+ t.rspec_opts = ['--format documentation',
9
+ '-t ~@skip-ci',
10
+ '--failure-exit-code 1']
11
+ end
12
+
13
+ desc 'Run rubocop'
14
+ RuboCop::RakeTask.new(:rubocop) do |t|
15
+ t.fail_on_error = true
16
+ t.verbose = false
17
+ t.formatters = ['RuboCop::Formatter::SimpleTextFormatter']
18
+ t.options = ['-D']
19
+ end
20
+
21
+ desc 'Run things for ci'
22
+ task :ci do
23
+ puts "\033[34mRunning rubocop:\033[0m"
24
+ Rake::Task['rubocop'].invoke
25
+
26
+ puts
27
+
28
+ puts "\033[34mRunning rspec:\033[0m"
29
+ Rake::Task['spec'].invoke
30
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'wheelbarrow/cli'
4
+ Wheelbarrow::CLI.start
@@ -0,0 +1,6 @@
1
+ require_relative 'wheelbarrow/version'
2
+ require_relative 'wheelbarrow/config'
3
+ require_relative 'wheelbarrow/utils'
4
+ require_relative 'wheelbarrow/authenticator'
5
+ require_relative 'wheelbarrow/bucketeer'
6
+ require_relative 'wheelbarrow/cli'
@@ -0,0 +1,54 @@
1
+ require 'singleton'
2
+ require 'oauth'
3
+ require 'launchy'
4
+ require 'thor'
5
+ require_relative 'config'
6
+
7
+ module Wheelbarrow
8
+ class Authenticator
9
+ include Singleton
10
+
11
+ attr_reader :oauth_client
12
+
13
+ def initialize
14
+ @config = Config.instance.fetch
15
+ authenticate
16
+ Config.instance.dump @config
17
+ end
18
+
19
+ private
20
+
21
+ def shell
22
+ @shell ||= Thor::Shell::Basic.new
23
+ end
24
+
25
+ def oauth_consumer
26
+ @consumer ||= OAuth::Consumer.new @config[:consumer_key],
27
+ @config[:consumer_secret],
28
+ Config.instance.bitbucket_oauth_config
29
+ end
30
+
31
+ def fetch_consumer_creditetntials
32
+ @config[:consumer_key] = shell.ask 'Enter your consumer_key:'
33
+ @config[:consumer_secret] = shell.ask 'Enter your consumer secret:'
34
+ end
35
+
36
+ def fetch_token_creditentials
37
+ request_token = oauth_consumer.get_request_token
38
+ Launchy.open request_token.authorize_url
39
+ verifier = shell.ask 'Authorize wheelbarrow and enter the verifier code you are assigned:'
40
+ access_token = request_token.get_access_token oauth_verifier: verifier
41
+ @config[:token] = access_token.token
42
+ @config[:token_secret] = access_token.secret
43
+ end
44
+
45
+ def authenticate
46
+ fetch_consumer_creditetntials unless @config[:consumer_key] && @config[:consumer_secret]
47
+ fetch_token_creditentials unless @config[:token] && @config[:token_secret]
48
+
49
+ @oauth_client ||= OAuth::AccessToken.new oauth_consumer,
50
+ @config[:token],
51
+ @config[:token_secret]
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ require 'singleton'
2
+ require 'json'
3
+ require_relative 'utils'
4
+ require_relative 'authenticator'
5
+
6
+ module Wheelbarrow
7
+ class Bucketeer
8
+ include Singleton
9
+
10
+ def initialize
11
+ @bb_client = Authenticator.instance.oauth_client
12
+ end
13
+
14
+ def send_pull_request!(target_branch: 'master',
15
+ title: Utils.last_commit_message,
16
+ description: '')
17
+ payload = pull_request_body(target_branch, title, description).to_json
18
+
19
+ res = @bb_client.post pull_request_url,
20
+ payload,
21
+ 'Content-Type' => 'application/json'
22
+ JSON.parse res.body
23
+ end
24
+
25
+ private
26
+
27
+ def pull_request_body(target_branch, title, description)
28
+ {
29
+ title: title,
30
+ description: description,
31
+ source: pull_request_source,
32
+ destination: pull_request_destination(target_branch)
33
+ }
34
+ end
35
+
36
+ def pull_request_source
37
+ {
38
+ branch: {
39
+ name: Utils.current_branch
40
+ },
41
+ repository: {
42
+ full_name: Utils.repo_name
43
+ }
44
+ }
45
+ end
46
+
47
+ def pull_request_destination(target_branch)
48
+ {
49
+ branch: {
50
+ name: target_branch
51
+ }
52
+ }
53
+ end
54
+
55
+ def pull_request_url
56
+ "/api/2.0/repositories/#{Utils.repo_name}/pullrequests/"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ require 'wheelbarrow'
2
+
3
+ module Wheelbarrow
4
+ class CLI < Thor
5
+ desc 'version', 'show wheelbarrow version'
6
+ def version
7
+ puts Wheelbarrow::VERSION
8
+ end
9
+ map ['-v', '--version'] => :version
10
+
11
+ desc 'pull-request', 'send a pull request to BitBucket'
12
+ method_option :title,
13
+ aliases: '-t',
14
+ desc: 'Pull request title',
15
+ default: Utils.last_commit_message
16
+ method_option :description,
17
+ aliases: '-d',
18
+ desc: 'Pull request description',
19
+ default: ''
20
+ method_option :target_branch,
21
+ aliases: '-b',
22
+ desc: 'Target branch for the pull request',
23
+ default: 'master'
24
+ def pull_request
25
+ Utils.ensure_within_git! do
26
+ args = { title: options[:title],
27
+ description: options[:description],
28
+ target_branch: options[:target_branch] }
29
+
30
+ pr_response = Bucketeer.instance.send_pull_request! args
31
+ puts pretty_pr_status(pr_response)
32
+ end
33
+ end
34
+ map ['pull-request', 'pr'] => :pull_request
35
+
36
+ default_task :pull_request
37
+
38
+ no_tasks do
39
+ def pretty_pr_status(response)
40
+ if response['error']
41
+ pretty_failed_pr_message response['error']
42
+ else
43
+ pretty_successful_pr_message
44
+ end
45
+ end
46
+
47
+ def pretty_successful_pr_message
48
+ set_color('YAY, pull request submitted successfully!', :green)
49
+ end
50
+
51
+ def pretty_failed_pr_message(errors)
52
+ status = set_color('OH NOES, something went wrong...', :red, :bold)
53
+ message = set_color(" #{errors['message']}", :red)
54
+ field_errors = errors['fields'] || []
55
+ field_messages = field_errors.map do |field, msg|
56
+ set_color(" #{field}: #{msg}", :red)
57
+ end.join "\n"
58
+
59
+ [status, message, field_messages].join "\n"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,45 @@
1
+ require 'singleton'
2
+ require 'yaml'
3
+
4
+ module Wheelbarrow
5
+ class Config
6
+ include Singleton
7
+
8
+ def fetch
9
+ YAML.load_file config_file_path
10
+ rescue Errno::ENOENT
11
+ {}
12
+ end
13
+
14
+ def dump(config)
15
+ create_config_dir
16
+
17
+ File.open(config_file_path, 'w') { |f| YAML.dump config, f }
18
+ end
19
+
20
+ def bitbucket_oauth_config
21
+ { site: 'https://bitbucket.org',
22
+ request_token_path: '/!api/1.0/oauth/request_token',
23
+ authorize_path: '/!api/1.0/oauth/authenticate',
24
+ access_token_path: '/!api/1.0/oauth/access_token' }
25
+ end
26
+
27
+ private
28
+
29
+ def config_file_path
30
+ "#{config_dir}/#{config_file_name}"
31
+ end
32
+
33
+ def config_file_name
34
+ 'config.yml'
35
+ end
36
+
37
+ def config_dir
38
+ File.expand_path('~/.wheelbarrow')
39
+ end
40
+
41
+ def create_config_dir
42
+ Dir.mkdir(config_dir) unless File.directory?(config_dir)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ module Wheelbarrow
2
+ module Utils
3
+ module_function
4
+
5
+ def current_branch
6
+ `git symbolic-ref HEAD`[%r{refs/heads/(.*)}, 1]
7
+ end
8
+
9
+ def git_repository?
10
+ system('git rev-parse')
11
+ end
12
+
13
+ def ensure_within_git!
14
+ git_repository? ? yield : fail('fatal: Not a git repository!')
15
+ end
16
+
17
+ def git_remotes
18
+ `git remote -v`
19
+ end
20
+
21
+ def remote_url
22
+ origin = git_remotes.split("\n")
23
+ .map(&:strip)
24
+ .grep(/^origin.*\(push\)$/)
25
+ .first.to_s
26
+
27
+ URI.extract(origin).first.to_s
28
+ end
29
+
30
+ def repo_name
31
+ repo_name = remote_url.match repo_regex
32
+ fail 'Repository does not seem to be hosted in BitBucket!' if repo_name.nil?
33
+ repo_name[1]
34
+ end
35
+
36
+ def repo_regex
37
+ /bitbucket\.org:(.*)\.git/
38
+ end
39
+
40
+ def last_commit_message
41
+ `git log -1 --pretty=%B`.strip
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Wheelbarrow
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,17 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expectations|
3
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
4
+ end
5
+
6
+ config.mock_with :rspec do |mocks|
7
+ mocks.verify_partial_doubles = true
8
+ end
9
+
10
+ config.filter_run :focus
11
+
12
+ config.default_formatter = 'doc' if config.files_to_run.one?
13
+
14
+ config.order = :random
15
+
16
+ Kernel.srand config.seed
17
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'wheelbarrow/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'wheelbarrow'
9
+ spec.version = Wheelbarrow::VERSION
10
+ spec.authors = ['LuckyThirteen']
11
+ spec.email = ['baloghzsof@gmail.com']
12
+ spec.summary = 'command-line BitBucket pull requests with ease'
13
+ spec.description = 'command-line utility for BitBucket pull requests'
14
+ spec.homepage = 'https://github.com/LuckyThirteen/wheelbarrow'
15
+ spec.license = 'GNU GPL v3'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
23
+ spec.add_runtime_dependency 'oauth', '~> 0.4', '>= 0.4.7'
24
+ spec.add_runtime_dependency 'launchy', '~> 2.4', '>= 2.4.2'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.6', '>= 1.6.2'
27
+ spec.add_development_dependency 'rake', '~> 10.3', '>= 10.3.2'
28
+ spec.add_development_dependency 'rspec', '~> 3.1', '>= 3.1.0'
29
+ spec.add_development_dependency 'nyan-cat-formatter', '~> 0.10', '>= 0.10.1'
30
+ spec.add_development_dependency 'rubocop', '~> 0.26', '>= 0.26.1'
31
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wheelbarrow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - LuckyThirteen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.19.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.19'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.19.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: oauth
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.4'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.4.7
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.4'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.4.7
53
+ - !ruby/object:Gem::Dependency
54
+ name: launchy
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.4'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.4.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.4'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 2.4.2
73
+ - !ruby/object:Gem::Dependency
74
+ name: bundler
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.6'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.6.2
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.6.2
93
+ - !ruby/object:Gem::Dependency
94
+ name: rake
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '10.3'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 10.3.2
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '10.3'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 10.3.2
113
+ - !ruby/object:Gem::Dependency
114
+ name: rspec
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '3.1'
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: 3.1.0
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '3.1'
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 3.1.0
133
+ - !ruby/object:Gem::Dependency
134
+ name: nyan-cat-formatter
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '0.10'
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 0.10.1
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '0.10'
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 0.10.1
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.26'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 0.26.1
163
+ type: :development
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '0.26'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 0.26.1
173
+ description: command-line utility for BitBucket pull requests
174
+ email:
175
+ - baloghzsof@gmail.com
176
+ executables:
177
+ - git-bb-pull-request
178
+ extensions: []
179
+ extra_rdoc_files: []
180
+ files:
181
+ - ".gitignore"
182
+ - ".rspec"
183
+ - ".rubocop.yml"
184
+ - ".ruby-gemset"
185
+ - ".ruby-version"
186
+ - Gemfile
187
+ - LICENSE
188
+ - README.markdown
189
+ - Rakefile
190
+ - bin/git-bb-pull-request
191
+ - lib/wheelbarrow.rb
192
+ - lib/wheelbarrow/authenticator.rb
193
+ - lib/wheelbarrow/bucketeer.rb
194
+ - lib/wheelbarrow/cli.rb
195
+ - lib/wheelbarrow/config.rb
196
+ - lib/wheelbarrow/utils.rb
197
+ - lib/wheelbarrow/version.rb
198
+ - spec/spec_helper.rb
199
+ - wheelbarrow.gemspec
200
+ homepage: https://github.com/LuckyThirteen/wheelbarrow
201
+ licenses:
202
+ - GNU GPL v3
203
+ metadata: {}
204
+ post_install_message:
205
+ rdoc_options: []
206
+ require_paths:
207
+ - lib
208
+ required_ruby_version: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ required_rubygems_version: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - ">="
216
+ - !ruby/object:Gem::Version
217
+ version: '0'
218
+ requirements: []
219
+ rubyforge_project:
220
+ rubygems_version: 2.2.2
221
+ signing_key:
222
+ specification_version: 4
223
+ summary: command-line BitBucket pull requests with ease
224
+ test_files:
225
+ - spec/spec_helper.rb