sysexits 1.0.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.
@@ -0,0 +1,9 @@
1
+ 2[tip] 5b05aabe75b9 2010-06-18 16:36 -0700 ged
2
+ Wow, Kernel.include? Really? Good thing it's Friday.
3
+
4
+ 1 975a57604d30 2010-06-18 16:15 -0700 ged
5
+ Cleanup, switched README and class docs, docs corrections, no-monkeypatch test.
6
+
7
+ 0 917705a6837d 2010-06-18 14:50 -0700 ged
8
+ Initial checkin
9
+
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2010, Michael Granger
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the author/s, nor the names of the project's
15
+ contributors may be used to endorse or promote products derived from this
16
+ software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,46 @@
1
+ # sysexits
2
+
3
+ Sysexits is a _completely awesome_ collection of human-readable constants for the standard (BSDish) exit codes, used as arguments to `Kernel.exit` to indicate a specific error condition to the parent process.
4
+
5
+ It's so fantastically fabulous that you'll want to fork it right away to avoid being thought of as that guy that's still using Webrick for his blog. I mean, `exit(1)` is so passé! This is like the 14-point font of Systems Programming.
6
+
7
+ Like the C header file from which this was derived (I mean forked, naturally), error numbers begin at `Sysexits::EX__BASE` (which is way more cool than plain old '64') to reduce the possibility of clashing with other exit statuses that other programs may already return.
8
+
9
+ The codes are available in two forms: as constants which can be imported into your own namespace via `include Sysexits`, or as `Sysexits::STATUS_CODES`, a Hash keyed by Symbols derived from the constant names.
10
+
11
+ Allow me to demonstrate. First, the old way:
12
+
13
+ exit( 69 )
14
+
15
+ Whaaa...? Is that a euphemism? What's going on? See how unattractive and... well, 1970 that is? We're not changing vaccuum tubes here, people, we're _building a totally-awesome future in the Cloud™!_
16
+
17
+ include Sysexits
18
+ exit EX_UNAVAILABLE
19
+
20
+ Okay, at least this is readable to people who have used fork() more
21
+ than twice, but you could do so much better!
22
+
23
+ include Sysexits
24
+ exit :unavailable
25
+
26
+ Holy Toledo! It's like we're writing Ruby, but our own made-up
27
+ dialect in which variable++ is possible! Well, okay, it's not quite
28
+ that cool. But it does look more Rubyish. And no monkeys were patched
29
+ in the filming of this episode! All the simpletons still exiting
30
+ with icky *numbers* can still continue blithely along, none the
31
+ wiser.
32
+
33
+ ## Contributing
34
+
35
+ You can check out the current development source with Mercurial like so:
36
+
37
+ hg clone http://repo.deveiate.org/sysexits
38
+
39
+ You can submit bug reports, suggestions, and read more super-exited pointless marketing at:
40
+
41
+ http://deveiate.org/sysexits.html
42
+
43
+ # License
44
+
45
+ See the included [LICENSE](LICENSE.html) file for licensing details.
46
+
@@ -0,0 +1,358 @@
1
+ #!rake -*- ruby -*-
2
+ #
3
+ # sysexits rakefile
4
+ #
5
+ # Based on various other Rakefiles, especially one by Ben Bleything
6
+ #
7
+ # Copyright (c) 2007-2010 The FaerieMUD Consortium
8
+ #
9
+ # Authors:
10
+ # * Michael Granger <ged@FaerieMUD.org>
11
+ #
12
+
13
+ BEGIN {
14
+ require 'rbconfig'
15
+ require 'pathname'
16
+ basedir = Pathname.new( __FILE__ ).dirname
17
+
18
+ libdir = basedir + "lib"
19
+ extdir = libdir + Config::CONFIG['sitearch']
20
+
21
+ $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
22
+ $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
23
+ }
24
+
25
+ begin
26
+ require 'readline'
27
+ include Readline
28
+ rescue LoadError
29
+ # Fall back to a plain prompt
30
+ def readline( text )
31
+ $stderr.print( text.chomp )
32
+ return $stdin.gets
33
+ end
34
+ end
35
+
36
+ begin
37
+ require 'rubygems'
38
+ rescue LoadError
39
+ module Gem
40
+ class Specification; end
41
+ end
42
+ end
43
+
44
+ require 'rbconfig'
45
+ require 'rake'
46
+ require 'rake/testtask'
47
+ require 'rake/packagetask'
48
+ require 'rake/clean'
49
+ # require 'rake/191_compat.rb'
50
+
51
+ $dryrun = false
52
+
53
+ ### Config constants
54
+ BASEDIR = Pathname.new( __FILE__ ).dirname.relative_path_from( Pathname.getwd )
55
+ BINDIR = BASEDIR + 'bin'
56
+ LIBDIR = BASEDIR + 'lib'
57
+ EXTDIR = BASEDIR + 'ext'
58
+ DOCSDIR = BASEDIR + 'docs'
59
+ PKGDIR = BASEDIR + 'pkg'
60
+ DATADIR = BASEDIR + 'data'
61
+
62
+ MANUALDIR = DOCSDIR + 'manual'
63
+
64
+ PROJECT_NAME = 'sysexits'
65
+ PKG_NAME = PROJECT_NAME.downcase
66
+ PKG_SUMMARY = 'A Ruby front end to sysexits.h'
67
+
68
+ # Cruisecontrol stuff
69
+ CC_BUILD_LABEL = ENV['CC_BUILD_LABEL']
70
+ CC_BUILD_ARTIFACTS = ENV['CC_BUILD_ARTIFACTS'] || 'artifacts'
71
+
72
+ VERSION_FILE = LIBDIR + 'sysexits.rb'
73
+ if VERSION_FILE.exist? && buildrev = ENV['CC_BUILD_LABEL']
74
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ] + '.' + buildrev
75
+ elsif VERSION_FILE.exist?
76
+ PKG_VERSION = VERSION_FILE.read[ /VERSION\s*=\s*['"](\d+\.\d+\.\d+)['"]/, 1 ]
77
+ end
78
+
79
+ PKG_VERSION = '0.0.0' unless defined?( PKG_VERSION )
80
+
81
+ PKG_FILE_NAME = "#{PKG_NAME.downcase}-#{PKG_VERSION}"
82
+ GEM_FILE_NAME = "#{PKG_FILE_NAME}.gem"
83
+
84
+ # Universal VCS constants
85
+ DEFAULT_EDITOR = 'vi'
86
+ COMMIT_MSG_FILE = 'commit-msg.txt'
87
+ FILE_INDENT = " " * 12
88
+ LOG_INDENT = " " * 3
89
+
90
+ EXTCONF = EXTDIR + 'extconf.rb'
91
+
92
+ ARTIFACTS_DIR = Pathname.new( CC_BUILD_ARTIFACTS )
93
+
94
+ TEXT_FILES = Rake::FileList.new( %w[Rakefile ChangeLog README* LICENSE] )
95
+ BIN_FILES = Rake::FileList.new( "#{BINDIR}/*" )
96
+ LIB_FILES = Rake::FileList.new( "#{LIBDIR}/**/*.rb" )
97
+ EXT_FILES = Rake::FileList.new( "#{EXTDIR}/**/*.{c,h,rb}" )
98
+ DATA_FILES = Rake::FileList.new( "#{DATADIR}/**/*" )
99
+
100
+ SPECDIR = BASEDIR + 'spec'
101
+ SPECLIBDIR = SPECDIR + 'lib'
102
+ SPEC_FILES = Rake::FileList.new( "#{SPECDIR}/**/*_spec.rb", "#{SPECLIBDIR}/**/*.rb" )
103
+
104
+ TESTDIR = BASEDIR + 'tests'
105
+ TEST_FILES = Rake::FileList.new( "#{TESTDIR}/**/*.tests.rb" )
106
+
107
+ RAKE_TASKDIR = BASEDIR + 'rake'
108
+ RAKE_TASKLIBS = Rake::FileList.new( "#{RAKE_TASKDIR}/*.rb" )
109
+ PKG_TASKLIBS = Rake::FileList.new( "#{RAKE_TASKDIR}/{191_compat,helpers,packaging,rdoc,testing}.rb" )
110
+ PKG_TASKLIBS.include( "#{RAKE_TASKDIR}/manual.rb" ) if MANUALDIR.exist?
111
+
112
+ RAKE_TASKLIBS_URL = 'http://repo.deveiate.org/rake-tasklibs'
113
+
114
+ LOCAL_RAKEFILE = BASEDIR + 'Rakefile.local'
115
+
116
+ EXTRA_PKGFILES = Rake::FileList.new
117
+
118
+ RELEASE_FILES = TEXT_FILES +
119
+ SPEC_FILES +
120
+ TEST_FILES +
121
+ BIN_FILES +
122
+ LIB_FILES +
123
+ EXT_FILES +
124
+ DATA_FILES +
125
+ RAKE_TASKLIBS +
126
+ EXTRA_PKGFILES
127
+
128
+
129
+ RELEASE_FILES << LOCAL_RAKEFILE.to_s if LOCAL_RAKEFILE.exist?
130
+
131
+ RELEASE_ANNOUNCE_ADDRESSES = [
132
+ "Ruby-Talk List <ruby-talk@ruby-lang.org>",
133
+ ]
134
+
135
+ COVERAGE_MINIMUM = ENV['COVERAGE_MINIMUM'] ? Float( ENV['COVERAGE_MINIMUM'] ) : 85.0
136
+ RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib'
137
+ RCOV_OPTS = [
138
+ '--exclude', RCOV_EXCLUDES,
139
+ '--xrefs',
140
+ '--save',
141
+ '--callsites',
142
+ #'--aggregate', 'coverage.data' # <- doesn't work as of 0.8.1.2.0
143
+ ]
144
+
145
+
146
+ ### Load some task libraries that need to be loaded early
147
+ if !RAKE_TASKDIR.exist?
148
+ $stderr.puts "It seems you don't have the build task directory. Shall I fetch it "
149
+ ans = readline( "for you? [y]" )
150
+ ans = 'y' if !ans.nil? && ans.empty?
151
+
152
+ if ans =~ /^y/i
153
+ $stderr.puts "Okay, fetching #{RAKE_TASKLIBS_URL} into #{RAKE_TASKDIR}..."
154
+ system 'hg', 'clone', RAKE_TASKLIBS_URL, "./#{RAKE_TASKDIR}"
155
+ if ! $?.success?
156
+ fail "Damn. That didn't work. Giving up; maybe try manually fetching?"
157
+ end
158
+ else
159
+ $stderr.puts "Then I'm afraid I can't continue. Best of luck."
160
+ fail "Rake tasklibs not present."
161
+ end
162
+
163
+ RAKE_TASKLIBS.include( "#{RAKE_TASKDIR}/*.rb" )
164
+ end
165
+
166
+ require RAKE_TASKDIR + 'helpers.rb'
167
+ include RakefileHelpers
168
+
169
+ # Set the build ID if the mercurial executable is available
170
+ if hg = which( 'hg' )
171
+ id = IO.read('|-') or exec hg.to_s, 'id', '-n'
172
+ PKG_BUILD = "pre%03d" % [(id.chomp[ /^[[:xdigit:]]+/ ] || '1')]
173
+ else
174
+ PKG_BUILD = 'pre000'
175
+ end
176
+ SNAPSHOT_PKG_NAME = "#{PKG_FILE_NAME}.#{PKG_BUILD}"
177
+ SNAPSHOT_GEM_NAME = "#{SNAPSHOT_PKG_NAME}.gem"
178
+
179
+ # Documentation constants
180
+ API_DOCSDIR = DOCSDIR + 'api'
181
+ README_FILE = TEXT_FILES.find {|path| path =~ /^README/ } || 'README'
182
+ RDOC_OPTIONS = [
183
+ '--tab-width=4',
184
+ '--show-hash',
185
+ '--include', BASEDIR.to_s,
186
+ "--main=#{README_FILE}",
187
+ "--title=#{PKG_NAME}",
188
+ ]
189
+ YARD_OPTIONS = [
190
+ '--use-cache',
191
+ '--no-private',
192
+ '--protected',
193
+ '-r', README_FILE,
194
+ '--exclude', 'extconf\\.rb',
195
+ '--files', 'ChangeLog,LICENSE',
196
+ '--output-dir', API_DOCSDIR.to_s,
197
+ '--title', "#{PKG_NAME} #{PKG_VERSION}",
198
+ ]
199
+
200
+ # Release constants
201
+ SMTP_HOST = "mail.faeriemud.org"
202
+ SMTP_PORT = 465 # SMTP + SSL
203
+
204
+ # Project constants
205
+ PROJECT_HOST = 'deveiate.org'
206
+ PROJECT_PUBDIR = '/usr/local/www/public/code/'
207
+ PROJECT_DOCDIR = "#{PROJECT_PUBDIR}/#{PKG_NAME}"
208
+ PROJECT_SCPPUBURL = "#{PROJECT_HOST}:#{PROJECT_PUBDIR}"
209
+ PROJECT_SCPDOCURL = "#{PROJECT_HOST}:#{PROJECT_DOCDIR}"
210
+
211
+ # Gem dependencies: gemname => version
212
+ DEPENDENCIES = {
213
+ }
214
+
215
+ # Developer Gem dependencies: gemname => version
216
+ DEVELOPMENT_DEPENDENCIES = {
217
+ 'rake' => '>= 0.8.7',
218
+ 'rcodetools' => '>= 0.7.0.0',
219
+ 'rcov' => '>= 0.8.1.2.0',
220
+ 'rdoc' => '>= 2.4.3',
221
+ 'RedCloth' => '>= 4.0.3',
222
+ 'rspec' => '>= 1.2.6',
223
+ 'ruby-termios' => '>= 0.9.6',
224
+ 'text-format' => '>= 1.0.0',
225
+ 'tmail' => '>= 1.2.3.1',
226
+ 'diff-lcs' => '>= 1.1.2',
227
+ 'rake-compiler' => '>=0',
228
+ }
229
+
230
+ # Non-gem requirements: packagename => version
231
+ REQUIREMENTS = {
232
+ }
233
+
234
+ # RubyGem specification
235
+ GEMSPEC = Gem::Specification.new do |gem|
236
+ gem.name = PKG_NAME.downcase
237
+ gem.version = PKG_VERSION
238
+
239
+ gem.summary = PKG_SUMMARY
240
+ gem.description = [
241
+ "Have you ever wanted to call exit() with an error condition, but weren't sure what",
242
+ "number to use? No? Maybe it's just me, then.",
243
+ "",
244
+ "Anyway, I was reading W. Richard Stephens's book _Advanced Programming in the UNIX Environment_, and",
245
+ "I wanted to make my program exit with a reasonable exit code just like his C examples, but much",
246
+ "to my chagrin, I couldn't find a 'sysexits' for Ruby! Well, for the other 2 people that actually",
247
+ "care about this kind of thing, now there is!",
248
+ ].join( "\n" )
249
+ gem.post_install_message = [
250
+ "Happy exiting!",
251
+ ].join( "\n" )
252
+
253
+ gem.authors = "Michael Granger"
254
+ gem.email = ["ged@FaerieMUD.org"]
255
+ gem.homepage = 'http://rubygems.org/gems/sysexits'
256
+
257
+ gem.has_rdoc = true
258
+ gem.rdoc_options = RDOC_OPTIONS
259
+ gem.extra_rdoc_files = TEXT_FILES - [ 'Rakefile' ]
260
+
261
+ gem.bindir = BINDIR.relative_path_from(BASEDIR).to_s
262
+ gem.executables = BIN_FILES.select {|pn| File.executable?(pn) }.
263
+ collect {|pn| File.basename(pn) }
264
+ gem.require_paths << EXTDIR.relative_path_from( BASEDIR ).to_s if EXTDIR.exist?
265
+
266
+ if EXTCONF.exist?
267
+ gem.extensions << EXTCONF.relative_path_from( BASEDIR ).to_s
268
+ end
269
+
270
+ gem.files = RELEASE_FILES
271
+ gem.test_files = SPEC_FILES
272
+
273
+ DEPENDENCIES.each do |name, version|
274
+ version = '>= 0' if version.length.zero?
275
+ gem.add_runtime_dependency( name, version )
276
+ end
277
+
278
+ REQUIREMENTS.each do |name, version|
279
+ gem.requirements << [ name, version ].compact.join(' ')
280
+ end
281
+ end
282
+
283
+ $trace = Rake.application.options.trace ? true : false
284
+ $dryrun = Rake.application.options.dryrun ? true : false
285
+ $include_dev_dependencies = false
286
+
287
+ # Load any remaining task libraries
288
+ RAKE_TASKLIBS.each do |tasklib|
289
+ next if tasklib.to_s =~ %r{/helpers\.rb$}
290
+ begin
291
+ trace " loading tasklib %s" % [ tasklib ]
292
+ import tasklib
293
+ rescue ScriptError => err
294
+ fail "Task library '%s' failed to load: %s: %s" %
295
+ [ tasklib, err.class.name, err.message ]
296
+ trace "Backtrace: \n " + err.backtrace.join( "\n " )
297
+ rescue => err
298
+ log "Task library '%s' failed to load: %s: %s. Some tasks may not be available." %
299
+ [ tasklib, err.class.name, err.message ]
300
+ trace "Backtrace: \n " + err.backtrace.join( "\n " )
301
+ end
302
+ end
303
+
304
+ # Load any project-specific rules defined in 'Rakefile.local' if it exists
305
+ import LOCAL_RAKEFILE if LOCAL_RAKEFILE.exist?
306
+
307
+
308
+ #####################################################################
309
+ ### T A S K S
310
+ #####################################################################
311
+
312
+ ### Default task
313
+ task :default => [:clean, :local, :spec, :apidocs, :package]
314
+
315
+ ### Task the local Rakefile can append to -- no-op by default
316
+ task :local
317
+
318
+ ### Task: clean
319
+ CLEAN.include 'coverage', '**/*.orig', '**/*.rej'
320
+ CLOBBER.include 'artifacts', 'coverage.info', 'ChangeLog', PKGDIR
321
+
322
+ ### Task: changelog
323
+ file 'ChangeLog' do |task|
324
+ log "Updating #{task.name}"
325
+
326
+ changelog = make_changelog()
327
+ File.open( task.name, 'w' ) do |fh|
328
+ fh.print( changelog )
329
+ end
330
+ end
331
+
332
+
333
+ ### Task: cruise (Cruisecontrol task)
334
+ desc "Cruisecontrol build"
335
+ task :cruise => [:clean, 'spec:quiet', :package] do |task|
336
+ raise "Artifacts dir not set." if ARTIFACTS_DIR.to_s.empty?
337
+ artifact_dir = ARTIFACTS_DIR.cleanpath + (CC_BUILD_LABEL || Time.now.strftime('%Y%m%d-%T'))
338
+ artifact_dir.mkpath
339
+
340
+ coverage = BASEDIR + 'coverage'
341
+ if coverage.exist? && coverage.directory?
342
+ $stderr.puts "Copying coverage stats..."
343
+ FileUtils.cp_r( 'coverage', artifact_dir )
344
+ end
345
+
346
+ $stderr.puts "Copying packages..."
347
+ FileUtils.cp_r( FileList['pkg/*'].to_a, artifact_dir )
348
+ end
349
+
350
+
351
+ desc "Update the build system to the latest version"
352
+ task :update_build do
353
+ log "Updating the build system"
354
+ run 'hg', '-R', RAKE_TASKDIR, 'pull', '-u'
355
+ log "Updating the Rakefile"
356
+ sh 'rake', '-f', RAKE_TASKDIR + 'Metarakefile'
357
+ end
358
+
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # = sysexits
4
+ #
5
+ # Exit status codes for system programs.
6
+ #
7
+ # Have you ever wanted to call exit() with an error condition, but
8
+ # weren't sure what exit status to use? No? Maybe it's just me, then.
9
+ #
10
+ # Anyway, I was reading manpages late one evening before retiring to
11
+ # bed in my palatial estate in rural Oregon, and I stumbled across
12
+ # sysexits(3). Much to my chagrin, I couldn't find a 'sysexits' for
13
+ # Ruby! Well, for the other 2 people that actually care about style(9)
14
+ # as it applies to Ruby code, now there is one!
15
+ #
16
+ # == License
17
+ #
18
+ # This file was derived almost entirely from the BSD sysexits.h, which
19
+ # is distributed under the following license:
20
+ #
21
+ # Copyright (c) 1987, 1993
22
+ # The Regents of the University of California. All rights reserved.
23
+ #
24
+ # Redistribution and use in source and binary forms, with or without
25
+ # modification, are permitted provided that the following conditions
26
+ # are met:
27
+ #
28
+ # 1. Redistributions of source code must retain the above copyright
29
+ # notice, this list of conditions and the following disclaimer.
30
+ # 2. Redistributions in binary form must reproduce the above copyright
31
+ # notice, this list of conditions and the following disclaimer in the
32
+ # documentation and/or other materials provided with the distribution.
33
+ # 3. All advertising materials mentioning features or use of this software
34
+ # must display the following acknowledgement:
35
+ # This product includes software developed by the University of
36
+ # California, Berkeley and its contributors.
37
+ # 4. Neither the name of the University nor the names of its contributors
38
+ # may be used to endorse or promote products derived from this software
39
+ # without specific prior written permission.
40
+ #
41
+ # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
42
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
45
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
+ # SUCH DAMAGE.
52
+ #
53
+ module Sysexits
54
+
55
+ # The library version
56
+ VERSION = '1.0.0'
57
+
58
+ # The library's revision id
59
+ REVISION = %q$Revision: d43f3935008a $
60
+
61
+
62
+ #
63
+ # The constants
64
+ #
65
+
66
+ # Successful termination
67
+ EX_OK = 0
68
+
69
+
70
+ # The base value for sysexit codes
71
+ EX__BASE = 64
72
+
73
+ # The command was used incorrectly, e.g., with the wrong number of
74
+ # arguments, a bad flag, a bad syntax in a parameter, or whatever.
75
+ EX_USAGE = 64
76
+
77
+ # The input data was incorrect in some way. This should only be used
78
+ # for user data, not system files.
79
+ EX_DATAERR = 65
80
+
81
+ # An input file (not a system file) did not exist or was not readable.
82
+ # This could also include errors like "No message" to a mailer (if
83
+ # it cared to catch it).
84
+ EX_NOINPUT = 66
85
+
86
+ # The user specified did not exist. This might be used for mail
87
+ # addresses or remote logins.
88
+ EX_NOUSER = 67
89
+
90
+ # The host specified did not exist. This is used in mail addresses
91
+ # or network requests.
92
+ EX_NOHOST = 68
93
+
94
+ # A service is unavailable. This can occur if a support program or
95
+ # file does not exist. This can also be used as a catchall message
96
+ # when something you wanted to do doesn't work, but you don't know
97
+ # why.
98
+ EX_UNAVAILABLE = 69
99
+
100
+ # An internal software error has been detected. This should be limited
101
+ # to non-operating system related errors.
102
+ EX_SOFTWARE = 70
103
+
104
+ # An operating system error has been detected. This is intended to
105
+ # be used for such things as "cannot fork", "cannot create pipe", or
106
+ # the like. It includes things like getuid returning a user that
107
+ # does not exist in the passwd file.
108
+ EX_OSERR = 71
109
+
110
+ # Some system file (e.g., /etc/passwd, /etc/utmp, etc.) does not
111
+ # exist, cannot be opened, or has some sort of error (e.g., syntax
112
+ # error).
113
+ EX_OSFILE = 72
114
+
115
+ # A (user specified) output file cannot be created.
116
+ EX_CANTCREAT = 73
117
+
118
+ # An error occurred while doing I/O on a file.
119
+ EX_IOERR = 74
120
+
121
+ # Temporary failure, indicating something that is not really a serious
122
+ # error. In sendmail, this means that a mailer (e.g.) could not
123
+ # create a connection, and the request should be reattempted later.
124
+ EX_TEMPFAIL = 75
125
+
126
+ # The remote system returned something that was "not possible" during
127
+ # a protocol exchange.
128
+ EX_PROTOCOL = 76
129
+
130
+ # You did not have sufficient permission to perform the operation.
131
+ # This is not intended for file system problems, which should use
132
+ # NOINPUT or CANTCREAT, but rather for higher level permissions.
133
+ EX_NOPERM = 77
134
+
135
+ # There was an error in a user-specified configuration value.
136
+ EX_CONFIG = 78
137
+
138
+
139
+ # The maximum listed value. Automatically determined because, well, we can
140
+ # and I'll forget to update this if I ever add any codes.
141
+ EX__MAX = constants.
142
+ select {|name| name =~ /^EX_/ }.
143
+ collect {|name| self.const_get(name) }.max
144
+
145
+
146
+ # Mapping of human-readable Symbols to statuses
147
+ STATUS_CODES = {
148
+ :ok => EX_OK,
149
+ :success => EX_OK,
150
+
151
+ :_base => EX__BASE,
152
+
153
+ :usage => EX_USAGE,
154
+
155
+ :dataerr => EX_DATAERR,
156
+ :data_error => EX_DATAERR,
157
+
158
+ :noinput => EX_NOINPUT,
159
+ :input_missing => EX_NOINPUT,
160
+
161
+ :nouser => EX_NOUSER,
162
+ :no_such_user => EX_NOUSER,
163
+
164
+ :nohost => EX_NOHOST,
165
+ :no_such_host => EX_NOHOST,
166
+
167
+ :unavailable => EX_UNAVAILABLE,
168
+ :service_unavailable => EX_UNAVAILABLE,
169
+
170
+ :software => EX_SOFTWARE,
171
+ :software_error => EX_SOFTWARE,
172
+
173
+ :oserr => EX_OSERR,
174
+ :operating_system_error => EX_OSERR,
175
+
176
+ :osfile => EX_OSFILE,
177
+ :operating_system_file_error => EX_OSFILE,
178
+
179
+ :cantcreat => EX_CANTCREAT,
180
+ :cant_create_output => EX_CANTCREAT,
181
+
182
+ :ioerr => EX_IOERR,
183
+
184
+ :tempfail => EX_TEMPFAIL,
185
+ :temporary_failure => EX_TEMPFAIL,
186
+ :try_again => EX_TEMPFAIL,
187
+
188
+ :protocol => EX_PROTOCOL,
189
+ :protocol_error => EX_PROTOCOL,
190
+
191
+ :noperm => EX_NOPERM,
192
+ :permission_denied => EX_NOPERM,
193
+
194
+ :config => EX_CONFIG,
195
+ :config_error => EX_CONFIG,
196
+
197
+ :_max => EX__MAX,
198
+
199
+ }
200
+
201
+
202
+ ###############
203
+ module_function
204
+ ###############
205
+
206
+ ### Enhanced exit!
207
+ ### @param [Symbol, String, Fixnum] status the exit status, which can be either one of the
208
+ ### keys of STATUS_CODES or a number.
209
+ def exit( status=EX_OK )
210
+ status = case status
211
+ when Symbol, String
212
+ STATUS_CODES[ status.to_sym ] or
213
+ raise "unknown status %p" % [ status ]
214
+ else
215
+ status
216
+ end
217
+
218
+ ::Kernel.exit( status )
219
+ end
220
+
221
+ end # module Sysexits
222
+