stephencelis-ghi 0.0.7 → 0.0.8

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.
data/History.rdoc CHANGED
@@ -1,3 +1,15 @@
1
+ === 0.0.8 / 2009-04-26
2
+
3
+ * 1 major enhancement
4
+
5
+ * Flag to return issues URLs.
6
+
7
+
8
+ * 1 minor enhancement
9
+
10
+ * Preliminary specs for top-level module and API class.
11
+
12
+
1
13
  === 0.0.7 / 2009-04-25
2
14
 
3
15
  * 1 major enhancement
data/README.rdoc CHANGED
@@ -27,6 +27,7 @@ Go:
27
27
  -t, --label [number] [label]
28
28
  --claim [number]
29
29
  -d, --unlabel [number] [label]
30
+ -u, --url [number]
30
31
  -V, --version
31
32
  -h, --help
32
33
 
@@ -52,6 +53,8 @@ ghi works simply from within a repository. Some short examples:
52
53
  ghi -t1 "tag" # Labels issue 1 with "tag"
53
54
  ghi -d1 "tag" # Removes the label, "tag"
54
55
  ghi --claim 1 # Tags issue 1 with your GitHub username
56
+ open `ghi -u` # Loads issues in your browser.
57
+ open `ghi -u1` # Loads an issue in your browser.
55
58
 
56
59
 
57
60
  ghi also works anywhere:
data/lib/ghi/cli.rb CHANGED
@@ -162,6 +162,8 @@ module GHI::CLI #:nodoc:
162
162
  when :comment then comment
163
163
  when :label, :claim then add_label
164
164
  when :unlabel then remove_label
165
+
166
+ when :url then url
165
167
  end
166
168
  rescue GHI::API::InvalidConnection
167
169
  warn "#{File.basename $0}: not a GitHub repo"
@@ -188,13 +190,15 @@ module GHI::CLI #:nodoc:
188
190
  opts.on("-l", "--list", "--search", "--show [state|term|number]") do |v|
189
191
  @action = :list
190
192
  case v
191
- when nil, /^o$/
193
+ when nil, /^o(?:pen)?$/
192
194
  @state = :open
193
195
  when /^\d+$/
194
196
  @action = :show
195
197
  @number = v.to_i
196
- when /^c$/
198
+ when /^c(?:losed)?$/
197
199
  @state = :closed
200
+ when /^u$/
201
+ @action = :url
198
202
  else
199
203
  @action = :search
200
204
  @state ||= :open
@@ -213,6 +217,8 @@ module GHI::CLI #:nodoc:
213
217
  @state = :open
214
218
  when /^m$/
215
219
  @title = ARGV * " "
220
+ when /^u$/
221
+ @action = :url
216
222
  else
217
223
  @title = v
218
224
  end
@@ -221,11 +227,14 @@ module GHI::CLI #:nodoc:
221
227
  opts.on("-c", "--closed", "--close [number]") do |v|
222
228
  case v
223
229
  when /^\d+$/
224
- @action = :close
225
- @number = v.to_i
226
- when /^l/, nil
230
+ @action ||= :close
231
+ @number = v.to_i unless v.nil?
232
+ when /^l$/, nil
227
233
  @action = :list
228
234
  @state = :closed
235
+ when /^u$/, nil
236
+ @action = :url
237
+ @state = :closed
229
238
  when nil
230
239
  raise OptionParser::MissingArgument
231
240
  else
@@ -286,6 +295,16 @@ module GHI::CLI #:nodoc:
286
295
  end
287
296
  end
288
297
 
298
+ opts.on("-u", "--url [number]") do |v|
299
+ @action = :url
300
+ case v
301
+ when /^\d+$/
302
+ @number = v.to_i
303
+ when /^c/
304
+ @state = :closed
305
+ end
306
+ end
307
+
289
308
  opts.on_tail("-V", "--version") do
290
309
  puts "#{File.basename($0)}: v#{GHI::VERSION}"
291
310
  exit
@@ -375,7 +394,14 @@ module GHI::CLI #:nodoc:
375
394
  body = gets_from_editor api.show(number)
376
395
  comment = api.comment(number, body)
377
396
  delete_message
378
- puts "comment #{comment["status"]}"
397
+ puts "(comment #{comment["status"]})"
398
+ end
399
+
400
+ def url
401
+ url = "http://github.com/#{user}/#{repo}/issues"
402
+ url << "/#{state}" unless state.nil?
403
+ url << "/#{number}/find" unless number.nil?
404
+ puts url
379
405
  end
380
406
  end
381
407
  end
data/lib/ghi.rb CHANGED
@@ -2,7 +2,7 @@ require "net/http"
2
2
  require "yaml"
