jewelbox 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 TODO: Write your name
1
+ Copyright (c) 2012 Steve Jang
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -4,6 +4,7 @@ Useful Ruby utility classes that handle:
4
4
 
5
5
  - configuration
6
6
  - time stamp
7
+ - object serialization
7
8
 
8
9
  ## Installation
9
10
 
@@ -73,10 +74,6 @@ you might store your configuration in a YAML file under conf/ directory.
73
74
  Jewelbox.config.service.log_dir => "/opt/myrailsapp/current/log"
74
75
  Jewelbox.config.service.bin_dir => "/opt/myrailsapp/current/bin"
75
76
 
76
- 3. And my unicorn configuration looks like this:
77
-
78
- TBD
79
-
80
77
  ## Contributing
81
78
 
82
79
  1. Fork it
data/lib/jewelbox.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "jewelbox/version"
2
- require "jewelbox/config"
3
2
  require "jewelbox/ext/object"
4
3
  require "jewelbox/ext/time"
4
+ require "jewelbox/config"
5
+ require "jewelbox/command"
@@ -0,0 +1,179 @@
1
+ require 'jewelbox/ext/object'
2
+ require 'jewelbox/ext/string'
3
+ require 'optparse'
4
+ module Jewelbox
5
+
6
+ # === Description
7
+ # Simple wrapper around Ruby OptionParser to factor out common code that
8
+ # you have to repeat every time you write a command line tool. This is a
9
+ # simple wrapper. There is minimum additional functionality.
10
+ #
11
+ # === Example Code
12
+ # Creating a new command line tool or service runner.
13
+ #
14
+ # class MyApp < Jewelbox::Command
15
+ #
16
+ # class MyCustomException < RuntimeError; end
17
+ # exit_code 1, RuntimeError, "Unexpected error"
18
+ # exit_code 2, MyCustomException, "Some good explanation"
19
+ #
20
+ # def initialize
21
+ # @address = "default address"
22
+ # @name = "default name"
23
+ # @arg1 = ""
24
+ # @arg2 = ""
25
+ # end
26
+ #
27
+ # def define_options(opt)
28
+ # opt.banner = "Usage: #{opt.program_name} [options] arg1 arg2"
29
+ # opt.on("-a addr", "--address addr", String, "Address to work with") {|s| @address = s}
30
+ # opt.on("-n name", "--name name", String, "Name to work with") {|s| @name = s}
31
+ # end
32
+ #
33
+ # # Main entry point of the application
34
+ # #
35
+ # def main(argv)
36
+ # @arg1 = argv[0]
37
+ # @arg2 = argv[1]
38
+ # # write application code here
39
+ # end
40
+ #
41
+ # end
42
+ #
43
+ # MyApp.new.run
44
+ #
45
+ # === Help Output Example
46
+ # With the above example, you will get the following help text:
47
+ #
48
+ # Usage: myapp [options] arg1 arg2
49
+ # -a, --address addr Address to work with
50
+ # -n, --name name Name to work with
51
+ # -h, --help Display help
52
+ # -v, --verbose Verbose output
53
+ #
54
+ # Exit codes:
55
+ # 1 [RuntimeError] Unexpected error
56
+ # 2 [MyApp::MyCustomException] Some good explanation
57
+ #
58
+ # === Notes
59
+ #
60
+ # 1. The following options are automatically added.
61
+ # opt.on("-h", "--help", "Display help") { @help = true }
62
+ # opt.on("-v", "--verbose", "Verbose output") { @verbose = true }
63
+ #
64
+ # 2. You can map exception type to exit code by using exit_code method
65
+ # When exception happens during "run", we exit with the matching exit code (default = 1)
66
+ # Also, exception message + "[ERROR]" will be displayed to STDERR.
67
+ #
68
+ # 3. Make sure to override "define_options" and "main" methods.
69
+ #
70
+ class Command
71
+ @@exit_code_map = {}
72
+
73
+ # === Description
74
+ # Maps exception class to the exit code.
75
+ #
76
+ # === Parameters
77
+ # number:: (Integer) exit code to return on given exception
78
+ # eClass:: (Class) exception class
79
+ # message:: (String) explanation of the exception
80
+ #
81
+ def self.exit_code(number, eClass, message = "")
82
+ @@exit_code_map[eClass] = [number.to_i, eClass, message]
83
+ end
84
+
85
+ private
86
+
87
+ def default_options(opt) # :nodoc:
88
+ opt.on("-h", "--help", "Display help") {@help = true}
89
+ opt.on("-v", "--verbose", "Verbose output") {@verbose = true}
90
+ end
91
+
92
+ def define_exit_codes(opt) # :nodoc:
93
+ opt.separator ""
94
+ arr = @@exit_code_map.values.sort {|a,b| a[0] <=> b[0]}
95
+ unless arr.empty?
96
+ opt.separator "Exit codes:"
97
+ arr.each do |code, eClass, msg|
98
+ opt.separator "%6d %-29s %s" % [code, "[#{eClass}]", msg]
99
+ end
100
+ end
101
+ end
102
+
103
+ public
104
+
105
+ # === Description
106
+ # Your application should override this method.
107
+ # Define application command line options.
108
+ #
109
+ # === Parameters
110
+ # opt:: (OptionParser) use this to define options
111
+ #
112
+ def define_options(opt)
113
+ # override this; no additional options by default
114
+ end
115
+
116
+ # === Description
117
+ # Your application should override this method.
118
+ # Implement the main entry point.
119
+ #
120
+ # === Parameters
121
+ # argv:: (Array) of positional arguments
122
+ # Basically left over after processing command line options
123
+ # starting with dash(s) as defined in get_options.
124
+ #
125
+ # === Returns
126
+ # (Integer) exit code
127
+ #
128
+ def main(argv)
129
+ # override this; no default action in main
130
+ end
131
+
132
+ # === Description
133
+ # Parse options, and run the main method
134
+ #
135
+ # === Returns
136
+ # (Integer) exit code
137
+ #
138
+ def run
139
+ code = 0
140
+ opt = OptionParser.new
141
+ define_options(opt)
142
+ default_options(opt)
143
+ define_exit_codes(opt)
144
+ argv = opt.parse!
145
+
146
+ if @help
147
+ puts_msg(opt.help)
148
+
149
+ else
150
+ begin
151
+ main(argv)
152
+ rescue Exception => e
153
+ arr = @@exit_code_map[e.class]
154
+ code = arr ? arr[0] : 1
155
+ puts_err e.to_s
156
+ puts_err "[ERROR]"
157
+ end
158
+ end
159
+
160
+ exit(code)
161
+ end
162
+
163
+ # === Description
164
+ # Print out msg to STDOUT
165
+ #
166
+ def puts_msg(msg)
167
+ STDOUT.puts(msg)
168
+ end
169
+
170
+ # === Description
171
+ # Print out msg to STDERR in red color
172
+ #
173
+ def puts_err(msg)
174
+ STDERR.puts(msg.to_s.red)
175
+ end
176
+
177
+ end
178
+ end
179
+
@@ -0,0 +1,32 @@
1
+ class String
2
+
3
+ def colorize(color_code)
4
+ "\e[#{color_code}m#{self}\e[0m"
5
+ end
6
+
7
+ def red
8
+ colorize(31)
9
+ end
10
+
11
+ def green
12
+ colorize(32)
13
+ end
14
+
15
+ def yellow
16
+ colorize(33)
17
+ end
18
+
19
+ def blue
20
+ colorize(34)
21
+ end
22
+
23
+ def magenta
24
+ colorize(35)
25
+ end
26
+
27
+ def cyan
28
+ colorize(36)
29
+ end
30
+
31
+ end
32
+
@@ -1,3 +1,3 @@
1
1
  module Jewelbox
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/test/bin/myapp ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ require 'jewelbox/command'
3
+
4
+ class MyApp < Jewelbox::Command
5
+
6
+ class MyCustomException < RuntimeError; end
7
+ exit_code 1, RuntimeError, "Unexpected error"
8
+ exit_code 2, MyCustomException, "Some good explanation"
9
+
10
+ def initialize
11
+ @address = "default address"
12
+ @name = "default name"
13
+ end
14
+
15
+ def define_options(opt)
16
+ opt.banner = "Usage: #{opt.program_name} [options] file1 file2"
17
+ opt.on("-a addr", "--address addr", String, "Address to work with") {|s| @address = s}
18
+ opt.on("-n name", "--name name", String, "Name to work with") {|s| @name = s}
19
+ end
20
+
21
+ def do_something_with_address
22
+ puts "@address is #{@address}"
23
+ end
24
+
25
+ def do_something_with_name
26
+ puts "@name is #{@name}"
27
+ end
28
+
29
+ # Entry point of the application
30
+ #
31
+ def main(argv)
32
+ do_something_with_address
33
+ do_something_with_name
34
+ puts_msg "regular message"
35
+ puts_err "error message"
36
+ if argv[0] == "err"
37
+ raise MyCustomException.new("Some bad thing happened")
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ MyApp.new.run
44
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jewelbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-20 00:00:00.000000000 Z
12
+ date: 2012-08-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ruby-debug19
16
- requirement: &19426280 !ruby/object:Gem::Requirement
16
+ requirement: &13114440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *19426280
24
+ version_requirements: *13114440
25
25
  description: A set of useful Ruby functions to be used when creating a new service
26
26
  or rails application
27
27
  email:
@@ -37,10 +37,13 @@ files:
37
37
  - Rakefile
38
38
  - jewelbox.gemspec
39
39
  - lib/jewelbox.rb
40
+ - lib/jewelbox/command.rb
40
41
  - lib/jewelbox/config.rb
41
42
  - lib/jewelbox/ext/object.rb
43
+ - lib/jewelbox/ext/string.rb
42
44
  - lib/jewelbox/ext/time.rb
43
45
  - lib/jewelbox/version.rb
46
+ - test/bin/myapp
44
47
  - test/unit/conf/additional.yml
45
48
  - test/unit/conf/service.yml
46
49
  - test/unit/config_test.rb
@@ -72,6 +75,7 @@ specification_version: 3
72
75
  summary: Contains functions that support service configuration, useful ruby methods
73
76
  (such as eigenclass), and other functionality commonly used by Ruby services
74
77
  test_files:
78
+ - test/bin/myapp
75
79
  - test/unit/conf/additional.yml
76
80
  - test/unit/conf/service.yml
77
81
  - test/unit/config_test.rb