stephencelis-ghi 0.1.0 → 0.1.1

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,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