3
3
 
4
4
  module GHI
5
- VERSION = "0.0.7"
5
+ VERSION = "0.0.8"
6
6
 
7
7
  def self.login
8
8
  return @login if defined? @login
@@ -39,15 +39,15 @@ module GHI
39
39
  def self.user?(username)
40
40
  url = "http://github.com/api/v2/yaml/user/show/#{username}"
41
41
  !YAML.load(Net::HTTP.get(URI.parse(url)))["user"].nil?
42
- rescue ArgumentError # Failure to parse YAML.
42
+ rescue ArgumentError, URI::InvalidURIError
43
43
  false
44
44
  end
45
45
 
46
46
  def self.token?(token)
47
47
  url = "http://github.com/api/v2/yaml/user/show/#{GHI.login}"
48
48
  url += "?login=#{GHI.login}&token=#{token}"
49
- !YAML.load(Net::HTTP.get(URI.parse(url)))["user"].nil?
50
- rescue ArgumentError, NoMethodError # Failure to parse YAML.
49
+ !YAML.load(Net::HTTP.get(URI.parse(url)))["user"]["plan"].nil?
50
+ rescue ArgumentError, NoMethodError, URI::InvalidURIError
51
51
  false
52
52
  end
53
53
  end
data/spec/ghi/api_spec.rb CHANGED
@@ -1,8 +1,57 @@
1
1
  $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
2
  require "ghi"
3
3
  require "ghi/api"
4
+ require "ghi/issue"
4
5
  include GHI
5
6
 
7
+ ISSUES_YAML = <<-YAML
8
+ ---
9
+ issues:
10
+ - number: 1
11
+ votes: 0
12
+ created_at: 2009-04-17 14:55:33 -07:00
13
+ body: my sweet, sweet issue
14
+ title: new issue
15
+ updated_at: 2009-04-17 14:55:33 -07:00
16
+ user: schacon
17
+ state: open
18
+ - number: 2
19
+ votes: 0
20
+ created_at: 2009-04-17 15:16:47 -07:00
21
+ body: the body of a second issue
22
+ title: another issue
23
+ updated_at: 2009-04-17 15:16:47 -07:00
24
+ user: schacon
25
+ state: open
26
+ YAML
27
+
28
+ ISSUE_YAML = <<-YAML
29
+ ---
30
+ issue:
31
+ number: 1
32
+ votes: 0
33
+ created_at: 2009-04-17 14:55:33 -07:00
34
+ body: my sweet, sweet issue
35
+ title: new issue
36
+ updated_at: 2009-04-17 14:55:33 -07:00
37
+ user: schacon
38
+ state: open
39
+ YAML
40
+
41
+ LABELS_YAML = <<-YAML
42
+ ---
43
+ labels:
44
+ - testing
45
+ - test_label
46
+ YAML
47
+
48
+ COMMENT_YAML = <<-YAML
49
+ ---
50
+ comment:
51
+ comment: this is amazing
52
+ status: saved
53
+ YAML
54
+
6
55
  describe GHI::API do
7
56
  it "should require user and repo" do
8
57
  proc { API.new(nil, nil) }.should raise_error(API::InvalidConnection)
@@ -10,4 +59,138 @@ describe GHI::API do
10
59
  proc { API.new(nil, "r") }.should raise_error(API::InvalidConnection)
11
60
  proc { API.new("u", "r") }.should_not raise_error(API::InvalidConnection)
12
61
  end
