ghi 0.2.4 → 0.2.5

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