ghi 0.2.4 → 0.2.5

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.
@@ -1,3 +1,10 @@
1
+ === 0.2.5
2
+
3
+ * 1 enhancement
4
+
5
+ * Support for SSL with the "--ssl" flag (and "github.ssl" configuration).
6
+
7
+
1
8
  === 0.2.4
2
9
 
3
10
  * 1 enhancement
@@ -19,6 +19,7 @@ Go:
19
19
  -l, --list [state|term|number]
20
20
  --search, --show
21
21
  -v, --verbose
22
+ --ssl
22
23
  -o, --open [title|number]
23
24
  --reopen
24
25
  -c, --closed, --close [number]
@@ -76,11 +77,16 @@ ghi uses ANSI colors if you use them in git.
76
77
 
77
78
  ghi looks for a <tt>$GHI_PAGER</tt> variable for paging.
78
79
 
80
+ Always favor SSL by setting it:
81
+
82
+ git config --global github.ssl true
83
+
79
84
 
80
85
  == CONTRIBUTORS
81
86
 
82
87
  * Jamie Macey (http://blog.tracefunc.com)
83
88
  * Hiroshi Nakamura (http://github.com/nahi)
89
+ * David J. Hamilton
84
90
 
85
91
 
86
92
  === CONTRIBUTE?
@@ -1,5 +1,6 @@
1
1
  require "net/http"
2
2
  require "yaml"
3
+ require "cgi"
3
4
 
4
5
  class GHI::API
5
6
  class InvalidRequest < StandardError
@@ -11,13 +12,14 @@ class GHI::API
11
12
  class ResponseError < StandardError
12
13
  end
13
14
 
14
- API_URL = "http://github.com/api/v2/yaml/issues/:action/:user/:repo"
15
+ API_HOST = "github.com"
16
+ API_PATH = "/api/v2/yaml/issues/:action/:user/:repo"
15
17
 
16
18
  attr_reader :user, :repo
17
19
 
18
- def initialize(user, repo)
20
+ def initialize(user, repo, use_ssl = false)
19
21
  raise InvalidConnection if user.nil? || repo.nil?
20
- @user, @repo = user, repo
22
+ @user, @repo, @use_ssl = user, repo, use_ssl
21
23
  end
22
24
 
23
25
  def search(term, state = :open)
@@ -64,7 +66,19 @@ class GHI::API
64
66
  private
65
67
 
66
68
  def get(*args)
67
- res = YAML.load Net::HTTP.get(URI.parse(url(*args) + auth(true)))
69
+ res = nil
70
+ http = Net::HTTP.new(API_HOST, @use_ssl ? 443 : 80)
71
+ http.use_ssl = true if @use_ssl
72
+ http.start do
73
+ if @use_ssl
74
+ req = Net::HTTP::Post.new path(*args)
75
+ req.set_form_data auth
76
+ else
77
+ req = Net::HTTP::Get.new(path(*args) + auth(true))
78
+ end
79
+ res = YAML.load http.request(req).body
80
+ end
81
+
68
82
  raise ResponseError, errors(res) if res["error"]
69
83
  res
70
84
  rescue ArgumentError, URI::InvalidURIError
@@ -75,8 +89,16 @@ class GHI::API
75
89
 
76
90
  def post(*args)
77
91
  params = args.last.is_a?(Hash) ? args.pop : {}
78
- params.update auth
79
- res = YAML.load Net::HTTP.post_form(URI.parse(url(*args)), params).body
92
+
93
+ res = nil
94
+ http = Net::HTTP.new(API_HOST, @use_ssl ? 443 : 80)
95
+ http.use_ssl = true if @use_ssl
96
+ http.start do
97
+ req = Net::HTTP::Post.new path(*args)
98
+ req.set_form_data params.merge(auth)
99
+ res = YAML.load http.request(req).body
100
+ end
101
+
80
102
  raise ResponseError, errors(res) if res["error"]
81
103
  res
82
104
  rescue ArgumentError, URI::InvalidURIError
@@ -97,10 +119,10 @@ class GHI::API
97
119
  end
98
120
  end
99
121
 
100
- def url(action, *args)
101
- @url ||= API_URL.sub(":user", user).sub(":repo", repo)
102
- uri = @url.sub ":action", action.to_s
103
- uri += "/#{args.join("/")}" unless args.empty?
104
- uri
122
+ def path(action, *args)
123
+ @path ||= API_PATH.sub(":user", user).sub(":repo", repo)
124
+ path = @path.sub ":action", action.to_s
125
+ path << "/#{args.join("/")}" unless args.empty?
126
+ path
105
127
  end
106
128
  end
@@ -207,7 +207,8 @@ module GHI::CLI #:nodoc:
207
207
  include FileHelper, FormattingHelper
208
208
 
209
209
  attr_reader :message, :local_user, :local_repo, :user, :repo, :api,
210
- :action, :search_term, :number, :title, :body, :tag, :args, :verbosity
210
+ :action, :search_term, :number, :title, :body, :tag, :args, :verbosity,
211
+ :use_ssl
211
212
 
212
213
  def parse!(*argv)
213
214
  @args, @argv = argv, argv.dup
@@ -241,7 +242,7 @@ module GHI::CLI #:nodoc:
241
242
  end
242
243
 
243
244
  def run!
244
- @api = GHI::API.new user, repo
245
+ @api = GHI::API.new user, repo, use_ssl
245
246
 
246
247
  case action
247
248
  when :search then search
@@ -313,6 +314,10 @@ module GHI::CLI #:nodoc:
313
314
  end
314
315
  end
315
316
 
317
+ opts.on("--ssl") do |ssl|
318
+ @use_ssl = true
319
+ end
320
+
316
321
  opts.on("-o", "--open", "--reopen [title|number]") do |v|
317
322
  @action = :open
318
323
  case v
@@ -607,6 +612,9 @@ module GHI::CLI #:nodoc:
607
612
  @action = :url
608
613
  @number ||= arguments.shift[/\d+/].to_i
609
614
  end
615
+
616
+ @use_ssl ||= `git config github.ssl`.chomp == 'true'
617
+
610
618
  if @action
611
619
  @args = @argv.dup
612
620
  args.delete_if { |arg| arg == command }
@@ -65,132 +65,154 @@ describe GHI::API do
65
65
  @api = API.new "stephencelis", "ghi"
66
66
  GHI.stub!(:login).and_return "stephencelis"
67
67
  GHI.stub!(:token).and_return "token"
68
+
69
+ @http = mock(Net::HTTP)
70
+ @http.stub(:start) { |l| l.call }
68
71
  end
69
72
 
70
73
  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"
74
+ @api.send(:path, :open).should ==
75
+ "/api/v2/yaml/issues/open/stephencelis/ghi"
76
+ @api.send(:path, :show, 1).should ==
77
+ "/api/v2/yaml/issues/show/stephencelis/ghi/1"
78
+ @api.send(:path, :search, :open, "me").should ==
79
+ "/api/v2/yaml/issues/search/stephencelis/ghi/open/me"
80
+ @api.send(:path, "label/add", "me").should ==
81
+ "/api/v2/yaml/issues/label/add/stephencelis/ghi/me"
79
82
  end
80
83
 
81
84
  it "should process gets" do
82
- url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
85
+ path = "/api/v2/yaml/issues/open/stephencelis/ghi"
83
86
  query = "?login=stephencelis&token=token"
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.stub!(:path).and_return path
88
+ req = mock(Net::HTTPRequest)
89
+ res = mock(Net::HTTPResponse)
90
+ Net::HTTP.should_receive(:new).once.and_return @http
91
+ Net::HTTP::Get.should_receive(:new).once.with(path + query).
92
+ and_return req
93
+ @http.should_receive(:request).once.with(req).and_return res
94
+ res.should_receive(:body).once.and_return ISSUES_YAML
87
95
  @api.list
88
96
  end
89
97
 
90
98
  it "should process posts" do
91
- url = "http://github.com/api/v2/yaml/issues/open/stephencelis/ghi"
99
+ path = "/api/v2/yaml/issues/open/stephencelis/ghi"
92
100
  query = { "login" => "stephencelis",
93
101
  "token" => "token",
94
102
  "title" => "Title",
95
103
  "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
104
+ @api.stub!(:path).and_return path
105
+ req = mock(Net::HTTPRequest)
106
+ res = mock(Net::HTTPResponse)
107
+ Net::HTTP.should_receive(:new).once.and_return @http
108
+ Net::HTTP::Post.should_receive(:new).once.with(path).and_return req
109
+ req.should_receive(:set_form_data).once
110
+ @http.should_receive(:request).once.with(req).and_return res
111
+ res.should_receive(:body).once.and_return ISSUE_YAML
101
112
  @api.open "Title", "Body"
102
113
  end
103
114
 
115
+ def expect_get_response(body)
116
+ req = mock(Net::HTTPRequest)
117
+ res = mock(Net::HTTPResponse)
118
+ Net::HTTP.should_receive(:new).once.and_return @http
119
+ Net::HTTP::Get.should_receive(:new).once.and_return req
120
+ @http.should_receive(:request).once.with(req).and_return res
121
+ res.should_receive(:body).once.and_return body
122
+ end
123
+
124
+ def expect_post_response(body)
125
+ req = mock(Net::HTTPRequest)
126
+ res = mock(Net::HTTPResponse)
127
+ Net::HTTP.should_receive(:new).once.and_return @http
128
+ Net::HTTP::Post.should_receive(:new).once.and_return req
129
+ req.should_receive(:set_form_data).once
130
+ @http.should_receive(:request).once.with(req).and_return res
131
+ res.should_receive(:body).once.and_return body
132
+ end
133
+
104
134
  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
135
+ @api.should_receive(:path).with(:search, :open, "me").and_return "u"
136
+ expect_get_response ISSUES_YAML
107
137
  issues = @api.search "me"
108
138
  issues.should be_an_instance_of(Array)
109
139
  issues.each { |issue| issue.should be_an_instance_of(Issue) }
110
140
  end
111
141
 
112
142
  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
143
+ @api.should_receive(:path).with(:search, :closed, "me").and_return "u"
144
+ expect_get_response ISSUES_YAML
115
145
  @api.search "me", :closed
116
146
  end
117
147
 
118
148
  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
149
+ @api.should_receive(:path).with(:list, :open).and_return "u"
150
+ expect_get_response ISSUES_YAML
121
151
  issues = @api.list
122
152
  issues.should be_an_instance_of(Array)
123
153
  issues.each { |issue| issue.should be_an_instance_of(Issue) }
124
154
  end
125
155
 
126
156
  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
157
+ @api.should_receive(:path).with(:list, :closed).and_return "u"
158
+ expect_get_response ISSUES_YAML
129
159
  @api.list :closed
130
160
  end
131
161
 
132
162
  it "should show" do
133
- @api.should_receive(:url).with(:show, 1).and_return "u"
134
- Net::HTTP.stub!(:get).and_return ISSUE_YAML
163
+ @api.should_receive(:path).with(:show, 1).and_return "u"
164
+ expect_get_response ISSUE_YAML
135
165
  @api.show(1).should be_an_instance_of(Issue)
136
166
  end
137
167
 
138
168
  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
169
+ @api.should_receive(:path).with(:open).and_return "u"
170
+ expect_post_response ISSUE_YAML
143
171
  @api.open("Title", "Body").should be_an_instance_of(Issue)
144
172
  end
145
173
 
146
174
  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
175
+ @api.should_receive(:path).with(:edit, 1).and_return "u"
176
+ expect_post_response ISSUE_YAML
151
177
  @api.edit(1, "Title", "Body").should be_an_instance_of(Issue)
152
178
  end
153
179
 
154
180
  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
181
+ @api.should_receive(:path).with(:close, 1).and_return "u"
182
+ expect_post_response ISSUE_YAML
159
183
  @api.close(1).should be_an_instance_of(Issue)
160
184
  end
161
185
 
162
186
  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
187
+ @api.should_receive(:path).with(:reopen, 1).and_return "u"
188
+ expect_post_response ISSUE_YAML
167
189
  @api.reopen(1).should be_an_instance_of(Issue)
168
190
  end
169
191
 
170
192
  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
193
+ @api.should_receive(:path).with("label/add", 1, "l").and_return "u"
194
+ expect_post_response LABELS_YAML
175
195
  @api.add_label(1, "l").should be_an_instance_of(Array)
176
196
  end
177
197
 
178
198
  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
199
+ @api.should_receive(:path).with("label/remove", 1, "l").and_return "u"
200
+ expect_post_response LABELS_YAML
183
201
  @api.remove_label(1, "l").should be_an_instance_of(Array)
184
202
  end
185
203
 
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)
204
+ it "should comment, and escape values" do
205
+ @api.should_receive(:path).with(:comment, 1).and_return "u"
206
+
207
+ req = mock(Net::HTTPRequest)
208
+ res = mock(Net::HTTPResponse)
209
+ Net::HTTP.should_receive(:new).once.and_return @http
210
+ Net::HTTP::Post.should_receive(:new).once.and_return req
211
+ req.should_receive(:set_form_data).once
212
+ @http.should_receive(:request).once.with(req).and_return res
213
+ res.should_receive(:body).once.and_return COMMENT_YAML
214
+
215
+ @api.comment(1, "Comment&so").should be_an_instance_of(Hash)
194
216
  end
195
217
  end
196
218
  end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 5
9
+ version: 0.2.5
5
10
  platform: ruby
6
11
  authors:
7
12
  - Stephen Celis
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-28 00:00:00 -06:00
17
+ date: 2010-07-28 00:00:00 -05:00
13
18
  default_executable: ghi
14
19
  dependencies: []
15
20
 
@@ -48,21 +53,25 @@ rdoc_options:
48
53
  require_paths:
49
54
  - lib
50
55
  required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
51
57
  requirements:
52
58
  - - ">="
53
59
  - !ruby/object:Gem::Version
60
+ segments:
61
+ - 0
54
62
  version: "0"
55
- version:
56
63
  required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
57
65
  requirements:
58
66
  - - ">="
59
67
  - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
60
70
  version: "0"
61
- version:
62
71
  requirements: []
63
72
 
64
73
  rubyforge_project: ghi
65
- rubygems_version: 1.3.5
74
+ rubygems_version: 1.3.7
66
75
  signing_key:
67
76
  specification_version: 3
68
77
  summary: GitHub Issues on the command line