gish 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +69 -0
- data/Rakefile +1 -0
- data/bin/gish +5 -0
- data/gish.gemspec +26 -0
- data/lib/gish/cli/comments.rb +30 -0
- data/lib/gish/cli/labels.rb +32 -0
- data/lib/gish/commands/assignee.rb +10 -0
- data/lib/gish/commands/comment.rb +17 -0
- data/lib/gish/commands/issue.rb +67 -0
- data/lib/gish/commands/label.rb +27 -0
- data/lib/gish/configuration.rb +68 -0
- data/lib/gish/helpers/input_helpers.rb +27 -0
- data/lib/gish/helpers/terminal_helpers.rb +20 -0
- data/lib/gish/presentation/comment.rb +18 -0
- data/lib/gish/presentation/issue.rb +46 -0
- data/lib/gish/presentation/label.rb +12 -0
- data/lib/gish/runner.rb +114 -0
- data/lib/gish/version.rb +3 -0
- data/lib/gish.rb +37 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 88e892754c58c48d94420e68a0d72518d1764db6
|
4
|
+
data.tar.gz: 42cfa7282ce8820f148ac2f0929b9e03ff304de6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc489d2112e59c0ce29cb09b913e7cb68ea78f853e315e9d1257a9ef3a7e925e67e80a3cfb810e7413aff9211b9bbacd33504ac6d8d4140cc92bc32e919c86c5
|
7
|
+
data.tar.gz: 1ae384ef55e4687054533ed97450b8727b72aaad8b08e06e09ef401cfaa058d2c6836c030525a2b53405cbed74f3b5924dba3260ede5aa0ab0480055f454b0a6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Baris Balic
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Gish
|
2
|
+
|
3
|
+
Github Issues on the command-line. Not much else to say about it.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install gish
|
8
|
+
|
9
|
+
When you first use Gish you will be prompted for your github credentials, and asked if you would like to use Gish with private repositories. This information is used to create a [personal access token](https://github.com/blog/1509-personal-api-tokens) for your Github account, this token will then be stored and used instead of your credentials.
|
10
|
+
|
11
|
+
You may also want to consider setting the environment variables `GISH_EDITOR` and `GISH_BROWSER`. These will be used to launch an editor or browser respectively when the need arises. When they are not set, Gish defaults to `EDITOR` and `BROWSER`, and finally `vi` and `open`.
|
12
|
+
|
13
|
+
Why 'open'? Because I'm an OSX user and there's no *nix analogue as far as I can tell.
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Gish has too many commands, subcommands and options to list here, thankfully it's uses the excellent [thor](http://whatisthor.com/) under the hood so you can use the help command like so to see your options...
|
18
|
+
|
19
|
+
```Bash
|
20
|
+
$ gish help
|
21
|
+
$ gish subcommand help
|
22
|
+
```
|
23
|
+
|
24
|
+
Some commands may allow for excessive input, namely opening and commenting on issues. In these cases, if you don't specify a message with "-m", Gish will spawn an editor for you to write the message in.
|
25
|
+
|
26
|
+
Oh, one more thing! Gish expects you to be running against the repository under the origin remote, if you want to override this, use -r/--repository, like so:
|
27
|
+
|
28
|
+
```shell
|
29
|
+
$ gish list -r andrew/24pullrequests
|
30
|
+
```
|
31
|
+
|
32
|
+
### Examples
|
33
|
+
|
34
|
+
Here are some examples to get you started.
|
35
|
+
|
36
|
+
|command|outcome|
|
37
|
+
|-------|-------|
|
38
|
+
|gish list | List 20 issues|
|
39
|
+
|gish show 1 | Show issue #1|
|
40
|
+
|gish show 1 -i| Show issue #1 and include comments|
|
41
|
+
|gish comment 1 -m ":+1"| Comment on issue #1|
|
42
|
+
|gish comment 1| Comment on issue #1 using an editor|
|
43
|
+
|gish close 1| Close issue #1|
|
44
|
+
|gish label 1 such-feature| Add the label such-feature to issue #1|
|
45
|
+
|
46
|
+
When listing issues, the number of comments on an issue will be displayed at the end of a line.
|
47
|
+
|
48
|
+
```
|
49
|
+
#9 barisbalic Emoji! [2]
|
50
|
+
#8 barisbalic Fix editor input for open command [0]
|
51
|
+
#7 barisbalic Support API paging [0]
|
52
|
+
#6 barisbalic Current repository check is lame [1]
|
53
|
+
#5 barisbalic Format issue and comment times [0]
|
54
|
+
#4 barisbalic Enhance terminal output [0]
|
55
|
+
#2 barisbalic Check issue assignee [0]
|
56
|
+
#1 barisbalic Add config subcommand [0]
|
57
|
+
```
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
Contributions are very welcome, whether it's refactoring or taking care of the [issues](http://github.com/gish/issues).
|
64
|
+
|
65
|
+
1. Fork it
|
66
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
67
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
68
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
69
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/gish
ADDED
data/gish.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gish/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "gish"
|
8
|
+
spec.version = Gish::VERSION
|
9
|
+
spec.authors = ["Baris Balic"]
|
10
|
+
spec.email = ["leafybasil@gmail.com"]
|
11
|
+
spec.description = %q{Gish brings Github Issues to the command-line.}
|
12
|
+
spec.summary = %q{A fairly functional command-line interface for the most excellent Gitub Issues.}
|
13
|
+
spec.homepage = "http://github.com/barisbalic/gish"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_dependency 'octokit'
|
25
|
+
spec.add_dependency 'thor'
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Gish
|
2
|
+
module Cli
|
3
|
+
class Comments < Thor
|
4
|
+
no_tasks do
|
5
|
+
include InputHelpers
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'list ISSUE_NUMBER', 'List all comments for the issue.'
|
9
|
+
def list(issue_number)
|
10
|
+
puts Gish.comments(issue_number)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'update COMMENT_NUMBER', 'Update a comment.'
|
14
|
+
method_option :message, :aliases => '-m', :type => :string, :desc => 'Specify the message inline.'
|
15
|
+
def update(comment_number)
|
16
|
+
existing_comment = Gish.issue_comment(comment_number).body
|
17
|
+
message = capture_editor_input(existing_comment) unless options.message? && options.message != 'message'
|
18
|
+
message ||= options.message
|
19
|
+
Gish.update_comment(comment_number, message)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'delete COMMENT_NUMBER', 'Delete a comment.'
|
23
|
+
method_option :force, :type => :boolean, :aliases => '-f', :desc => 'Force yes, no prompt!'
|
24
|
+
def delete(comment_number)
|
25
|
+
return unless options.force? || confirm('Are you sure you want to delete this comment? (y/n)... ')
|
26
|
+
Gish.delete_comment(comment_number)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Gish
|
2
|
+
module Cli
|
3
|
+
class Labels < Thor
|
4
|
+
no_tasks do
|
5
|
+
include InputHelpers
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'list', 'List all labels for this repository.'
|
9
|
+
def list
|
10
|
+
puts Gish.list_labels
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'create NAME [color]', 'Create a new label for this repository.'
|
14
|
+
def create(name, color=nil)
|
15
|
+
Gish.create_label(name, color)
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'update NAME [color]', 'Update an existing label.'
|
19
|
+
def update(name, title, color=nil)
|
20
|
+
Gish.update_label(name, title, color)
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'delete NAME', 'Delete an existing label.'
|
24
|
+
method_option :force, :type => :boolean, :aliases => '-f', :desc => 'Force yes, no prompt!'
|
25
|
+
def delete(name, *names)
|
26
|
+
return unless options.force? || confirm('Are you sure you want to delete this label(s)? (y/n)... ')
|
27
|
+
names << name
|
28
|
+
Gish.delete_labels(names)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Gish
|
2
|
+
module Commands
|
3
|
+
module Comment
|
4
|
+
def update_comment(comment_number, comment)
|
5
|
+
request { client.update_comment(Gish.repository, comment_number, comment) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete_comment(comment_number)
|
9
|
+
request { client.delete_comment(Gish.repository, comment_number) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def issue_comment(comment_number)
|
13
|
+
request { client.issue_comment(Gish.repository, comment_number) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Gish
|
2
|
+
module Commands
|
3
|
+
module Issue
|
4
|
+
def list(options)
|
5
|
+
issues = request { client.issues(Gish.repository, options) }
|
6
|
+
issues.map {|i| Gish::Issue.new(i).headline }
|
7
|
+
end
|
8
|
+
|
9
|
+
def show(issue_number)
|
10
|
+
issue = request { client.issue(Gish.repository, issue_number) }
|
11
|
+
Gish::Issue.new(issue) if issue
|
12
|
+
end
|
13
|
+
|
14
|
+
def reopen(issue_number)
|
15
|
+
request { client.reopen_issue(Gish.repository, issue_number) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(title, body, labels=[], assignee)
|
19
|
+
options = {:labels => labels}
|
20
|
+
options.merge!({:assignee => assignee}) unless assignee.nil?
|
21
|
+
request { client.create_issue(Gish.repository, title, body, options) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def close(issue_number, comment=nil)
|
25
|
+
request { client.close_issue(Gish.repository, issue_number)}
|
26
|
+
end
|
27
|
+
|
28
|
+
def comments(issue_number)
|
29
|
+
comments = request { client.issue_comments(Gish.repository, issue_number) }
|
30
|
+
comments.map {|c| Gish::Comment.new(c) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def comment(issue_number, comment)
|
34
|
+
request { client.add_comment(Gish.repository, issue_number, comment) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def label(issue_number, label, labels=[])
|
38
|
+
labels << label
|
39
|
+
sanitized_labels = labels.map{|l| l.strip }
|
40
|
+
request { client.add_labels_to_an_issue(Gish.repository, issue_number, sanitized_labels) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def unlabel(issue_number, label, labels=[])
|
44
|
+
labels << label
|
45
|
+
labels.each do |l|
|
46
|
+
request { client.remove_label(Gish.repository, issue_number, l.strip) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def assign(issue_number, user_login)
|
51
|
+
options = {:assignee => user_login}
|
52
|
+
issue = request { client.issue(Gish.repository, issue_number) }
|
53
|
+
request { client.update_issue(Gish.repository, issue_number, issue.title, issue.body, options) }
|
54
|
+
end
|
55
|
+
|
56
|
+
def unassign(issue_number)
|
57
|
+
issue = request { client.issue(Gish.repository, issue_number) }
|
58
|
+
request { client.update_issue(Gish.repository, issue_number, issue.title, issue.body, {:assignee => ''}) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def browse(issue_number=nil)
|
62
|
+
command = "#{Gish.browser} '#{Gish.github_url}/issues/#{issue_number}'"
|
63
|
+
%x{#{command}}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Gish
|
2
|
+
module Commands
|
3
|
+
module Label
|
4
|
+
def list_labels
|
5
|
+
labels = request { client.labels(Gish.repository) }
|
6
|
+
labels.map{|l| Gish::Label.new(l) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def delete_labels(labels)
|
10
|
+
labels.each do |l|
|
11
|
+
request { client.delete_label!(Gish.repository, l) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def update_label(name, new_name, color)
|
16
|
+
opts = {:name => new_name}
|
17
|
+
opts[:color] = color unless color.nil?
|
18
|
+
|
19
|
+
request { client.update_label(Gish.repository, name, opts) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_label(name, color=nil)
|
23
|
+
request { client.add_label(Gish.repository, name, color) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
|
3
|
+
module Gish
|
4
|
+
module Configuration
|
5
|
+
include InputHelpers
|
6
|
+
attr_accessor :editor, :access_token, :repository, :browser
|
7
|
+
|
8
|
+
def self.extended(base)
|
9
|
+
base.defaults
|
10
|
+
end
|
11
|
+
|
12
|
+
def editor=(editor)
|
13
|
+
@editor = editor
|
14
|
+
end
|
15
|
+
|
16
|
+
def access_token=(access_token)
|
17
|
+
@access_token = access_token
|
18
|
+
end
|
19
|
+
|
20
|
+
def repository=(repository)
|
21
|
+
@repository = repository
|
22
|
+
end
|
23
|
+
|
24
|
+
def browser=(browser)
|
25
|
+
@browser = browser
|
26
|
+
end
|
27
|
+
|
28
|
+
def github_url
|
29
|
+
"http://github.com/#{@repository}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def defaults
|
33
|
+
@config_file = File.expand_path('~/.gish')
|
34
|
+
self.access_token = retrieve_or_generate_token
|
35
|
+
self.editor = (ENV['GISH_EDITOR'] || ENV['EDITOR']) || 'vi'
|
36
|
+
self.browser = (ENV['GISH_BROWSER'] || ENV['BROWSER']) || 'open'
|
37
|
+
self.repository = default_repository
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def default_repository
|
43
|
+
url = %x(git config --get remote.origin.url)
|
44
|
+
url.match(/:(.*)\.git/)[1] rescue ''
|
45
|
+
end
|
46
|
+
|
47
|
+
def retrieve_or_generate_token
|
48
|
+
return File.read(@config_file) if File.exists?(@config_file)
|
49
|
+
|
50
|
+
puts "(step 1 of 2) Gish needs your login details to create a personal use token. This only happens once and your credentials will not be stored."
|
51
|
+
username = prompt('Username: ')
|
52
|
+
password = prompt('Password: ')
|
53
|
+
|
54
|
+
puts "(step 2 of 2) Gish works with public repositories by default, but if you want to use it with We are about to create a token, but first you need to decide if you want to use Gish with private repositories, we need to know now!"
|
55
|
+
private_access = confirm("Use with private repositories? (y/n) ")
|
56
|
+
|
57
|
+
github = Octokit::Client.new(:login => username, :password => password)
|
58
|
+
options = {
|
59
|
+
:note => 'Gish: Github Issues on the command-line.',
|
60
|
+
:note_url => 'http://github.com/barisbalic/gish/'
|
61
|
+
}
|
62
|
+
options.merge!({:scopes => ['repo']}) if private_access
|
63
|
+
authorization = github.create_authorization(options)
|
64
|
+
|
65
|
+
File.open(@config_file, 'w+') { |file| file.write(authorization.token) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Gish
|
4
|
+
module InputHelpers
|
5
|
+
def prompt(message)
|
6
|
+
print message
|
7
|
+
STDIN.gets.chomp
|
8
|
+
end
|
9
|
+
|
10
|
+
def confirm(message)
|
11
|
+
print message
|
12
|
+
STDIN.gets.chomp == 'y'
|
13
|
+
end
|
14
|
+
|
15
|
+
def capture_editor_input(content=nil)
|
16
|
+
unique_file = "/tmp/#{SecureRandom.hex}"
|
17
|
+
File.open(unique_file, 'w+'){|f| f.write(content) }
|
18
|
+
|
19
|
+
command = "#{Gish.editor} #{unique_file} < `tty` > `tty`"
|
20
|
+
%x{#{command}}
|
21
|
+
ouput = %x{cat #{unique_file}}
|
22
|
+
|
23
|
+
File.delete(unique_file)
|
24
|
+
ouput.length < 1 ? nil : ouput
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Gish
|
2
|
+
module TerminalHelpers
|
3
|
+
def console_width
|
4
|
+
size = %x{stty size}
|
5
|
+
size.split(' ').last
|
6
|
+
end
|
7
|
+
|
8
|
+
def bold(message)
|
9
|
+
"\033[1m#{message}\033[0m"
|
10
|
+
end
|
11
|
+
|
12
|
+
def underline(message)
|
13
|
+
"\033[4m#{message}\033[0m"
|
14
|
+
end
|
15
|
+
|
16
|
+
def format_label(label)
|
17
|
+
"\033[30m\033[47m #{label} \033[0m"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gish
|
2
|
+
class Comment
|
3
|
+
include TerminalHelpers
|
4
|
+
|
5
|
+
def initialize(github_comment)
|
6
|
+
@body = github_comment.body.gsub("\r\n", "\n")
|
7
|
+
@user = github_comment.user.login
|
8
|
+
@id = github_comment.id
|
9
|
+
@created_at = github_comment.created_at
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
output = "\n#{@id} #{bold(@user)} commented on #{@created_at}"
|
14
|
+
output << "\n\"#{@body}\"\n"
|
15
|
+
output
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Gish
|
2
|
+
class Issue
|
3
|
+
include TerminalHelpers
|
4
|
+
|
5
|
+
def initialize(github_issue)
|
6
|
+
@url = github_issue.html_url
|
7
|
+
@number = github_issue.number.to_s
|
8
|
+
@state = github_issue.state
|
9
|
+
@title = github_issue.title
|
10
|
+
@body = github_issue.body
|
11
|
+
@labels = github_issue.labels
|
12
|
+
@user = github_issue.user.login
|
13
|
+
@comment_count = github_issue.comments
|
14
|
+
@assignee = github_issue.assignee.login rescue nil
|
15
|
+
@created_at = github_issue.created_at
|
16
|
+
end
|
17
|
+
|
18
|
+
def headline
|
19
|
+
user = @user.ljust(20, ' ')
|
20
|
+
title = short_title.ljust(70, ' ')
|
21
|
+
number = @number.ljust(5, ' ')
|
22
|
+
"##{number} #{bold(user)} #{title} [#{@comment_count}]"
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
output = underline("##{@number} #{@title}")
|
27
|
+
output << " [#{@state}]"
|
28
|
+
output << "\nOpened by #{bold(@user)} on #{@created_at}"
|
29
|
+
output << "\nAssigned to #{bold(@assignee)}" unless @assignee.nil?
|
30
|
+
output << "\n\n#{@body}\n\n"
|
31
|
+
output << "#{label_names.join(' ')}" unless @labels.empty?
|
32
|
+
output
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def short_title
|
38
|
+
return "#{@title}" unless @title.length > 60
|
39
|
+
"#{@title[0..69]}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def label_names
|
43
|
+
@labels.map{ |l| format_label(l.name) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/gish/runner.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
require_relative 'cli/labels'
|
4
|
+
require_relative 'cli/comments'
|
5
|
+
|
6
|
+
module Gish
|
7
|
+
class Runner < Thor
|
8
|
+
no_tasks do
|
9
|
+
include InputHelpers
|
10
|
+
end
|
11
|
+
|
12
|
+
class_option :repository, :type=> :string , :aliases => '-r', :desc => 'Specify the repository.'
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
return unless options.repository? && options.repository != 'repository'
|
16
|
+
Gish.repository = options.repository
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'labels SUBCOMMAND ...ARGS', 'Manage labels for the repository.'
|
20
|
+
subcommand 'labels', Gish::Cli::Labels
|
21
|
+
|
22
|
+
desc 'label ISSUE_NUMBER LABEL [LABEL]...', 'Add one or more labels to an issue.'
|
23
|
+
def label(issue_number, label, *more_labels)
|
24
|
+
Gish.label(issue_number, label, more_labels)
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'unlabel ISSUE_NUMBER LABEL [LABEL]...', 'Remove a label from an issue.'
|
28
|
+
def unlabel(issue_number, label, *more_labels)
|
29
|
+
Gish.unlabel(issue_number, label, more_labels)
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'comments SUBCOMMAND ...ARGS', 'Manage comments for an issue.'
|
33
|
+
subcommand 'comments', Gish::Cli::Comments
|
34
|
+
|
35
|
+
desc 'comment ISSUE_NUMBER', 'Comment on an issue.'
|
36
|
+
method_option :message, :type => :string, :aliases => '-m', :desc => 'Specify the message inline.'
|
37
|
+
def comment(issue_number)
|
38
|
+
message = capture_editor_input unless options.message? || options.message == 'message'
|
39
|
+
message ||= options.message
|
40
|
+
Gish.comment(issue_number, message)
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'list [COUNT]', 'List issues.'
|
44
|
+
method_option :closed, :type => :boolean, :aliases => '-c', :desc => 'Show closed issues.'
|
45
|
+
method_option :order, :type => :string, :aliases => '-o', :desc => 'Ordering by asc or desc.'
|
46
|
+
def list(count=20)
|
47
|
+
args = {:per_page => count}
|
48
|
+
args[:state] = 'closed' if options.closed?
|
49
|
+
args[:direction] = 'asc' if options.order == 'asc'
|
50
|
+
puts Gish.list(args)
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'show ISSUE_NUMBER', 'Display the issue in full.'
|
54
|
+
method_option :include_comments, :type => :boolean, :aliases => '-i', :desc => 'Include comments.'
|
55
|
+
def show(issue_number)
|
56
|
+
puts Gish.show(issue_number)
|
57
|
+
puts "\n"
|
58
|
+
puts Gish.comments(issue_number) if options.include_comments?
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'close ISSUE_NUMBER', 'Close an issue.'
|
62
|
+
method_option :force, :type => :boolean, :aliases => '-f', :desc => 'Force yes, no prompt!'
|
63
|
+
method_option :message, :type => :string, :aliases => '-m', :desc => 'Provide a message before closing.'
|
64
|
+
def close(issue_number)
|
65
|
+
return unless options.force? || options.message? || confirm("Are you sure you want to close issue ##{issue_number} (y/n)... ")
|
66
|
+
message = capture_editor_input if options.message? && options.message == 'message'
|
67
|
+
message ||= options.message
|
68
|
+
Gish.comment(issue_number, message) if options.message?
|
69
|
+
Gish.close(issue_number)
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'reopen ISSUE_NUMBER', 'Reopen a closed issue.'
|
73
|
+
def reopen(issue_number)
|
74
|
+
Gish.reopen(issue_number)
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'browse [ISSUE_NUMBER]', 'View issues in your browser.'
|
78
|
+
def browse(issue_number=nil)
|
79
|
+
Gish.browse(issue_number)
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'assignees', 'List assignees for the repository.'
|
83
|
+
def assignees
|
84
|
+
puts Gish.list_assignees
|
85
|
+
end
|
86
|
+
|
87
|
+
desc 'assign ISSUE_NUMBER USER_LOGIN', 'Assign an issue to a user.'
|
88
|
+
def assign(issue_number, user_login)
|
89
|
+
Gish.assign(issue_number, user_login)
|
90
|
+
end
|
91
|
+
|
92
|
+
desc 'unassign ISSUE_NUMBER', 'Unassign an issue.'
|
93
|
+
def unassign(issue_number)
|
94
|
+
Gish.unassign(issue_number)
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'open TITLE', 'Open a new issue.'
|
98
|
+
method_option :labels, :type => :array, :aliases => '-l', :desc => 'Add labels.'
|
99
|
+
method_option :assignee, :type => :string, :aliases => '-a', :desc => 'Assign someone to the issue.'
|
100
|
+
method_option :message, :type => :string, :aliases => '-m', :desc => 'Specify the message inline.'
|
101
|
+
def open(title)
|
102
|
+
labels = (options.labels || []).map{|l| l.strip }
|
103
|
+
message = capture_editor_input unless options.message? && options.message != 'message'
|
104
|
+
message ||= options.message
|
105
|
+
assignee = options.assignee
|
106
|
+
Gish.create(title, message, labels, assignee)
|
107
|
+
end
|
108
|
+
|
109
|
+
desc 'version', 'Display the version of Gish.'
|
110
|
+
def version
|
111
|
+
puts "v#{Gish::VERSION}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/gish/version.rb
ADDED
data/lib/gish.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "gish/version"
|
2
|
+
require "gish/helpers/input_helpers"
|
3
|
+
require "gish/helpers/terminal_helpers"
|
4
|
+
require "gish/configuration"
|
5
|
+
require "gish/commands/issue"
|
6
|
+
require "gish/commands/comment"
|
7
|
+
require "gish/commands/label"
|
8
|
+
require "gish/commands/assignee"
|
9
|
+
require "gish/presentation/issue"
|
10
|
+
require "gish/presentation/label"
|
11
|
+
require "gish/presentation/comment"
|
12
|
+
require 'gish/runner'
|
13
|
+
|
14
|
+
module Gish
|
15
|
+
extend Configuration
|
16
|
+
|
17
|
+
def self.client
|
18
|
+
@github ||= Octokit::Client.new(:access_token => Gish.access_token)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.request(resource='issue/comment/label')
|
22
|
+
begin
|
23
|
+
yield()
|
24
|
+
rescue Octokit::NotFound
|
25
|
+
puts "Could not find #{resource}."
|
26
|
+
exit 1
|
27
|
+
rescue Octokit::Unauthorized
|
28
|
+
puts "Something is wrong with your personal access token."
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
extend Gish::Commands::Label
|
34
|
+
extend Gish::Commands::Issue
|
35
|
+
extend Gish::Commands::Comment
|
36
|
+
extend Gish::Commands::Assignee
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Baris Balic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: octokit
|
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'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Gish brings Github Issues to the command-line.
|
70
|
+
email:
|
71
|
+
- leafybasil@gmail.com
|
72
|
+
executables:
|
73
|
+
- gish
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/gish
|
83
|
+
- gish.gemspec
|
84
|
+
- lib/gish.rb
|
85
|
+
- lib/gish/cli/comments.rb
|
86
|
+
- lib/gish/cli/labels.rb
|
87
|
+
- lib/gish/commands/assignee.rb
|
88
|
+
- lib/gish/commands/comment.rb
|
89
|
+
- lib/gish/commands/issue.rb
|
90
|
+
- lib/gish/commands/label.rb
|
91
|
+
- lib/gish/configuration.rb
|
92
|
+
- lib/gish/helpers/input_helpers.rb
|
93
|
+
- lib/gish/helpers/terminal_helpers.rb
|
94
|
+
- lib/gish/presentation/comment.rb
|
95
|
+
- lib/gish/presentation/issue.rb
|
96
|
+
- lib/gish/presentation/label.rb
|
97
|
+
- lib/gish/runner.rb
|
98
|
+
- lib/gish/version.rb
|
99
|
+
homepage: http://github.com/barisbalic/gish
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 2.0.3
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: A fairly functional command-line interface for the most excellent Gitub Issues.
|
123
|
+
test_files: []
|