octokom 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44d6e46950110b275a00f47a37b743a493125ca2
4
- data.tar.gz: edb4f1b026404ddd5d7776a518f674dc720fceb7
3
+ metadata.gz: 1e09a35e0cf96d8108161d2e98d3b0bb2eef732d
4
+ data.tar.gz: 53ab6973726062831ce6fdea8e5abfe87eead951
5
5
  SHA512:
6
- metadata.gz: 96dad3cc169a8642c4f035d86bedb3a085994bb1f55035fd9461d43dec9ee245c2b4cff03acbb7ae64b0d8ffcfb08a39735b50c3ac3f144f0b4b3fb2e81ebd67
7
- data.tar.gz: 27ae4cbfee8c372fa952270a3af8d522e2efb8e2682a3107d9ebf1d7854ddf834a0d741645ac665d3d814048bcacd7ab8e2f5802ff9a19429c7f0ed26a440ba9
6
+ metadata.gz: 748cbaac055db47202bfb129952bf8656b96054606599ef11790ec8beeeaf34a189266608cb0c1f72d937aafb978aa84335e7377c3573bc71b969beef4aea3c8
7
+ data.tar.gz: 1ef8d30e2359cb1d5292f876acaeb306dccc11cb52e8a2edaab8ea5094fc7a793228eb3cf7f2e17dec0769caee7eed5cecce7751bad4fbee5c63d305f243383a
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - ruby-head
7
+
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: ruby-head
11
+
12
+ notifications:
13
+ email:
14
+ on_success: change
15
+ on_failure: always
data/README.md CHANGED
@@ -1,3 +1,17 @@
1
1
  # Octokom
2
2
 
3
- Work in progress.
3
+ Work in progress command line application for your every day GitHub workflow.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ $ gem install octokom
9
+ ```
10
+
11
+ ## Examples
12
+
13
+ #### Create a new pull request
14
+
15
+ ```bash
16
+ $ octokom pull-request create --title "New feature"
17
+ ```
@@ -0,0 +1,42 @@
1
+ require 'io/console'
2
+
3
+ module Octokom
4
+ module Authentication
5
+ OCTOKIT_ERRORS = [
6
+ Octokit::BadRequest,
7
+ Octokit::Unauthorized,
8
+ Octokit::Forbidden,
9
+ Octokit::NotFound,
10
+ Octokit::NotAcceptable,
11
+ Octokit::UnprocessableEntity,
12
+ Octokit::InternalServerError,
13
+ Octokit::NotImplemented,
14
+ Octokit::BadGateway,
15
+ Octokit::ServiceUnavailable
16
+ ]
17
+
18
+ def authenticate(&block)
19
+ begin
20
+ yield Octokit::Client.new(login: login, password: password)
21
+ rescue *OCTOKIT_ERRORS => e
22
+ puts "Unable to authenticate user '#{login}' (#{e.class})"
23
+ # TODO print message about how to reenter credentials
24
+ # TODO use custom method instead of puts
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def login
31
+ keychain[:login]
32
+ end
33
+
34
+ def password
35
+ keychain[:password]
36
+ end
37
+
38
+ def keychain
39
+ Octokom::Keychain.create
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ module Octokom
2
+ class Command
3
+ class PullRequest < Clamp::Command
4
+ include Octokom::Authentication
5
+
6
+ subcommand 'create', 'Create a new pull request.' do
7
+ option ['--repo', '-r'], '', 'The GitHub repository. Example: "mjio/octokom"'
8
+ # TODO make ancestor default base
9
+ option ['--base', '-b'], '', 'The branch you want your changes pulled into. Example: "master"', default: 'master'
10
+ option ['--head', '-d'], '', 'The branch where your changes are implemented. Example: "new_feature"'
11
+ # option ['--issue', '-i'], '', 'Create pull request from an existing issue. Example: "123"'
12
+ option ['--title', '-t'], '', 'Title for the pull request.'
13
+ option ['--body', '-b'], '', 'Body for the pull request.'
14
+
15
+ def execute
16
+ authenticate do |client|
17
+ repo ||= Repository.remote_path
18
+ head ||= Repository.current_branch
19
+
20
+ if Repository.unpushed_commits?
21
+ exit unless system 'git push'
22
+ end
23
+
24
+ puts "Create pull request (#{repo}) #{base}:#{head}"
25
+ client.create_pull_request(repo, base, head, title, body)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,4 +1,7 @@
1
1
  module Octokom
2
- module Command
2
+ class Command < Clamp::Command
3
+ autoload :PullRequest, 'octokom/command/pull_request'
4
+
5
+ subcommand 'pull-request', 'Create, update or merge pull requests.', PullRequest
3
6
  end
4
7
  end
@@ -0,0 +1,54 @@
1
+ module Octokom
2
+ class Keychain
3
+ def self.create
4
+ new.find_or_create_keychain
5
+ end
6
+
7
+ def find_or_create_keychain
8
+ if keychain
9
+ {login: keychain.attributes['acct'], password: keychain.password}
10
+ else
11
+ create_octokom_keychain
12
+ find_or_create_keychain
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def keychain
19
+ # TODO make sure this happens only once
20
+ @keychain ||= octokom_keychain || github_keychain
21
+ end
22
+
23
+ def octokom_keychain
24
+ Security::GenericPassword.find(service: 'octokom')
25
+ end
26
+
27
+ def github_keychain
28
+ Security::InternetPassword.find(server: 'github.com')
29
+ end
30
+
31
+ def create_octokom_keychain
32
+ login = ask_for_login
33
+ password = ask_for_password
34
+
35
+ puts
36
+
37
+ save_octokom_keychain(login, password)
38
+ end
39
+
40
+ def ask_for_login
41
+ print 'GitHub Login: '
42
+ STDIN.gets.chomp
43
+ end
44
+
45
+ def ask_for_password
46
+ print 'Password: '
47
+ STDIN.noecho(&:gets).chomp
48
+ end
49
+
50
+ def save_octokom_keychain(login, password)
51
+ Security::GenericPassword.add('octokom', login, password)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,29 @@
1
+ module Octokom
2
+ class Repository
3
+ class << self
4
+ def remote_path
5
+ remote_url[/(\w+\/(\w+|\.)+)\.git$/, 1]
6
+ end
7
+
8
+ def current_branch
9
+ `git rev-parse --abbrev-ref HEAD`.chomp
10
+ end
11
+
12
+ def unpushed_commits?
13
+ !count_unpushed_commits.zero?
14
+ end
15
+
16
+ def count_unpushed_commits
17
+ cmd = 'git log --branches --not --remotes --format=oneline'
18
+ `#{cmd}`.chomp.split('\n').count
19
+ end
20
+
21
+ private
22
+
23
+ def remote_url
24
+ # TODO make "origin" configurable
25
+ `git config --get remote.origin.url`.chomp
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module Octokom
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
data/lib/octokom.rb CHANGED
@@ -1,9 +1,15 @@
1
- require 'octokom/version'
1
+ require 'clamp'
2
+ require 'octokit'
3
+ require 'security'
4
+
5
+ require 'octokom/authentication'
2
6
  require 'octokom/command'
