stephencelis-ghi 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,17 @@
1
+ === 0.1.1 / 2009-05/01
2
+
3
+ * 3 major enhancements
4
+
5
+ * Use `more' (or $GHI_PAGER) to accommodate lengthy output.
6
+ * Default to "-l" if Dir.pwd is a git repo.
7
+ * Accept numbered args/flags to shortcut "show" (e.g., "ghi -2", "ghi 2")
8
+
9
+
10
+ * 1 minor enhancement
11
+
12
+ * Update --url flag to GitHub's new convention.
13
+
14
+
1
15
  === 0.1.0 / 2009-04-27
2
16
 
3
17
  * 2 major enhancements
data/README.rdoc CHANGED
@@ -38,9 +38,14 @@ Go:
38
38
  ghi works simply from within a repository. Some short examples:
39
39
 
40
40
  ghi -l # Lists all open issues
41
+ ghi # Shorter shorthand for "ghi -l"
42
+ ghi -v # Lists all open issues, verbosely (includes body)
41
43
  ghi -lc # Lists all closed issues
42
44
  ghi -l "doesn't work" # Searches for open issues matching "doesn't work"
43
45
  ghi -l invalid -c # Searches for closed issues matching "invalid"
46
+ ghi -l1 # Shows issue 1
47
+ ghi -1 # Shorter shorthand for "ghi -l1"
48
+ ghi 1 # Shorter shorthand still
44
49
  ghi -o # Opens a new issue (in your $EDITOR)
45
50
  ghi -o "New issue" # Opens a new issue with the title "New issue"
46
51
  ghi -o "Title" -m "Body" # Opens a new issue with specified title and body
@@ -54,8 +59,8 @@ ghi works simply from within a repository. Some short examples:
54
59
  ghi -t1 "tag" # Labels issue 1 with "tag"
55
60
  ghi -d1 "tag" # Removes the label, "tag"
56
61
  ghi --claim 1 # Tags issue 1 with your GitHub username
57
- open `ghi -u` # Loads issues in your browser.
58
- open `ghi -u1` # Loads an issue in your browser.
62
+ ghi -u # Loads issues in your browser.
63
+ ghi -u1 # Loads an issue in your browser.
59
64
 
60
65
 
61
66
  ghi also works anywhere:
@@ -66,10 +71,13 @@ ghi also works anywhere:
66
71
 
67
72
  ghi uses ANSI colors if you use them in git.
68
73
 
74
+ ghi looks for a <tt>$GHI_PAGER</tt> variable for paging.
75
+
69
76
 
70
77
  == CONTRIBUTORS
71
78
 
72
79
  * Jamie Macey (http://blog.tracefunc.com)
80
+ * Hiroshi Nakamura (http://github.com/nahi)
73
81
 
74
82
 
75
83
  === CONTRIBUTE?
data/bin/ghi CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "ghi/cli"
4
+ $stdout.sync = true
4
5
  GHI::CLI::Executable.new.parse!(ARGV)
data/lib/ghi/cli.rb CHANGED
@@ -4,6 +4,12 @@ require "ghi"
4
4
  require "ghi/api"
5
5
  require "ghi/issue"
6
6
 
7
+ begin
8
+ require "launchy"
9
+ rescue LoadError
10
+ # No launchy!
11
+ end
12
+
7
13
  module GHI::CLI #:nodoc:
8
14
  module FileHelper
9
15
  def launch_editor(file)
@@ -33,7 +39,7 @@ module GHI::CLI #:nodoc:
33
39
  private
34
40
 
35
41
  def editor
36
- ENV["VISUAL"] || ENV["EDITOR"] || "vi"
42
+ ENV["GHI_EDITOR"] || ENV["VISUAL"] || ENV["EDITOR"] || "vi"
37
43
  end
38
44
 
39
45
  def gitdir
@@ -64,17 +70,23 @@ module GHI::CLI #:nodoc:
64
70
  end
65
71
 
66
72
  module FormattingHelper
67
- def list_format(issues, term = nil)
68
- l = if term
69
- ["# #{state.to_s.capitalize} #{term.inspect} issues on #{user}/#{repo}"]
73
+ def list_header(term = nil)
74
+ if term
75
+ "# #{state.to_s.capitalize} #{term.inspect} issues on #{user}/#{repo}"
70
76
  else
71
- ["# #{state.to_s.capitalize} issues on #{user}/#{repo}"]
77
+ "# #{state.to_s.capitalize} issues on #{user}/#{repo}"
72
78
  end
79
+ end
73
80
 
74
- l += unless issues.empty?
75
- issues.map { |i| " #{i.number.to_s.rjust 3}: #{truncate i.title, 72}" }
81
+ def list_format(issues, verbosity = nil)
82
+ unless issues.empty?
83
+ if verbosity
84
+ issues.map { |i| ["=" * 79] + show_format(i) }
85
+ else
86
+ issues.map { |i| " #{i.number.to_s.rjust 3}: #{truncate i.title, 72}" }
87
+ end
76
88
  else
77
- ["none"]
89
+ "none"
78
90
  end
79
91
  end
80
92
 
@@ -149,7 +161,7 @@ module GHI::CLI #:nodoc:
149
161
  rescue NoMethodError
150
162
  # Do nothing.
151
163
  ensure
152
- Kernel.puts(*args)
164
+ $stdout.puts(*args)
153
165
  end
154
166
 
155
167
  def colorize?
@@ -160,36 +172,53 @@ module GHI::CLI #:nodoc:
160
172
  false
161
173
  end
162
174
  end
175
+
176
+ def prepare_stdout
177
+ return if @prepared || @no_pager || !$stdout.isatty
178
+ colorize? # Check for colorization.
179
+ $stdout = IO.popen pager, "w"
180
+ @prepared = true
181
+ end
182
+
183
+ def pager
184
+ ENV["GHI_PAGER"] || "more -EMR"
185
+ end
163
186
  end
164
187
 
165
188
  class Executable
166
189
  include FileHelper, FormattingHelper
167
190
 
168
191
  attr_reader :message, :local_user, :local_repo, :user, :repo, :api,
169
- :action, :state, :search_term, :number, :title, :body, :tag, :args
192
+ :action, :search_term, :number, :title, :body, :tag, :args, :verbosity
170
193
 
171
194
  def parse!(*argv)
172
195
  @args = argv
196
+
197
+ `git config --get remote.origin.url`.match %r{([^:/]+)/([^/]+).git$}
198
+ @user, @repo = $1, $2
199
+
173
200
  option_parser.parse!(*args)
174
201
 
175
- if action.nil?
202
+ if action.nil? && fallback_parsing(*args).nil?
176
203
  puts option_parser
177
204
  exit
178
205
  end
179
-
180
- run!
181
- rescue OptionParser::InvalidOption, OptionParser::MissingArgument,
182
- OptionParser::AmbiguousOption => e
206
+ rescue OptionParser::InvalidOption => e
207
+ if fallback_parsing(*e.args).nil?
208
+ warn "#{File.basename $0}: #{e.message}"
209
+ puts option_parser
210
+ exit 1
211
+ end
212
+ rescue OptionParser::MissingArgument, OptionParser::AmbiguousOption => e
183
213
  warn "#{File.basename $0}: #{e.message}"
184
214
  puts option_parser
185
215
  exit 1
216
+ ensure
217
+ run!
218
+ $stdout.close_write
186
219
  end
187
220
 
188
221
  def run!
189
- `git config --get remote.origin.url`.match %r{([^:/]+)/([^/]+).git$}
190
- @local_user, @local_repo = $1, $2
191
- @user ||= @local_user
192
- @repo ||= @local_repo
193
222
  @api = GHI::API.new user, repo
194
223
 
195
224
  case action
@@ -221,6 +250,10 @@ module GHI::CLI #:nodoc:
221
250
  @commenting
222
251
  end
223
252
 
253
+ def state
254
+ @state || :open
255
+ end
256
+
224
257
  private
225
258
 
226
259
  def option_parser
@@ -231,7 +264,7 @@ module GHI::CLI #:nodoc:
231
264
  @action = :list
232
265
  case v
233
266
  when nil, /^o(?:pen)?$/
234
- @state = :open
267
+ # Defaults.
235
268
  when /^\d+$/
236
269
  @action = :show
237
270
  @number = v.to_i
@@ -239,13 +272,21 @@ module GHI::CLI #:nodoc:
239
272
  @state = :closed
240
273
  when /^u$/
241
274
  @action = :url
275
+ when /^v$/
276
+ @verbosity = true
242
277
  else
243
278
  @action = :search
244
- @state ||= :open
245
279
  @search_term = v
246
280
  end
247
281
  end
248
282
 
283
+ opts.on("-v", "--verbose") do |v|
284
+ if v
285
+ @action ||= :list
286
+ @verbosity = true
287
+ end
288
+ end
289
+
249
290
  opts.on("-o", "--open", "--reopen [title|number]") do |v|
250
291
  @action = :open
251
292
  case v
@@ -254,7 +295,6 @@ module GHI::CLI #:nodoc:
254
295
  @number = v.to_i
255
296
  when /^l$/
256
297
  @action = :list
257
- @state = :open
258
298
  when /^m$/
259
299
  @title = args * " "
260
300
  when /^u$/
@@ -276,7 +316,11 @@ module GHI::CLI #:nodoc:
276
316
  @action = :url
277
317
  @state = :closed
278
318
  when nil
279
- @action = :close
319
+ if @action.nil? || @number
320
+ @action = :close
321
+ else
322
+ @state = :closed
323
+ end
280
324
  else
281
325
  raise OptionParser::InvalidOption
282
326
  end
@@ -355,6 +399,10 @@ module GHI::CLI #:nodoc:
355
399
  @colorize = v
356
400
  end
357
401
 
402
+ opts.on("--[no-]pager") do |v|
403
+ @no_pager = (v == false)
404
+ end
405
+
358
406
  opts.on_tail("-V", "--version") do
359
407
  puts "#{File.basename($0)}: v#{GHI::VERSION}"
360
408
  exit
@@ -368,16 +416,21 @@ module GHI::CLI #:nodoc:
368
416
  end
369
417
 
370
418
  def search
419
+ prepare_stdout
420
+ puts list_header(search_term)
371
421
  issues = api.search search_term, state
372
- puts list_format(issues, search_term)
422
+ puts list_format(issues, verbosity)
373
423
  end
374
424
 
375
425
  def list
376
- issues = api.list state
377
- puts list_format(issues)
426
+ prepare_stdout
427
+ puts list_header
428
+ issues = api.list(state)
429
+ puts list_format(issues, verbosity)
378
430
  end
379
431
 
380
432
  def show
433
+ prepare_stdout
381
434
  issue = api.show number
382
435
  puts show_format(issue)
383
436
  end
@@ -460,9 +513,23 @@ module GHI::CLI #:nodoc:
460
513
 
461
514
  def url
462
515
  url = "http://github.com/#{user}/#{repo}/issues"
463
- url << "/#{state}" unless state.nil?
464
- url << "/#{number}/find" unless number.nil?
465
- puts url
516
+ if number.nil?
517
+ url << "/#{state}" unless state == :open
518
+ else
519
+ url << "#issue/#{number}"
520
+ end
521
+ defined?(Launchy) ? Launchy.open(url) : puts(url)
522
+ end
523
+
524
+ def fallback_parsing(*arguments)
525
+ if user && repo
526
+ if arguments.to_s.empty?
527
+ @action = :list
528
+ elsif arguments.to_s =~ /^-?(\d+)$/
529
+ @action = :show
530
+ @number = $1
531
+ end
532
+ end
466
533
  end
467
534
  end
468
535
  end
data/spec/ghi/cli_spec.rb CHANGED
@@ -6,6 +6,8 @@ describe GHI::CLI::Executable do
6
6
  before :each do
7
7
  @cli = GHI::CLI::Executable.new
8
8
  @cli.stub!(:api).and_return(mock(GHI::API))
9
+ $stdout.stub! :close_write
10
+ IO.stub!(:popen).and_return $stdout
9
11
  end
10
12
 
11
13
  describe "parsing" do
@@ -21,7 +23,7 @@ describe GHI::CLI::Executable do
21
23
  @cli.should_receive(@action)
22
24
  @cli.parse! @args
23
25
  @cli.action.should == @action
24
- @cli.state.should == @state
26
+ @cli.state.should == (@state || :open)
25
27
  @cli.number.should == @number
26
28
  @cli.search_term.should == @term
27
29
  @cli.title.should == @title
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.1.0
4
+ version: 0.1.1
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-27 00:00:00 -07:00
12
+ date: 2009-05-01 00:00:00 -07:00
13
13
  default_executable: ghi
14
14
  dependencies: []
15
15