62
+
63
+ describe "requests" do
64
+ before :all do
65
+ @api = API.new "stephencelis", "ghi"
66
+ GHI.stub!(:login).and_return "stephencelis"
67
+ GHI.stub!(:token).and_return "token"
68
+ end
69
+
70
+ it "should substitute url tokens" do
71
+ @api.send(:url, :open).should ==
72
+ "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
73
+ @api.send(:url, :show, 1).should ==
74
+ "http://github.com/api/v2/yaml/issues/show/stephencelis/ghi/1"
75
+ @api.send(:url, :search, :open, "me").should ==
76
+ "http://github.com/api/v2/yaml/issues/search/stephencelis/ghi/open/me"
77
+ @api.send(:url, "label/add", "me").should ==
78
+ "http://github.com/api/v2/yaml/issues/label/add/stephencelis/ghi/me"
79
+ end
80
+
81
+ it "should process gets" do
82
+ url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
83
+ query = "?login=stephencelis&token=d1cd249db48d51c9847cbf2b291f5ae9"
84
+ @api.stub!(:url).and_return url
85
+ URI.should_receive(:parse).once.with(url + query).and_return("mock")
86
+ Net::HTTP.should_receive(:get).once.with("mock").and_return ISSUES_YAML
87
+ @api.list
88
+ end
89
+
90
+ it "should process posts" do
91
+ url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
92
+ query = { :login => "stephencelis",
93
+ :token => "d1cd249db48d51c9847cbf2b291f5ae9",
94
+ :title => "Title",
95
+ :body => "Body" }
96
+ @api.stub!(:url).and_return url
97
+ r = mock(Net::HTTPRequest)
98
+ r.should_receive(:body).once.and_return ISSUE_YAML
99
+ URI.should_receive(:parse).once.with(url).and_return "u"
100
+ Net::HTTP.should_receive(:post_form).once.with("u", query).and_return r
101
+ @api.open "Title", "Body"
102
+ end
103
+
104
+ it "should search open by default" do
105
+ @api.should_receive(:url).with(:search, :open, "me").and_return "u"
106
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
107
+ issues = @api.search "me"
108
+ issues.should be_an_instance_of(Array)
109
+ issues.each { |issue| issue.should be_an_instance_of(Issue) }
110
+ end
111
+
112
+ it "should search closed" do
113
+ @api.should_receive(:url).with(:search, :closed, "me").and_return "u"
114
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
115
+ @api.search "me", :closed
116
+ end
117
+
118
+ it "should list open by default" do
119
+ @api.should_receive(:url).with(:list, :open).and_return "u"
120
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
121
+ issues = @api.list
122
+ issues.should be_an_instance_of(Array)
123
+ issues.each { |issue| issue.should be_an_instance_of(Issue) }
124
+ end
125
+
126
+ it "should list closed" do
127
+ @api.should_receive(:url).with(:list, :closed).and_return "u"
128
+ Net::HTTP.stub!(:get).and_return ISSUES_YAML
129
+ @api.list :closed
130
+ end
131
+
132
+ it "should show" do
133
+ @api.should_receive(:url).with(:show, 1).and_return "u"
134
+ Net::HTTP.stub!(:get).and_return ISSUE_YAML
135
+ @api.show(1).should be_an_instance_of(Issue)
136
+ end
137
+
138
+ it "should open" do
139
+ @api.should_receive(:url).with(:open).and_return "u"
140
+ response = mock(Net::HTTPRequest)
141
+ response.stub!(:body).and_return ISSUE_YAML
142
+ Net::HTTP.stub!(:post_form).and_return response
143
+ @api.open("Title", "Body").should be_an_instance_of(Issue)
144
+ end
145
+
146
+ it "should edit" do
147
+ @api.should_receive(:url).with(:edit, 1).and_return "u"
148
+ response = mock(Net::HTTPRequest)
149
+ response.stub!(:body).and_return ISSUE_YAML
150
+ Net::HTTP.stub!(:post_form).and_return response
151
+ @api.edit(1, "Title", "Body").should be_an_instance_of(Issue)
152
+ end
153
+
154
+ it "should close" do
155
+ @api.should_receive(:url).with(:close, 1).and_return "u"
156
+ response = mock(Net::HTTPRequest)
157
+ response.stub!(:body).and_return ISSUE_YAML
158
+ Net::HTTP.stub!(:post_form).and_return response
159
+ @api.close(1).should be_an_instance_of(Issue)
160
+ end
161
+
162
+ it "should reopen" do
163
+ @api.should_receive(:url).with(:reopen, 1).and_return "u"
164
+ response = mock(Net::HTTPRequest)
165
+ response.stub!(:body).and_return ISSUE_YAML
166
+ Net::HTTP.stub!(:post_form).and_return response
167
+ @api.reopen(1).should be_an_instance_of(Issue)
168
+ end
169
+
170
+ it "should add labels" do
171
+ @api.should_receive(:url).with("label/add", 1, "l").and_return "u"
172
+ response = mock(Net::HTTPRequest)
173
+ response.stub!(:body).and_return LABELS_YAML
174
+ Net::HTTP.stub!(:post_form).and_return response
175
+ @api.add_label(1, "l").should be_an_instance_of(Array)
176
+ end
177
+
178
+ it "should remove labels" do
179
+ @api.should_receive(:url).with("label/remove", 1, "l").and_return "u"
180
+ response = mock(Net::HTTPRequest)
181
+ response.stub!(:body).and_return LABELS_YAML
182
+ Net::HTTP.stub!(:post_form).and_return response
183
+ @api.remove_label(1, "l").should be_an_instance_of(Array)
184
+ end
185
+
186
+ it "should comment" do
187
+ @api.should_receive(:url).with(:comment, 1).and_return "u"
188
+ URI.stub!(:parse).and_return "u"
189
+ response = mock(Net::HTTPRequest)
190
+ response.stub!(:body).and_return COMMENT_YAML
191
+ Net::HTTP.should_receive(:post_form).with("u",
192
+ hash_including(:comment => "Comment")).and_return response
193
+ @api.comment(1, "Comment").should be_an_instance_of(Hash)
194
+ end
195
+ end
13
196
  end