7
+ require 'octokom/keychain'
8
+ require 'octokom/repository'
9
+ require 'octokom/version'
3
10
 
4
11
  module Octokom
5
12
  def self.start(*args)
6
- command = args.shift
7
- Octokom::Command.run(command, args)
13
+ Octokom::Command.run(args)
8
14
  end
9
15
  end
data/octokom.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Octokom::VERSION
9
9
  gem.authors = 'Martin Jagusch'
10
10
  gem.email = '_@mj.io'
11
- gem.description = 'Command line interface for the GitHub API'
11
+ gem.description = 'Command line application for your every day GitHub workflow.'
12
12
  gem.summary = "octokom-#{Octokom::VERSION}"
13
13
  gem.homepage = 'https://github.com/mjio/octokom'
14
14
  gem.license = 'MIT'
@@ -18,6 +18,10 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^spec/})
19
19
  gem.require_paths = ['lib']
20
20
 
21
+ gem.add_dependency 'clamp', '~> 0.6.1'
22
+ gem.add_dependency 'octokit', '2.0.0.rc2'
23
+ gem.add_dependency 'security', '~> 0.1.2'
24
+
21
25
  gem.add_development_dependency 'rake', '~> 10.1.0'
22
26
  gem.add_development_dependency 'rspec', '~> 2.14.1'
