ghi 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -91,8 +91,36 @@ Always favor SSL by setting it:
91
91
 
92
92
  === CONTRIBUTE?
93
93
 
94
+ Running the tests should be as simple as a `bundle` and
95
+ `bundle exec spec spec`.
96
+
94
97
  ghi is not under currently under the control of any gem packaging system. To
95
98
  build, use RubyGems:
96
99
 
97
100
  % gem build ghi.gemspec
98
101
  % sudo gem install ghi*.gem
102
+
103
+
104
+ == LICENSE
105
+
106
+ (The MIT License)
107
+
108
+ (c) 2009-* Stephen Celis, stephen@stephencelis.com.
109
+
110
+ Permission is hereby granted, free of charge, to any person obtaining a copy
111
+ of this software and associated documentation files (the "Software"), to deal
112
+ in the Software without restriction, including without limitation the rights
113
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
114
+ copies of the Software, and to permit persons to whom the Software is
115
+ furnished to do so, subject to the following conditions:
116
+
117
+ The above copyright notice and this permission notice shall be included in all
118
+ copies or substantial portions of the Software.
119
+
120
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
121
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
122
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
123
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
124
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
125
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
126
+ SOFTWARE.
data/lib/ghi.rb CHANGED
@@ -1,21 +1,19 @@
1
1
  require "net/http"
2
2
  require "yaml"
3
+ YAML::ENGINE.yamler = "syck" if YAML.const_defined? :ENGINE
3
4
 
4
5
  module GHI
5
- VERSION = "0.2.4"
6
+ VERSION = "0.3.0"
6
7
 
7
8
  class << self
8
9
  def login
9
10
  return @login if defined? @login
10
11
  @login = `git config --get github.user`.chomp
11
12
  if @login.empty?
12
- begin
13
- print "Please enter your GitHub username: "
14
- @login = gets.chomp
15
- valid = user? @login
16
- warn "invalid username" unless valid
17
- end until valid
18
- `git config --global github.user #@login`
13
+ warn "Please configure your GitHub username."
14
+ puts
15
+ puts "E.g., git config --global github.user [your username]"
16
+ abort
19
17
  end
20
18
  @login
21
19
  end
@@ -24,13 +22,14 @@ module GHI
24
22
  return @token if defined? @token
25
23
  @token = `git config --get github.token`.chomp
26
24
  if @token.empty?
27
- begin
28
- print "GitHub token (https://github.com/account): "
29
- @token = gets.chomp
30
- valid = token? @token
31
- warn "invalid token for #{login}" unless valid
32
- end until valid
33
- `git config --global github.token #@token`
25
+ warn "Please configure your GitHub token."
26
+ puts
27
+ puts "E.g., git config --global github.user [your token]"
28
+ puts
29
+ puts "Find your token here: https://github.com/account/admin"
30
+ abort
31
+ elsif @token.sub!(/^!/, '')
32
+ @token = `#@token`
34
33
  end
35
34
  @token
36
35
  end
data/lib/ghi/api.rb CHANGED
@@ -1,19 +1,22 @@
1
- require "net/http"
1
+ require "net/https"
2
2
  require "yaml"
3
3
  require "cgi"
4
4
 
5
5
  class GHI::API
6
- class InvalidRequest < StandardError
6
+ class GHIError < StandardError
7
7
  end
8
8
 
9
- class InvalidConnection < StandardError
9
+ class InvalidRequest < GHIError
10
10
  end
11
11
 
12
- class ResponseError < StandardError
12
+ class InvalidConnection < GHIError
13
13
  end
14
14
 
15
- API_HOST = "github.com"
16
- API_PATH = "/api/v2/yaml/issues/:action/:user/:repo"
15
+ class ResponseError < GHIError
16
+ end
17
+
18
+ API_HOST = "github.com"
19
+ API_PATH = "/api/v2/yaml/issues/:action/:user/:repo"
17
20
 
18
21
  attr_reader :user, :repo
19
22
 
@@ -34,11 +37,21 @@ class GHI::API
34
37
  GHI::Issue.new get(:show, number)["issue"]
35
38
  end
36
39
 
40
+ def comments(number)
41
+ get(:comments, number)["comments"]
42
+ end
43
+
37
44
  def open(title, body)
45
+ if title.empty? && body.empty?
46
+ raise GHIError, "Aborting request due to empty issue."
47
+ end
38
48
  GHI::Issue.new post(:open, "title" => title, "body" => body)["issue"]
39
49
  end
40
50
 
41
51
  def edit(number, title, body)