data/spec/ghi_spec.rb CHANGED
@@ -1,14 +1,93 @@
1
- $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
1
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../lib")
2
2
  require "ghi"
3
3
 
4
+ LOGGED_OUT_YAML = <<-YAML
5
+ ---
6
+ user:
7
+ id: 23
8
+ login: defunkt
9
+ name: Kristopher Walken Wanstrath
10
+ company: LA
11
+ location: SF
12
+ email: me@email.com
13
+ blog: http://myblog.com
14
+ following_count: 13
15
+ followers_count: 63
16
+ public_gist_count: 0
17
+ public_repo_count: 2
18
+ YAML
19
+
20
+ LOGGED_IN_YAML = <<-YAML
21
+ ---
22
+ user:
23
+ id: 23
24
+ login: defunkt
25
+ name: Kristopher Walken Wanstrath
26
+ company: LA
27
+ location: SF
28
+ email: me@email.com
29
+ blog: http://myblog.com
30
+ following_count: 13
31
+ followers_count: 63
32
+ public_gist_count: 0
33
+ public_repo_count: 2
34
+ total_private_repo_count: 1
35
+ collaborators: 3
36
+ disk_usage: 50384
37
+ owned_private_repo_count: 1
38
+ private_gist_count: 0
39
+ plan:
40
+ name: mega
41
+ collaborators: 60
42
+ space: 20971520
43
+ private_repos: 125
44
+ YAML
45
+
4
46
  describe GHI do
47
+ before :each do
48
+ GHI.instance_eval do
49
+ remove_instance_variable :@login if instance_variable_defined? :@login
50
+ remove_instance_variable :@token if instance_variable_defined? :@token
51
+ end
52
+ end
53
+
5
54
  it "should return login" do
6
- GHI.stub!(:`).and_return "stephencelis\n"
55
+ GHI.should_receive(:`).once.and_return "stephencelis\n"
7
56
  GHI.login.should == "stephencelis"
8
57
  end
9
58
 
10
59
  it "should return token" do
11
- GHI.stub!(:`).and_return "da39a3ee5e6b4b0d3255bfef95601890\n"
60
+ GHI.should_receive(:`).once.and_return "da39a3ee5e6b4b0d3255bfef95601890\n"
12
61
  GHI.token.should == "da39a3ee5e6b4b0d3255bfef95601890"
13
62
  end
63
+
64
+ it "should approve login input" do
65
+ GHI.instance_eval { instance_variable_defined?(:@login).should == false }
66
+ GHI.should_receive(:`).with("git config --get github.user").
67
+ and_return "\n"
68
+ GHI.should_receive(:print).twice
69
+ GHI.should_receive(:gets).twice.and_return "defunct\n", "defunkt\n"
70
+ Net::HTTP.should_receive(:get).and_return "500: invalid: response",
71
+ LOGGED_OUT_YAML
72
+ GHI.should_receive(:warn).once
73
+ GHI.should_receive(:`).with("git config --global github.user defunkt").
74
+ and_return "\n"
75
+ GHI.login.should == "defunkt"
76
+ end
77
+
78
+ it "should approve token input" do
79
+ GHI.instance_eval { instance_variable_defined?(:@token).should == false }
80
+ GHI.stub!(:login).and_return "defunkt"
81
+ GHI.should_receive(:`).with("git config --get github.token").
82
+ and_return "\n"
83
+ GHI.should_receive(:print).twice
84
+ token = "da39a3ee5e6b4b0d3255bfef95601890"
85
+ GHI.should_receive(:gets).and_return "invalid\n", "#{token}\n"
86
+ Net::HTTP.should_receive(:get).and_return LOGGED_OUT_YAML, LOGGED_IN_YAML
87
+ GHI.should_receive(:warn).once
88
+ # FIXME: Passes on its own...but failing for `spec spec`.
89
+ GHI.should_receive(:`).with("git config --global github.token #{token}").
90
+ and_return "\n"
91
+ GHI.token.should == token
92
+ end
14
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stephencelis-ghi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Celis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-25 00:00:00 -07:00
12
+ date: 2009-04-26 00:00:00 -07:00
13
13
  default_executable: ghi
14
14
  dependencies: []
15
15