github-cli 0.0.0.pre.a → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/gh +1 -0
- data/bin/github +16 -0
- data/github-cli.gemspec +9 -7
- data/lib/github.rb +4 -0
- data/lib/github/cli.rb +50 -0
- data/lib/github/cli/shell_helpers.rb +15 -0
- data/lib/github/config.rb +4 -0
- data/lib/github/issues.rb +51 -0
- data/lib/github/pull_requests.rb +61 -0
- data/lib/github/repository.rb +118 -0
- data/ruby-version +1 -0
- metadata +84 -5
- data/lib/github/cli/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cec0982a2a34c97923817efef965c2f88ad3608e
|
4
|
+
data.tar.gz: 24c876159601fee0a7e6a1c6fd358979cd579a41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dc6aae525e8e32be33af259dd410458a9b920b5827c5b5015b604ecdc5b54967e90c8af368a36931437d263bdab431c230712a50405ad4abd5d08224fa0b200
|
7
|
+
data.tar.gz: cbd389008fac05979a64cf582028a49512d19686e3f652cb9a6b1cbf95480b91a3d4953f5784ac289d9a0375d8c0c6f5adbc30b44d4cf1799ccd018ccbe3f67d
|
data/bin/gh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github
|
data/bin/github
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
require_relative '../lib/github'
|
6
|
+
require_relative '../lib/github/cli'
|
7
|
+
|
8
|
+
# is github-cli properly configured?
|
9
|
+
Github::CLI.load_config
|
10
|
+
abort 'fatal: Not configured' unless Github::CLI.config
|
11
|
+
|
12
|
+
# are we in a git repository?
|
13
|
+
Github::CLI.configure_repository(Dir.pwd)
|
14
|
+
abort 'fatal: Not a git repository (or any of the parent directories): .git' unless Github::CLI.repository
|
15
|
+
|
16
|
+
Github::CLI.start(ARGV)
|
data/github-cli.gemspec
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
-
lib = File.expand_path('../lib', __FILE__)
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require 'github/cli/version'
|
4
|
-
|
5
1
|
Gem::Specification.new do |s|
|
6
2
|
s.name = 'github-cli'
|
7
|
-
s.version =
|
3
|
+
s.version = '0.0.1'
|
8
4
|
s.date = '2016-04-06'
|
9
5
|
s.summary = 'A cli tool for interacting with github'
|
10
6
|
s.authors = ['Nan Zhong']
|
11
7
|
s.email = 'nan@nine27.com'
|
8
|
+
s.homepage = 'https://github.com/nanzhong/github-cli'
|
12
9
|
s.files = `git ls-files -z`.split("\x0")
|
13
10
|
s.license = 'MIT'
|
14
11
|
|
15
|
-
s.add_dependency
|
16
|
-
s.
|
12
|
+
s.add_dependency 'activesupport'
|
13
|
+
s.add_dependency 'actionview'
|
14
|
+
s.add_dependency 'github_api'
|
15
|
+
s.add_dependency 'thor', '~> 0.19.1'
|
16
|
+
s.add_dependency 'rugged'
|
17
|
+
s.add_development_dependency 'rspec', '~> 3.4.0'
|
18
|
+
s.add_development_dependency 'pry'
|
17
19
|
end
|
data/lib/github.rb
ADDED
data/lib/github/cli.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rugged'
|
2
|
+
require 'thor'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require_relative 'issues'
|
6
|
+
require_relative 'pull_requests'
|
7
|
+
require_relative '../github'
|
8
|
+
|
9
|
+
module Github
|
10
|
+
class CLI < Thor
|
11
|
+
CONFIG_FILE_PATH = File.expand_path('~/.github-cli.yml')
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_reader :repository, :repository_dir, :config
|
15
|
+
|
16
|
+
def configure_repository(dir)
|
17
|
+
return @repository if @repository
|
18
|
+
|
19
|
+
@repository_dir = dir
|
20
|
+
begin
|
21
|
+
@repository = Github::Repository.new(@repository_dir)
|
22
|
+
rescue Github::Repository::InvalidRepositoryDirectory
|
23
|
+
parent_dir = File.expand_path('..', @repository_dir)
|
24
|
+
|
25
|
+
if @repository_dir != parent_dir
|
26
|
+
@repository_dir = parent_dir
|
27
|
+
retry
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_config
|
33
|
+
@config = YAML.load_file(CONFIG_FILE_PATH)
|
34
|
+
@config
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'issues SUBCOMMAND ...ARGS', 'Manage issues'
|
39
|
+
subcommand 'issues', Issues
|
40
|
+
|
41
|
+
desc 'prs SUBCOMMAND ...ARGS', 'Manage pull requests'
|
42
|
+
subcommand 'prs', PullRequests
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def repository
|
47
|
+
self.class.repository
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
require 'active_support/core_ext/object/acts_like'
|
3
|
+
require 'date'
|
4
|
+
require 'thor'
|
5
|
+
|
6
|
+
require_relative 'cli/shell_helpers'
|
7
|
+
|
8
|
+
module Github
|
9
|
+
class Issues < Thor
|
10
|
+
include ActionView::Helpers::DateHelper
|
11
|
+
include Github::CLI::ShellHelpers
|
12
|
+
|
13
|
+
desc 'list', 'List issues'
|
14
|
+
option :page, type: :numeric, default: 1
|
15
|
+
def list
|
16
|
+
issues = Github::CLI.repository.issues(page: options[:page])
|
17
|
+
page_count = issues.count_pages == 0 ? 1 : issues.count_pages
|
18
|
+
|
19
|
+
say "Issues for #{Github::CLI.repository.id} (Page #{options[:page]}/#{page_count})"
|
20
|
+
|
21
|
+
title_width = width_for_percent(0.45)
|
22
|
+
creator_width = width_for_percent(0.15)
|
23
|
+
format_s = "%-8s %-#{title_width}.#{title_width}s %-#{creator_width}s %s"
|
24
|
+
|
25
|
+
say sprintf(format_s, '#', 'Title', 'User', 'Date')
|
26
|
+
issues.each do |issue|
|
27
|
+
say sprintf(format_s, "##{issue.number}", issue.title, issue.user.login, time_ago_in_words(Date.parse(issue.updated_at)) + ' ago')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'show NUMBER', 'Show issue detail'
|
32
|
+
def show(number)
|
33
|
+
issue = Github::CLI.repository.issue(number)
|
34
|
+
|
35
|
+
say "##{number} - #{issue.title}"
|
36
|
+
say sprintf("%#{terminal_width}s", "#{issue.user.login} on #{issue.created_at}")
|
37
|
+
say hr
|
38
|
+
say issue.body + "\n"
|
39
|
+
|
40
|
+
return if issue.comments == 0
|
41
|
+
|
42
|
+
comments = Github::CLI.repository.issue_comments(number)
|
43
|
+
|
44
|
+
comments.each do |comment|
|
45
|
+
say hr
|
46
|
+
say sprintf("%#{terminal_width}s", "#{comment.user.login} on #{comment.created_at}")
|
47
|
+
say comment.body
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
require 'active_support/core_ext/object/acts_like'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require_relative 'cli/shell_helpers'
|
6
|
+
|
7
|
+
module Github
|
8
|
+
class PullRequests < Thor
|
9
|
+
include ActionView::Helpers::DateHelper
|
10
|
+
include Github::CLI::ShellHelpers
|
11
|
+
|
12
|
+
desc 'list', 'List pull requests'
|
13
|
+
option :page, type: :numeric, default: 1
|
14
|
+
def list
|
15
|
+
prs = Github::CLI.repository.pull_requests(page: options[:page])
|
16
|
+
page_count = prs.count_pages == 0 ? 1 : prs.count_pages
|
17
|
+
|
18
|
+
say "Pull requests for #{Github::CLI.repository.id} (Page #{options[:page]}/#{page_count})"
|
19
|
+
|
20
|
+
title_width = width_for_percent(0.45)
|
21
|
+
creator_width = width_for_percent(0.15)
|
22
|
+
format_s = "%-8s %-#{title_width}.#{title_width}s %-#{creator_width}s %s"
|
23
|
+
|
24
|
+
say sprintf(format_s, '#', 'Title', 'User', 'Date')
|
25
|
+
prs.each do |pr|
|
26
|
+
say sprintf(format_s, "##{pr.number}", pr.title, pr.user.login, time_ago_in_words(Date.parse(pr.updated_at)) + ' ago')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'show NUMBER', 'Show pr detail'
|
31
|
+
def show(number)
|
32
|
+
pr = Github::CLI.repository.pull_request(number)
|
33
|
+
|
34
|
+
say "##{number} - #{pr.title}"
|
35
|
+
say sprintf("%#{terminal_width}s", "#{pr.user.login} on #{pr.created_at}")
|
36
|
+
say hr
|
37
|
+
say "#{pr.commits} commits into #{pr.base.ref} from #{pr.head.ref}."
|
38
|
+
say hr
|
39
|
+
say pr.body.body + "\n"
|
40
|
+
|
41
|
+
commits = Github::CLI.repository.pull_request_commits(number)
|
42
|
+
|
43
|
+
message_width = width_for_percent(0.6) - 1
|
44
|
+
commit_width = width_for_percent(0.4)
|
45
|
+
format_s = "%-#{message_width}.#{message_width}s %#{commit_width}.#{commit_width}s"
|
46
|
+
say hr
|
47
|
+
commits.each do |commit|
|
48
|
+
say sprintf(format_s, "#{commit.commit.message}", (commit.author.login + ' - ' + commit.commit.tree.sha[0..8]))
|
49
|
+
end
|
50
|
+
|
51
|
+
files = Github::CLI.repository.pull_request_files(number)
|
52
|
+
|
53
|
+
files.each_with_index do |file, i|
|
54
|
+
say hr
|
55
|
+
say "#{file.filename} - #{file.additions}/#{file.changes}/#{file.deletions}"
|
56
|
+
say hr
|
57
|
+
say "#{file.patch}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'github_api'
|
2
|
+
require 'rugged'
|
3
|
+
|
4
|
+
module Github
|
5
|
+
class Repository
|
6
|
+
InvalidRepositoryDirectory = Class.new(ArgumentError)
|
7
|
+
MissingRemoteOrigin = Class.new(RuntimeError)
|
8
|
+
InvalidRemoteOrigin = Class.new(RuntimeError)
|
9
|
+
|
10
|
+
attr_reader :host, :owner, :name
|
11
|
+
|
12
|
+
def initialize(dir)
|
13
|
+
@repository = Rugged::Repository.new(dir)
|
14
|
+
|
15
|
+
origin = @repository.remotes['origin']
|
16
|
+
raise MissingRemoteOrigin unless origin
|
17
|
+
|
18
|
+
matches = origin.url.match(/\A(git@|https:\/\/)([^\/:]+)(\/|:)([^\/:]+)\/([^\/]+)\.git\z/)
|
19
|
+
unless matches
|
20
|
+
raise InvalidRemoteOrigin, 'Invalid remote url'
|
21
|
+
end
|
22
|
+
|
23
|
+
@host, @owner, @name = matches[2], matches[4], matches[5]
|
24
|
+
unless Github::CLI.config.keys.include?(@host)
|
25
|
+
raise InvalidRemoteOrigin, 'Unrecognized git host'
|
26
|
+
end
|
27
|
+
rescue Rugged::RepositoryError
|
28
|
+
raise InvalidRepositoryDirectory
|
29
|
+
end
|
30
|
+
|
31
|
+
def id
|
32
|
+
"#{owner}/#{name}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def issues(state: 'open', sort: 'updated', direction: 'desc', page: 1, per_page: 10)
|
36
|
+
client.issues.list(
|
37
|
+
user: owner,
|
38
|
+
repo: name,
|
39
|
+
state: state,
|
40
|
+
sort: sort,
|
41
|
+
direction: direction,
|
42
|
+
page: page,
|
43
|
+
per_page: per_page
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def issue(number)
|
48
|
+
client.issues.get(
|
49
|
+
user: owner,
|
50
|
+
repo: name,
|
51
|
+
number: number
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def issue_comments(number)
|
56
|
+
client.issues.comments.list(
|
57
|
+
user: owner,
|
58
|
+
repo: name,
|
59
|
+
number: number
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
def pull_requests(state: 'open', sort: 'updated', direction: 'desc', page: 1, per_page: 10)
|
64
|
+
client.pull_requests.list(
|
65
|
+
user: owner,
|
66
|
+
repo: name,
|
67
|
+
state: state,
|
68
|
+
sort: sort,
|
69
|
+
direction: direction,
|
70
|
+
page: page,
|
71
|
+
per_page: per_page
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def pull_request(number)
|
76
|
+
client.pull_requests.get(
|
77
|
+
user: owner,
|
78
|
+
repo: name,
|
79
|
+
number: number
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
def pull_request_commits(number)
|
84
|
+
client.pull_requests.commits(
|
85
|
+
user: owner,
|
86
|
+
repo: name,
|
87
|
+
number: number
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
def pull_request_files(number)
|
92
|
+
client.pull_requests.files(
|
93
|
+
user: owner,
|
94
|
+
repo: name,
|
95
|
+
number: number
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def pull_request_comments(number)
|
100
|
+
client.pull_requests.comments(
|
101
|
+
user: owner,
|
102
|
+
repo: name,
|
103
|
+
number: number
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
attr_reader :repository
|
110
|
+
|
111
|
+
def client
|
112
|
+
@client ||= Github.new do |c|
|
113
|
+
c.oauth_token = Github::CLI.config[host]['access_token']
|
114
|
+
c.endpoint = "https://#{host}/api/v3/" if host != 'github.com'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.0
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nan Zhong
|
@@ -10,6 +10,48 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2016-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionview
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: github_api
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
13
55
|
- !ruby/object:Gem::Dependency
|
14
56
|
name: thor
|
15
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +66,20 @@ dependencies:
|
|
24
66
|
- - "~>"
|
25
67
|
- !ruby/object:Gem::Version
|
26
68
|
version: 0.19.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rugged
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
27
83
|
- !ruby/object:Gem::Dependency
|
28
84
|
name: rspec
|
29
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +94,20 @@ dependencies:
|
|
38
94
|
- - "~>"
|
39
95
|
- !ruby/object:Gem::Version
|
40
96
|
version: 3.4.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
41
111
|
description:
|
42
112
|
email: nan@nine27.com
|
43
113
|
executables: []
|
@@ -46,9 +116,18 @@ extra_rdoc_files: []
|
|
46
116
|
files:
|
47
117
|
- ".gitignore"
|
48
118
|
- Gemfile
|
119
|
+
- bin/gh
|
120
|
+
- bin/github
|
49
121
|
- github-cli.gemspec
|
50
|
-
- lib/github
|
51
|
-
|
122
|
+
- lib/github.rb
|
123
|
+
- lib/github/cli.rb
|
124
|
+
- lib/github/cli/shell_helpers.rb
|
125
|
+
- lib/github/config.rb
|
126
|
+
- lib/github/issues.rb
|
127
|
+
- lib/github/pull_requests.rb
|
128
|
+
- lib/github/repository.rb
|
129
|
+
- ruby-version
|
130
|
+
homepage: https://github.com/nanzhong/github-cli
|
52
131
|
licenses:
|
53
132
|
- MIT
|
54
133
|
metadata: {}
|
@@ -63,9 +142,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
142
|
version: '0'
|
64
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
144
|
requirements:
|
66
|
-
- - "
|
145
|
+
- - ">="
|
67
146
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
147
|
+
version: '0'
|
69
148
|
requirements: []
|
70
149
|
rubyforge_project:
|
71
150
|
rubygems_version: 2.5.1
|