gli 1.2.2 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,7 @@ This is a DSL you can use to create a command line interface like git, gem or sv
13
13
 
14
14
  Install if you need to:
15
15
 
16
- sudo gem install gli
16
+ gem install gli
17
17
 
18
18
  The simplest way to get started is to create a scaffold project
19
19
 
@@ -46,5 +46,6 @@ Extensive documentation is {available at the wiki}[https://github.com/davetron50
46
46
  * [http://davetron5000.github.com/gli] - RubyDoc
47
47
  * [http://www.github.com/davetron5000/gli] - Source on GitHub
48
48
  * [http://www.github.com/davetron5000/gli/wiki] - Documentation Wiki
49
+ * [http://www.github.com/davetron5000/gli/wiki/Changelog] - Changelog
49
50
 
50
51
  :include:gli.rdoc
data/lib/gli.rb CHANGED
@@ -3,6 +3,7 @@ require 'gli/command.rb'
3
3
  require 'gli/switch.rb'
4
4
  require 'gli/flag.rb'
5
5
  require 'gli/options.rb'
6
+ require 'gli/exceptions.rb'
6
7
  require 'gli_version.rb'
7
8
  require 'support/help.rb'
8
9
  require 'support/rdoc.rb'
@@ -124,7 +125,11 @@ module GLI
124
125
  @@use_openstruct = use_openstruct
125
126
  end
126
127
 
127
- # Runs whatever command is needed based on the arguments.
128
+ # Runs whatever command is needed based on the arguments.
129
+ #
130
+ # args - the command line ARGV array
131
+ #
132
+ # Returns a number that would be a reasonable exit code
128
133
  def run(args)
129
134
  rdoc = RDocCommand.new
130
135
  commands[:rdoc] = rdoc if !commands[:rdoc]
@@ -142,6 +147,7 @@ module GLI
142
147
  command.execute(global_options,options,arguments)
143
148
  @@post_block.call(global_options,command,options,arguments) if @@post_block
144
149
  end
150
+ 0
145
151
  rescue Exception => ex
146
152
  regular_error_handling = true
147
153
  regular_error_handling = @@error_block.call(ex) if @@error_block
@@ -149,9 +155,25 @@ module GLI
149
155
  if regular_error_handling
150
156
  $stderr.puts "error: #{ex.message}"
151
157
  end
158
+
159
+ raise ex if ENV['GLI_DEBUG'] == 'true'
160
+
161
+ case ex
162
+ when BadCommandLine then -1
163
+ when CustomExit then ex.exit_code
164
+ else
165
+ -2
166
+ end
152
167
  end
153
168
  end
154
169
 
170
+ # Simpler means of exiting with a custom exit code. This will
171
+ # raise a CustomExit with the given message and exit code, which will ultimatley
172
+ # cause your application to exit with the given exit_code as its exit status
173
+ def exit_now!(message,exit_code)
174
+ raise CustomExit.new(message,exit_code)
175
+ end
176
+
155
177
  # Possibly returns a copy of the passed-in Hash as an instance of GLI::Option.
156
178
  # By default, it will *not*, however by putting <tt>use_openstruct true</tt>
157
179
  # in your CLI definition, it will
@@ -278,7 +300,7 @@ module GLI
278
300
  if !command
279
301
  command_name = args.shift
280
302
  command = find_command(command_name)
281
- raise "Unknown command '#{command_name}'" if !command
303
+ raise BadCommandLine.new("Unknown command '#{command_name}'") if !command
282
304
  return parse_options_helper(args,
283
305
  global_options,
284
306
  command,
@@ -344,16 +366,16 @@ module GLI
344
366
  try_me.delete arg
345
367
  break
346
368
  end
347
- raise "Unknown argument #{arg}" if arg =~ /^\-/
369
+ raise BadCommandLine.new("Unknown argument #{arg}") if arg =~ /^\-/
348
370
  end
349
371
  return [global_options,command,command_options,try_me + rest]
350
372
  else
351
373
  # Now we have our command name
352
374
  command_name = try_me.shift
353
- raise "Unknown argument #{command_name}" if command_name =~ /^\-/
375
+ raise BadCommandLine.new("Unknown argument #{command_name}") if command_name =~ /^\-/
354
376
 
355
377
  command = find_command(command_name)
356
- raise "Unknown command '#{command_name}'" if !command
378
+ raise BadCommandLine.new("Unknown command '#{command_name}'") if !command
357
379
 
358
380
  return parse_options_helper(rest,
359
381
  global_options,
@@ -0,0 +1,28 @@
1
+ module GLI
2
+ # Indicates that the command line invocation was bad
3
+ class BadCommandLine < Exception
4
+ def initialize(message)
5
+ super(message)
6
+ end
7
+ end
8
+
9
+ # Raise this if you want to use an exit status that isn't the default
10
+ # provided by GLI.
11
+ #
12
+ # Example:
13
+ #
14
+ # raise CustomExit.new("Not connected to DB",-5) unless connected?
15
+ # raise CustomExit.new("Bad SQL",-6) unless valid_sql?(args[0])
16
+ #
17
+ class CustomExit < Exception
18
+ attr_reader :exit_code
19
+ # Create a custom exit exception
20
+ #
21
+ # message - String containing error message to show the user
22
+ # exit_code - the exit code to use, overridding GLI's default
23
+ def initialize(message,exit_code)
24
+ super(message)
25
+ @exit_code = exit_code
26
+ end
27
+ end
28
+ end
@@ -24,7 +24,7 @@ module GLI
24
24
  args.delete_at index
25
25
  return value
26
26
  else
27
- raise "#{matched} requires an argument"
27
+ raise BadCommandLine.new("#{matched} requires an argument")
28
28
  end
29
29
  else
30
30
  return value
@@ -38,7 +38,7 @@ module GLI
38
38
  if @names[arg]
39
39
  return [true,arg,nil] if arg.length == 2
40
40
  # This means we matched the long-form, but there's no argument
41
- raise "#{arg} requires an argument via #{arg}=argument"
41
+ raise BadCommandLine.new("#{arg} requires an argument via #{arg}=argument")
42
42
  end
43
43
  @names.keys.each() do |name|
44
44
  match_string = "^#{name}=(.*)$"
@@ -0,0 +1,72 @@
1
+ module GLI
2
+ # Class to encapsulate stuff about the terminal. This is a singleton, mostly to facilitate testing.
3
+ #
4
+ # Example:
5
+ #
6
+ # Terminal.instance.size[0] # => columns in the terminal
7
+ # Terminal.default_size = [128,24] # => change default when we can't figure it out
8
+ # raise "no ls?!?!?" unless Terminal.instance.command_exists?("ls")
9
+ #
10
+ class Terminal
11
+
12
+ @@default_size = [80,24]
13
+
14
+ # Get the default size of the terminal when we can't figure it out
15
+ #
16
+ # Returns an array of int [cols,rows]
17
+ def self.default_size
18
+ @@default_size
19
+ end
20
+
21
+ # Set the default size of the terminal to use when we can't figure it out
22
+ #
23
+ # size - array of two int [cols,rows]
24
+ def self.default_size=(size)
25
+ @@default_size = size
26
+ end
27
+
28
+ # Provide access to the shared instance
29
+ def self.instance; @@instance ||= Terminal.new; end
30
+
31
+ # Call this to cause methods to throw exceptions rather than return a sane default. You
32
+ # probably don't want to call this unless you are writing tests
33
+ def make_unsafe!;
34
+ @unsafe = true
35
+ end
36
+
37
+ # Returns true if the given command exists on this system
38
+ #
39
+ # command - The command to check for
40
+ def command_exists?(command)
41
+ ENV['PATH'].split(File::PATH_SEPARATOR).any? {|d| File.exists? File.join(d, command) }
42
+ end
43
+
44
+ # Ripped from hirb https://github.com/cldwalker/hirb/blob/master/lib/hirb/util.rb
45
+ # Returns an array of size two ints representing the terminal width and height
46
+ def size
47
+ if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
48
+ [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
49
+ elsif (jruby? || (!STDIN.tty? && ENV['TERM'])) && command_exists?('tput')
50
+ [run_command('tput cols').to_i, run_command('tput lines').to_i]
51
+ elsif STDIN.tty? && command_exists?('stty')
52
+ run_command('stty size').scan(/\d+/).map { |s| s.to_i }.reverse
53
+ else
54
+ Terminal.default_size
55
+ end
56
+ rescue Exception => ex
57
+ raise ex if @unsafe
58
+ Terminal.default_size
59
+ end
60
+
61
+ private
62
+
63
+ # Runs a command using backticks. Extracted to allow for testing
64
+ def run_command(command)
65
+ `#{command}`
66
+ end
67
+
68
+ # True if we are JRuby; exposed to allow for testing
69
+ def jruby?; RUBY_PLATFORM =~ /java/; end
70
+
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module GLI
2
- VERSION = '1.2.2'
2
+ VERSION = '1.2.5'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'gli'
2
2
  require 'gli/command'
3
+ require 'gli/terminal'
3
4
 
4
5
  module GLI
5
6
  class DefaultHelpCommand < Command
@@ -119,7 +120,10 @@ module GLI
119
120
  # Wraps the line at the given column length, using the given line padding.
120
121
  # Assumes that the first line doesn't need the padding, as its filled
121
122
  # up with other stuff
122
- def wrap(line,pad_length=0,line_length=80)
123
+ def wrap(line,pad_length=0,line_length=nil)
124
+ if line_length.nil?
125
+ line_length = Terminal.instance.size[0]
126
+ end
123
127
  line_padding = sprintf("%#{pad_length}s",'')
124
128
  words = line.split(/\s+/)
125
129
  return line if !words || words.empty?
@@ -236,7 +236,7 @@ on_error do |exception|
236
236
  true
237
237
  end
238
238
 
239
- GLI.run(ARGV)
239
+ exit GLI.run(ARGV)
240
240
  EOS
241
241
  puts "Created #{bin_file}"
242
242
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gli
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 21
4
5
  prerelease: false
5
6
  segments:
6
7
  - 1
7
8
  - 2
8
- - 2
9
- version: 1.2.2
9
+ - 5
10
+ version: 1.2.5
10
11
  platform: ruby
11
12
  authors:
12
13
  - David Copeland
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-12-11 00:00:00 -05:00
18
+ date: 2010-12-12 00:00:00 -05:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -27,13 +28,14 @@ extensions: []
27
28
  extra_rdoc_files:
28
29
  - README.rdoc
29
30
  - gli.rdoc
30
- - CHANGELOG.rdoc
31
31
  files:
32
32
  - lib/gli/command.rb
33
33
  - lib/gli/command_line_token.rb
34
34
  - lib/gli/flag.rb
35
35
  - lib/gli/switch.rb
36
36
  - lib/gli/options.rb
37
+ - lib/gli/exceptions.rb
38
+ - lib/gli/terminal.rb
37
39
  - lib/gli.rb
38
40
  - lib/gli_version.rb
39
41
  - lib/support/help.rb
@@ -43,7 +45,6 @@ files:
43
45
  - bin/gli
44
46
  - README.rdoc
45
47
  - gli.rdoc
46
- - CHANGELOG.rdoc
47
48
  has_rdoc: true
48
49
  homepage: http://davetron5000.github.com/gli
49
50
  licenses: []
@@ -63,6 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
63
64
  requirements:
64
65
  - - ">="
65
66
  - !ruby/object:Gem::Version
67
+ hash: 3
66
68
  segments:
67
69
  - 0
68
70
  version: "0"
@@ -71,6 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
73
  requirements:
72
74
  - - ">="
73
75
  - !ruby/object:Gem::Version
76
+ hash: 3
74
77
  segments:
75
78
  - 0
76
79
  version: "0"
@@ -1,25 +0,0 @@
1
- == Changelog
2
- === 1.2.2 - 12/11/2010
3
-
4
- * Changed uses of <code>map(&:symbol)</code> to older form, since this doesn't work on 100% of Ruby 1.8.7s.
5
-
6
- === 1.2.1 - 11/26/2010
7
-
8
- * Changed default data structure of options *back* to a <tt>Hash</tt>. If you want to use the <tt>OpenStruct</tt> subclass <tt>Options</tt>, simply put <tt>use_openstruct true</tt> in your command line definition.
9
-
10
- === 1.2.0 - 11/26/2010
11
-
12
- * Added ability to use +help+ command to list commands suitable for creating bash completion script
13
- * <code>options</code> and <code>global_options</code> will now contain values for all aliases of each flag and switch, so if you created a flag with <code>flag [:f,:flag]</code> and the user specifies <code>-f foo</code> on the command line, both <code>options[:f]</code> and <code>options[:flag]</code> will have the value <code>foo</code>. Same behavior for <code>--flag=foo</code>.
14
- * You may now no-longer use names that have already been used. So if you declare a switch <code>switch :foo</code> and then later declare a flag <code>flag [:f,:foo]</code>, you get an <code>ArgumentError</code>. This is only checked within relevant scope, so you can still use the same option names between commands, and you can still have the same option name once in global and once in command scope. This is really a bugfix as the behavior of GLI was not clear before.
15
- * <tt>long_desc</tt> now shows up in generated rdoc for flags and switches
16
- * Scaffoling now generates a usable <code>Gemfile</code> for bundler
17
- * More direct support for version numbers in GLI-managed apps
18
-
19
- === 1.1.3 - 10/24/2010
20
-
21
- * Changed the way we locate <code>__FILE__</code>'s directory; if it's a symlink it would've have worked. Required adding <code>:realpath</code> method to <code>File</code> for pre 1.9.2 rubies
22
-
23
- === 0.0 - 1.1.2
24
-
25
- No changelog tracking was done for these versions :(