github-cli 0.0.0.pre.a → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e5de7f936847cdaa04411817f72634fce72162e
4
- data.tar.gz: 334960c7d38d97cf5beace5a51761d029d01150c
3
+ metadata.gz: cec0982a2a34c97923817efef965c2f88ad3608e
4
+ data.tar.gz: 24c876159601fee0a7e6a1c6fd358979cd579a41
5
5
  SHA512:
6
- metadata.gz: 89975220d17ef03c62a03bfa3fc0c53d1aef15a26c58297bc7da5731f819e3aa4f256b39ea0157a07d436fb7c58d5988e07fa4dbdd3d54640d0a999f5d54ac98
7
- data.tar.gz: 26a988189bef67cc8b1ea098cb341ab1dbf2b78764877ac4dfab8e4c0a46ed6cc483ede2d8caf885fbb45ce6bc5449c81a435206d1efb290de600151a11bc5af
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 = Github::CLI::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 'thor', '~> 0.19.1'
16
- s.add_development_dependency 'rspec', '~> 3.4.0'
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
@@ -0,0 +1,4 @@
1
+ require_relative 'github/repository'
2
+
3
+ module Github
4
+ end
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,15 @@
1
+ require 'thor'
2
+
3
+ module Github
4
+ class CLI < Thor
5
+ module ShellHelpers
6
+ def width_for_percent(percent)
7
+ (terminal_width * percent).to_i
8
+ end
9
+
10
+ def hr
11
+ '-' * terminal_width
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ class Config
2
+ def
3
+ end
4
+ 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.0.pre.a
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/cli/version.rb
51
- homepage:
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: 1.3.1
147
+ version: '0'
69
148
  requirements: []
70
149
  rubyforge_project:
71
150
  rubygems_version: 2.5.1
@@ -1,5 +0,0 @@
1
- module Github
2
- module CLI
3
- VERSION = '0.0.0-a'
4
- end
5
- end