52
+ if title.empty? && body.empty?
53
+ raise GHIError, "Aborting request due to empty issue."
54
+ end
42
55
  res = post :edit, number, "title" => title, "body" => body
43
56
  GHI::Issue.new res["issue"]
44
57
  end
@@ -60,6 +73,9 @@ class GHI::API
60
73
  end
61
74
 
62
75
  def comment(number, comment)
76
+ if comment.empty?
77
+ raise GHIError, "Aborting request due to empty comment."
78
+ end
63
79
  post(:comment, number, "comment" => comment)["comment"]
64
80
  end
65
81
 
@@ -79,7 +95,7 @@ class GHI::API
79
95
  res = YAML.load http.request(req).body
80
96
  end
81
97
 
82
- raise ResponseError, errors(res) if res["error"]
98
+ raise ResponseError, errors(res) if res["error"] || res[:error]
83
99
  res
84
100
  rescue ArgumentError, URI::InvalidURIError
85
101
  raise ResponseError, "GitHub hiccuped on your request"
@@ -99,7 +115,7 @@ class GHI::API
99
115
  res = YAML.load http.request(req).body
100
116
  end
101
117
 
102
- raise ResponseError, errors(res) if res["error"]
118
+ raise ResponseError, errors(res) if res["error"] || res[:error]
103
119
  res
104
120
  rescue ArgumentError, URI::InvalidURIError
105
121
  raise ResponseError, "GitHub hiccuped on your request"
@@ -108,6 +124,7 @@ class GHI::API
108
124
  end
109
125
 
110
126
  def errors(response)
127
+ return response[:error] if response.key? :error
111
128
  [*response["error"]].map { |e| e["error"] } * ", "
112
129
  end
113
130
 
data/lib/ghi/cli.rb CHANGED
@@ -90,12 +90,16 @@ module GHI::CLI #:nodoc:
90
90
  if verbosity
91
91
  issues.map { |i| ["=" * 79] + show_format(i) }
92
92
  else
93
- issues.map { |i| " #{i.number.to_s.rjust 3}: #{truncate(i.title, 72)}" }
93
+ issues.map { |i| " #{i.number.to_s.rjust 3}: #{truncate(i.title, 72)} #{label_format(i.labels)}" }
94
94
  end
95
95
  else
96
96
  "none"
97
97
  end
98
98
  end
99
+
100
+ def label_format(labels)
101
+ labels and labels.map {|l| "[#{l}]"}.join(' ')
102
+ end
99
103
 
100
104
  def edit_format(issue)
101
105
  l = []
@@ -122,6 +126,7 @@ module GHI::CLI #:nodoc:
122
126
  l << " number: #{issue.number}" if issue.number
123
127
  l << " state: #{issue.state}" if issue.state
124
128
  l << " title: #{indent(issue.title, 15, 0).join}" if issue.title
129
+ l << " labels: #{label_format(issue.labels)}" unless issue.labels.nil? || issue.labels.empty?
125
130
  l << " user: #{issue.user || GHI.login}"
126
131
  l << " votes: #{issue.votes}" if issue.votes
127
132
  l << " created at: #{issue.created_at}" if issue.created_at
@@ -129,6 +134,19 @@ module GHI::CLI #:nodoc:
129
134
  return l unless verbose
130
135
  l << ""
131
136
  l += indent(issue.body)[0..-2]
137
+
138
+ comments = api.comments(issue.number)
139
+ unless comments.empty?
140
+ l << "=" * 79
141
+ comments.each do |c|
142
+ l << "#{c["user"]} commented:"
143
+ l << ""
144
+ l += indent(c["body"])
145
+ l << "-" * 79
146
+ end
147
+ end
148
+
149
+ l
132
150
  end
133
151
 
134
152
  def action_format(value = nil)
@@ -143,6 +161,7 @@ module GHI::CLI #:nodoc:
143
161
  end
144
162
 
145
163
  def indent(string, level = 4, first = level)
