stephencelis-ghi 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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