climate 0.5.0 → 0.6.0
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/README.md +7 -3
- data/lib/climate/command.rb +1 -1
- data/lib/climate/errors.rb +1 -0
- data/lib/climate/script.rb +6 -2
- data/lib/climate/version.rb +1 -1
- data/lib/climate.rb +43 -22
- metadata +13 -12
data/README.md
CHANGED
@@ -7,6 +7,11 @@ structure.
|
|
7
7
|
|
8
8
|
Designed for both simple and more complex cases.
|
9
9
|
|
10
|
+
- Embed a CLI in to your application
|
11
|
+
- Builds on trollop, a refreshingly sane option parsing library
|
12
|
+
- N-levels of subcommands
|
13
|
+
- Nice help output
|
14
|
+
|
10
15
|
# Easy
|
11
16
|
|
12
17
|
Useful for one-shot scripts:
|
@@ -29,14 +34,13 @@ Useful for one-shot scripts:
|
|
29
34
|
|
30
35
|
This style is intended for embedding a CLI in to your existing application.
|
31
36
|
|
32
|
-
class Parent < Climate::Command
|
33
|
-
name 'thing'
|
37
|
+
class Parent < Climate::Command('thing')
|
34
38
|
description "App that does it all, yet without fuss"
|
35
39
|
opt :log, "Whether to log to stdout" :default => false
|
36
40
|
end
|
37
41
|
|
38
42
|
class Arbitrary < Climate::Command
|
39
|
-
|
43
|
+
set_name 'arbitrary'
|
40
44
|
subcommand_of, Parent
|
41
45
|
description "Do something arbitrary to a file"
|
42
46
|
arg :path "Path to input file"
|
data/lib/climate/command.rb
CHANGED
@@ -131,7 +131,7 @@ module Climate
|
|
131
131
|
command_name, *arguments = parent.leftovers
|
132
132
|
|
133
133
|
if command_name.nil?
|
134
|
-
raise
|
134
|
+
raise MissingSubcommandError.new("command #{parent.class.command_name}" +
|
135
135
|
" expects a subcommand as an argument", parent)
|
136
136
|
end
|
137
137
|
|
data/lib/climate/errors.rb
CHANGED
@@ -50,6 +50,7 @@ module Climate
|
|
50
50
|
|
51
51
|
# Raised when a {Command} is run with insufficient arguments
|
52
52
|
class MissingArgumentError < ParsingError ; end
|
53
|
+
class MissingSubcommandError < MissingArgumentError ; end
|
53
54
|
|
54
55
|
# Raised when two or more options conflict
|
55
56
|
class ConflictingOptionError < ParsingError ; end
|
data/lib/climate/script.rb
CHANGED
@@ -10,7 +10,11 @@ module Climate
|
|
10
10
|
@included = true
|
11
11
|
at_exit do
|
12
12
|
Climate.with_standard_exception_handling do
|
13
|
-
|
13
|
+
begin
|
14
|
+
othermodule.send(:parse_argv)
|
15
|
+
rescue Trollop::HelpNeeded => e
|
16
|
+
raise HelpNeeded.new(othermodule)
|
17
|
+
end
|
14
18
|
othermodule.send(:run)
|
15
19
|
end
|
16
20
|
end
|
@@ -35,7 +39,7 @@ module Climate
|
|
35
39
|
attr_reader :arguments, :options, :leftovers
|
36
40
|
|
37
41
|
def ancestors ; [self] ; end
|
38
|
-
def
|
42
|
+
def command_name ; File.basename($CLIMATE_PROGRAM_NAME || $PROGRAM_NAME) ; end
|
39
43
|
|
40
44
|
def has_subcommands? ; false ; end
|
41
45
|
|
data/lib/climate/version.rb
CHANGED
data/lib/climate.rb
CHANGED
@@ -2,38 +2,59 @@ require 'trollop'
|
|
2
2
|
|
3
3
|
module Climate
|
4
4
|
|
5
|
-
def self.
|
5
|
+
def self.error_messages
|
6
6
|
error_messages = {
|
7
|
-
UnexpectedArgumentError =>
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
UnexpectedArgumentError =>
|
8
|
+
proc {|e| "Unknown argument: #{e}" },
|
9
|
+
UnknownCommandError =>
|
10
|
+
proc {|e| "Unknown command '#{e}': #{e.command_class.ancestors.map(&:command_name).join(' ')} expects one of: #{e.command_class.subcommands.map(&:command_name).join(' ')}" },
|
11
|
+
MissingArgumentError =>
|
12
|
+
proc {|e| "Missing argument: #{e.message}" },
|
13
|
+
MissingSubcommandError =>
|
14
|
+
proc {|e| "Missing argument: #{e.command_class.ancestors.map(&:command_name).join(' ')} expects one of: #{e.command_class.subcommands.map(&:command_name).join(' ')}" },
|
15
|
+
ConflictingOptionError =>
|
16
|
+
proc {|e| "Conflicting options given: #{e}" }
|
11
17
|
}
|
18
|
+
end
|
12
19
|
|
20
|
+
def self.with_standard_exception_handling(options={}, &block)
|
13
21
|
begin
|
14
22
|
yield
|
15
|
-
rescue ExitException => e
|
16
|
-
# exit silently if there is no error message to print out
|
17
|
-
$stderr.puts(e.message) if e.has_message?
|
18
|
-
exit(e.exit_code)
|
19
|
-
rescue HelpNeeded => e
|
20
|
-
print_usage(e.command_class, options)
|
21
|
-
exit(0)
|
22
|
-
rescue ParsingError => e
|
23
|
-
$stderr.puts(error_messages[e.class] + ": #{e.message}")
|
24
|
-
print_usage(e.command_class, options)
|
25
|
-
exit(1)
|
26
23
|
rescue => e
|
27
|
-
|
28
|
-
$stderr.puts(e.backtrace)
|
29
|
-
exit(2)
|
24
|
+
exit handle_error(e, options)
|
30
25
|
end
|
31
26
|
end
|
32
27
|
|
33
|
-
|
34
|
-
|
28
|
+
# extracted for stubbing/overriding without having to do it globally
|
29
|
+
def self.stderr ; $stderr ; end
|
30
|
+
def self.stdout ; $stdout ; end
|
31
|
+
|
32
|
+
def self.handle_error(e, options)
|
33
|
+
case e
|
34
|
+
when ExitException
|
35
|
+
# exit silently if there is no error message to print out
|
36
|
+
stderr.puts(e.message) if e.has_message?
|
37
|
+
e.exit_code
|
38
|
+
when HelpNeeded
|
39
|
+
help(e.command_class).print(options)
|
40
|
+
0
|
41
|
+
when ParsingError
|
42
|
+
stderr.puts(error_messages[e.class].call(e))
|
43
|
+
help(e.command_class).print_usage
|
44
|
+
1
|
45
|
+
else
|
46
|
+
stderr.puts("Unexpected error: #{e.class.name} - #{e.message}")
|
47
|
+
stderr.puts(e.backtrace)
|
48
|
+
2
|
49
|
+
end
|
50
|
+
end
|
35
51
|
|
36
|
-
|
52
|
+
def self.help(command_class)
|
53
|
+
Help.new(command_class)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.print_usage(command_class, options={})
|
57
|
+
help(command_class).print_usage(options)
|
37
58
|
end
|
38
59
|
|
39
60
|
def run(&block)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: climate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nick Griffiths
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2013-02-18 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: trollop
|
@@ -84,15 +84,15 @@ extensions: []
|
|
84
84
|
extra_rdoc_files: []
|
85
85
|
|
86
86
|
files:
|
87
|
-
- lib/climate.rb
|
88
|
-
- lib/climate/help.rb
|
89
|
-
- lib/climate/command_compat.rb
|
90
87
|
- lib/climate/version.rb
|
91
|
-
- lib/climate/script.rb
|
92
|
-
- lib/climate/errors.rb
|
93
|
-
- lib/climate/parser.rb
|
94
|
-
- lib/climate/command.rb
|
95
88
|
- lib/climate/help/man.rb
|
89
|
+
- lib/climate/command_compat.rb
|
90
|
+
- lib/climate/command.rb
|
91
|
+
- lib/climate/parser.rb
|
92
|
+
- lib/climate/errors.rb
|
93
|
+
- lib/climate/script.rb
|
94
|
+
- lib/climate/help.rb
|
95
|
+
- lib/climate.rb
|
96
96
|
- README.md
|
97
97
|
- bin/climate
|
98
98
|
homepage:
|
@@ -124,9 +124,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
124
|
requirements: []
|
125
125
|
|
126
126
|
rubyforge_project:
|
127
|
-
rubygems_version: 1.8.
|
127
|
+
rubygems_version: 1.8.10
|
128
128
|
signing_key:
|
129
129
|
specification_version: 3
|
130
130
|
summary: Library for building command line interfaces
|
131
131
|
test_files: []
|
132
132
|
|
133
|
+
has_rdoc:
|