164
+ string = string.gsub(/\n{3,}/, "\n\n")
146
165
  lines = string.scan(/.{0,#{79 - level}}(?:\s|\Z)/).map { |line|
147
166
  " " * level + line
148
167
  }
@@ -214,7 +233,7 @@ module GHI::CLI #:nodoc:
214
233
  @args, @argv = argv, argv.dup
215
234
 
216
235
  remotes = `git config --get-regexp remote\..+\.url`.split /\n/
217
- repo_expression = %r{([^:/]+)/([^/\s]+)(?:\.git)$}
236
+ repo_expression = %r{([^:/]+)/([^/\s]+?)(?:\.git)?$}
218
237
  if remote = remotes.find { |r| r.include? "github.com" }
219
238
  remote.match repo_expression
220
239
  @user, @repo = $1, $2
@@ -271,6 +290,9 @@ module GHI::CLI #:nodoc:
271
290
  rescue GHI::API::ResponseError => e
272
291
  warn "#{File.basename $0}: #{e.message} (#{user}/#{repo})"
273
292
  exit 1
293
+ rescue GHI::API::GHIError => e
294
+ warn e.message
295
+ exit 1
274
296
  end
275
297
 
276
298
  def commenting?
@@ -504,7 +526,7 @@ module GHI::CLI #:nodoc:
504
526
  comment = api.comment number, new_body
505
527
  end
506
528
  puts action_format(issue.title)
507
- puts "(comment #{comment["status"]})" if comment
529
+ puts "(commented)" if comment
508
530
  end
509
531
 
510
532
  def reopen
@@ -514,7 +536,7 @@ module GHI::CLI #:nodoc:
514
536
  comment = api.comment number, new_body
515
537
  end
516
538
  puts action_format(issue.title)
517
- puts "(comment #{comment["status"]})" if comment
539
+ puts "(commented)" if comment
518
540
  end
519
541
 
520
542
  def prepare_label
@@ -545,15 +567,15 @@ module GHI::CLI #:nodoc:
545
567
  @body ||= gets_from_editor api.show(number)
546
568
  comment = api.comment(number, body)
547
569
  delete_message
548
- puts "(comment #{comment["status"]})"
570
+ puts "(comment})"
549
571
  end
550
572
 
551
573
  def url
552
- url = "http://github.com/#{user}/#{repo}/issues"
574
+ url = "https://github.com/#{user}/#{repo}/issues"
553
575
  if number.nil?
554
576
  url << "/#{state}" unless state == :open
555
577
  else
556
- url << "#issue/#{number}"
578
+ url << "/#{number}"
557
579
  end
558
580
  defined?(Launchy) ? Launchy.open(url) : puts(url)
559
581
  end
@@ -581,7 +603,13 @@ module GHI::CLI #:nodoc:
581
603
  @action = :show
582
604
  @number ||= ($1 || arguments.shift[/\d+/]).to_i
583
605
  when "open"
584
- @action = :open
606
+ if arguments.first =~ /^\d+$/
607
+ @action = :reopen
608
+ @number ||= arguments.shift[/\d+/].to_i
609
+ else
610
+ @action = :open
611
+ @title = arguments.join(' ')
612
+ end
585
613
  when "edit"
586
614
  @action = :edit
587
615
  @number ||= arguments.shift[/\d+/].to_i
data/lib/ghi/issue.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  class GHI::Issue
2
2
  attr_reader :number, :title, :body, :votes, :state, :user, :created_at,
3
- :updated_at
3
+ :updated_at, :labels
4
4
 
5
5
  def initialize(options = {})
6
6
  @number = options["number"]
@@ -11,6 +11,7 @@ class GHI::Issue
11
11
  @user = options["user"]
12
12
  @created_at = options["created_at"]
13
13
  @updated_at = options["updated_at"]
14
+ @labels = options["labels"]
14
15
  end
15
16
 
16
17
  #-
data/spec/ghi_spec.rb CHANGED
@@ -59,33 +59,4 @@ describe GHI do
59
59
  GHI.should_receive(:`).once.and_return "da39a3ee5e6b4b0d3255bfef95601890\n"
60
60
  GHI.token.should == "da39a3ee5e6b4b0d3255bfef95601890"
61
61
  end
62
-
63
- it "should approve login input" do
64
- GHI.instance_eval { instance_variable_defined?(:@login).should == false }
65
- GHI.should_receive(:`).with("git config --get github.user").
66
- and_return "\n"
67
- GHI.should_receive(:print).twice
68
- GHI.should_receive(:gets).twice.and_return "defunct\n", "defunkt\n"
69
- Net::HTTP.should_receive(:get).and_return "500: invalid: response",
70
- LOGGED_OUT_YAML
71
- GHI.should_receive(:warn).once
72
- GHI.should_receive(:`).with("git config --global github.user defunkt").
73
- and_return "\n"
74
- GHI.login.should == "defunkt"
75
- end
76
-
77
- it "should approve token input" do
78
- GHI.instance_eval { instance_variable_defined?(:@token).should == false }
79
- GHI.stub!(:login).and_return "defunkt"
80
- GHI.should_receive(:`).with("git config --get github.token").
81
- and_return "\n"
82
- GHI.should_receive(:print).twice
83
- token = "da39a3ee5e6b4b0d3255bfef95601890"
84
- GHI.should_receive(:gets).and_return "invalid\n", "#{token}\n"
85
- Net::HTTP.should_receive(:get).and_return LOGGED_OUT_YAML, LOGGED_IN_YAML
86
- GHI.should_receive(:warn).once
87
- GHI.should_receive(:`).with("git config --global github.token #{token}").
88
- and_return "\n"
89
- GHI.token.should == token
90
- end
91
62
  end
metadata CHANGED
@@ -1,38 +1,35 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ghi
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 2
8
- - 5
9
- version: 0.2.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Stephen Celis
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-07-28 00:00:00 -05:00
18
- default_executable: ghi
19
- dependencies: []
20
-
12
+ date: 2012-01-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70226629529100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - <
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70226629529100
21
25
  description: GitHub Issues on the command line. Use your `$EDITOR`, not your browser.
22
- email:
23
- - stephen@stephencelis.com
24
- executables:
26
+ email: stephen@stephencelis.com
27
+ executables:
25
28
  - ghi
26
29
  extensions: []
27
-
28
- extra_rdoc_files:
29
- - History.rdoc
30
- - Manifest.txt
31
- - README.rdoc
32
- files:
33
- - History.rdoc
34
- - Manifest.txt
30
+ extra_rdoc_files:
35
31
  - README.rdoc
32
+ files:
36
33
  - bin/ghi
37
34
  - lib/ghi/api.rb
38
35
  - lib/ghi/cli.rb
@@ -42,38 +39,32 @@ files:
42
39
  - spec/ghi/cli_spec.rb
43
40
  - spec/ghi/issue_spec.rb
44
41
  - spec/ghi_spec.rb
45
- has_rdoc: true
42
+ - README.rdoc
46
43
  homepage: http://github.com/stephencelis/ghi
47
44
  licenses: []
48
-
49
45
  post_install_message:
50
- rdoc_options:
46
+ rdoc_options:
51
47
  - --main
52
48
  - README.rdoc
53
- require_paths:
49
+ require_paths:
54
50
  - lib
55
- required_ruby_version: !ruby/object:Gem::Requirement
51
+ required_ruby_version: !ruby/object:Gem::Requirement
56
52
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- segments:
61
- - 0
62
- version: "0"
63
- required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
58
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- segments:
69
- - 0
70
- version: "0"
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
71
63
  requirements: []
72
-
73
- rubyforge_project: ghi
74
- rubygems_version: 1.3.7
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.11
75
66
  signing_key:
76
67
  specification_version: 3
77
- summary: GitHub Issues on the command line
68
+ summary: GitHub Issues command line interface
78
69
  test_files: []
79
-
70
+ has_rdoc: true
data/History.rdoc DELETED
@@ -1,221 +0,0 @@
1
- === 0.2.5
2
-
3
- * 1 enhancement
4
-
5
- * Support for SSL with the "--ssl" flag (and "github.ssl" configuration).
6
-
7
-
8
- === 0.2.4
9
-
10
- * 1 enhancement
11
-
12
- * Detect remotes and prefer them with the "-r" flag.
13
-
14
-
15
- * 1 bugfix
16
-
17
- * Fix formatting for Ruby 1.9.1.
18
-
19
-
20
- === 0.2.3 / 2009-12-17
21
-
22
- * Minor enhancements
23
-
24
- * Better follow git's editor and pager behavior.
25
- * Accept -w and --web as alternatives to -u and --url (like git help).
26
-
27
-
28
- === 0.2.2 / 2009-11-30
29
-
30
- * 1 bugfix
31
-
32
- * Fixed Net::HTTP posts in Ruby 1.9 (params must be stringified keys).
33
-
34
-
35
- === 0.2.1 / 2009-11-29
36
-
37
- * 1 bugfix
38
-
39
- * ANSI format by word break.
40
-
41
-
42
- === 0.2.0 / 2009-11-03
43
-
44
- * Major-minor release!
45
-
46
- * Cleanup! (Better help, warnings and errors.)
47
-
48
-
49
- === 0.1.7 / 2009-08-26
50
-
51
- * 2 bugfixes
52
-
53
- * Allow dots in repo names.
54
- * Fix bug preventing invocation from non-GitHub repo directories.
55
-
56
-
57
- === 0.1.6 / 2009-08-05
58
-
59
- * 1 minor enhancement
60
-
61
- * Support for non-"origin" remotes.
62
-
63
-
64
- * 1 bugfix
65
-
66
- * Graceful offline error.
67
-
68
-
69
- === 0.1.5 / 2009-07-08
70
-
71
- * 2 bugfixes
72
-
73
- * Long titles should wrap in show/verbose issue view.
74
- * If a non-OptionParser argument fails early, re-parse when valid.
75
-
76
-
77
- === 0.1.4 / 2009-05-15
78
-
79
- * 1 minor enhancement
80
-
81
- * Minor Windows support.
82
-
83
-
84
- === 0.1.3 / 2009-05-08
85
-
86
- * 1 minor enhancement
87
-
88
- * Fix bug where `more' was being passed `less' options.
89
- * Fix scoping of commands so `ghi user/repo` can run outside of a repo
90
- directory.
91
-
92
-
93
- === 0.1.2 / 2009-05-07
94
-
95
- * 1 major enhancement
96
-
97
- * Better fallbacks. Enter `ghi open`, `ghi list closed`, `ghi search term`,
98
- `ghi show 2`, `ghi user/repo`, etc., it will try to work. Fallbacks do not
99
- accept options, though.
100
-
101
-
102
- === 0.1.1 / 2009-05-01
103
-
104
- * 3 major enhancements
105
-
106
- * Use `more' (or $GHI_PAGER) to accommodate lengthy output.
107
- * Default to "-l" if Dir.pwd is a git repo.
108
- * Accept numbered args/flags to shortcut "show" (e.g., "ghi -2", "ghi 2")
109
-
110
-
111
- * 1 minor enhancement
112
-
113
- * Update --url flag to GitHub's new convention.
114
-
115
-
116
- === 0.1.0 / 2009-04-27
117
-
118
- * 2 major enhancements
119
-
120
- * Use tempfiles when we should, the gitdir otherwise.
121
- * Now a minor!
122
-
123
-
124
- * 2 minor enhancement
125
-
126
- * Small ANSI tweaks.
127
- * Truncation fix.
128
-
129
-
130
- === 0.0.9 / 2009-04-27
131
-
132
- * 1 major enhancement
133
-
134
- * ANSI colors (honors your .gitconfig).
135
-
136
-
137
- * 1 minor enhancement
138
-
139
- * Bugfixes.
140
-
141
-
142
- === 0.0.8 / 2009-04-26
143
-
144
- * 1 major enhancement
145
-
146
- * Flag to return issues URLs.
147
-
148
-
149
- * 1 minor enhancement
150
-
151
- * Preliminary specs for top-level module and API class.
152
-
153
-
154
- === 0.0.7 / 2009-04-25
155
-
156
- * 1 major enhancement
157
-
158
- * Labels! Label and un-label at your whim.
159
-
160
-
161
- * 1 minor enhancement
162
-
163
- * Tail arguments are sometimes parsed. E.g., ghi -om "Issue message parsed".
164
-
165
-
166
- === 0.0.6 / 2009-04-25
167
-
168
- * 2 minor enhancements
169
-
170
- * Accept comments as arguments in more places.
171
- * Update error message to accommodate both issues and comments.
172
-
173
-
174
- === 0.0.5 / 2009-04-25
175
-
176
- * 3 major enhancements
177
-
178
- * Flag to claim/label issues with your GitHub username (thanks, Jamie).
179
- * Flag for commenting on issues.
180
- * Prompt for GitHub login and token if absent from gitconfig.
181
-
182
-
183
- * 1 minor enhancement
184
-
185
- * Opening issues with a title bypasses your $EDITOR.
186
-
187
-
188
- === 0.0.4 / 2009-04-24
189
-
190
- * 1 major enhancement
191
-
192
- * Cache messages created in $EDITOR.
193
-
194
-
195
- * 2 minor enhancements
196
-
197
- * Refactoring and cleanup.
198
- * Change editing messages.
199
-
200
-
201
- === 0.0.3 / 2009-04-23
202
-
203
- * 2 minor enhancements
204
-
205
- * Typo corrected.
206
- * README updated.
207
-
208
-
209
- === 0.0.2 / 2009-04-22
210
-
211
- * 1 major enhancement
212
-
213
- * Add --search flag.
214
- * Add --repo flag.
215
-
216
-
217
- === 0.0.1 / 2009-04-21
218
-
219
- * 1 major enhancement
220
-
221
- * Birthday!
data/Manifest.txt DELETED
@@ -1,14 +0,0 @@
1
- History.rdoc
2
- Manifest.txt
3
- MIT-LICENSE
4
- Rakefile
5
- README.rdoc
6
- bin/ghi
7
- lib/ghi/api.rb
8
- lib/ghi/cli.rb
9
- lib/ghi/issue.rb
10
- lib/ghi.rb
11
- spec/ghi/api_spec.rb
12
- spec/ghi/cli_spec.rb
13
- spec/ghi/issue_spec.rb
14
- spec/ghi_spec.rb