23
27
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ class Cmd
4
+ include Octokom::Authentication
5
+ end
6
+
7
+ describe Octokom::Authentication do
8
+ let(:cmd) { Cmd.new }
9
+ let(:keychain) { {login: 'fox', password: 'bacon'} }
10
+
11
+ before do
12
+ allow(cmd).to receive(:keychain) { keychain }
13
+ end
14
+
15
+ it 'authenticates the user' do
16
+ credentials = {login: 'fox', password: 'bacon'}
17
+ expect(Octokit::Client).to receive(:new).with(credentials)
18
+ cmd.authenticate { }
19
+ end
20
+
21
+ it 'handels exceptions' do
22
+ expect(STDOUT).to receive(:puts).with(/Unable to authenticate/)
23
+ cmd.authenticate { raise Octokit::Unauthorized }
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octokom::Command::PullRequest do
4
+ it 'has a `create` sub command' do
5
+ command = Octokom::Command::PullRequest.find_subcommand('create')
6
+ expect(command).to be_kind_of(Clamp::Subcommand::Definition)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octokom::Command do
4
+ it 'has a `pull-request` sub command' do
5
+ command = Octokom::Command.find_subcommand('pull-request')
6
+ expect(command).to be_kind_of(Clamp::Subcommand::Definition)
7
+ end
8
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octokom::Keychain do
4
+ let(:keychain) { double(attributes: {'acct' => 'fox'}, password: 'bacon') }
5
+
6
+ before do
7
+ allow(Security::GenericPassword).to receive(:find) { nil }
8
+ allow(Security::GenericPassword).to receive(:add) { nil }
9
+ allow(Security::InternetPassword).to receive(:find) { nil }
10
+ end
11
+
12
+ context 'using existing `octokom` keychain' do
13
+ before do
14
+ allow(Security::GenericPassword).to receive(:find).with(service: 'octokom') { keychain }
15
+ end
16
+
17
+ it 'finds the keychain' do
18
+ expect(Octokom::Keychain.create).to eq(login: 'fox', password: 'bacon')
19
+ end
20
+ end
21
+
22
+ context 'using existing `github` keychain' do
23
+ before do
24
+ allow(Security::InternetPassword).to receive(:find).with(server: 'github.com') { keychain }
25
+ end
26
+
27
+ it 'finds the keychain' do
28
+ expect(Octokom::Keychain.create).to eq(login: 'fox', password: 'bacon')
29
+ end
30
+ end
31
+
32
+ context 'creating new `github` keychain' do
33
+ before do
34
+ Octokom::Keychain.any_instance.stub(:ask_for_login).and_return('fox')
35
+ Octokom::Keychain.any_instance.stub(:ask_for_password).and_return('bacon')
36
+ allow(STDOUT).to receive(:puts)
37
+ end
38
+
39
+ it 'saves a keychain' do
40
+ pending 'prevent retry'
41
+ expect(Security::GenericPassword).to receive(:add).with('octokom', 'fox', 'bacon')
42
+ Octokom::Keychain.create
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octokom::Repository do
4
+ subject(:repo) { Octokom::Repository }
5
+
6
+ describe '#remote_path' do
7
+ before do
8
+ allow(repo).to receive(:remote_url) { 'https://github.com/mjio/octokom.git' }
9
+ end
10
+
11
+ it 'returns GitHub remote path' do
12
+ expect(repo.remote_path).to eq('mjio/octokom')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Octokom do
4
+ it 'forwards arguments to the Command class' do
5
+ expect(Octokom::Command).to receive(:run).with(['one', 'two'])
6
+ Octokom.start('one', 'two')
7
+ end
8
+ end
metadata CHANGED
@@ -1,15 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octokom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Jagusch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-17 00:00:00.000000000 Z
11
+ date: 2013-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: clamp
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.6.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.6.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: octokit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0.rc2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.0.rc2
41
+ - !ruby/object:Gem::Dependency
42
+ name: security
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.2
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.2
13
55
  - !ruby/object:Gem::Dependency
14
56
  name: rake
15
57
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +80,7 @@ dependencies:
38
80
  - - ~>
39
81
  - !ruby/object:Gem::Version
40
82
  version: 2.14.1
41
- description: Command line interface for the GitHub API
83
+ description: Command line application for your every day GitHub workflow.
42
84
  email: _@mj.io
43
85
  executables:
44
86
  - octokom
@@ -47,16 +89,26 @@ extra_rdoc_files: []
47
89
  files:
48
90
  - .gitignore
49
91
  - .rspec
92
+ - .travis.yml
50
93
  - Gemfile
51
94
  - LICENSE.txt
52
95
  - README.md
53
96
  - Rakefile
54
97
  - bin/octokom
55
98
  - lib/octokom.rb
99
+ - lib/octokom/authentication.rb
56
100
  - lib/octokom/command.rb
101
+ - lib/octokom/command/pull_request.rb
102
+ - lib/octokom/keychain.rb
103
+ - lib/octokom/repository.rb
57
104
  - lib/octokom/version.rb
58
105
  - octokom.gemspec
59
- - spec/octokom.rb
106
+ - spec/octokom/authentication_spec.rb
107
+ - spec/octokom/command/pull_request_spec.rb
108
+ - spec/octokom/command_spec.rb
109
+ - spec/octokom/keychain_spec.rb
110
+ - spec/octokom/repository_spec.rb
111
+ - spec/octokom_spec.rb
60
112
  - spec/spec_helper.rb
61
113
  homepage: https://github.com/mjio/octokom
62
114
  licenses:
@@ -81,8 +133,13 @@ rubyforge_project:
81
133
  rubygems_version: 2.0.3
82
134
  signing_key:
83
135
  specification_version: 4
84
- summary: octokom-0.0.1
136
+ summary: octokom-0.0.2
85
137
  test_files:
86
- - spec/octokom.rb
138
+ - spec/octokom/authentication_spec.rb
139
+ - spec/octokom/command/pull_request_spec.rb
140
+ - spec/octokom/command_spec.rb
141
+ - spec/octokom/keychain_spec.rb
142
+ - spec/octokom/repository_spec.rb
143
+ - spec/octokom_spec.rb
87
144
  - spec/spec_helper.rb
88
145
  has_rdoc:
data/spec/octokom.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Octokom do
4
- it 'splits command and arguments' do
5
- expect(Octokom::Command).to receive(:run).with('one', ['two'])
6
- Octokom.start('one', 'two')
7
- end
8
- end