nkryptic-sandbox 0.2.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/CHANGELOG ADDED
@@ -0,0 +1,10 @@
1
+
2
+ v0.2.0 Functional basic version.
3
+ Requires rubygems and only installs environment (with optional gem installs).
4
+
5
+ v0.1.2 Branched fullversion from master.
6
+ Full version will include ruby and rubygems installs.
7
+
8
+ v0.1.1 Adding rspec and cucumber
9
+
10
+ v0.1.0 First version
data/README.rdoc ADDED
@@ -0,0 +1,117 @@
1
+ = Sandbox
2
+
3
+ * http://github.com/nkryptic/sandbox
4
+
5
+ == DESCRIPTION:
6
+
7
+ Inspired by Python's virtualenv[http://pypi.python.org/pypi/virtualenv]
8
+ project, Sandbox is a utility to create sandboxed Ruby/Rubygems environments.
9
+
10
+ It is meant to address the following issues:
11
+
12
+ * Conflicts with unspecified gem dependency versions.
13
+ * Applications can have their own gem repositories.
14
+ * Permissions for installing your own gems.
15
+ * Ability to try gems out without installing into your global repository.
16
+ * A Simple way to enable this.
17
+
18
+ Running from your own gem repositories is fairly straight-forward, but
19
+ managing the necessary environment is a pain. This utility will create a new
20
+ environment which may be activated by the script `bin/activate` in your
21
+ sandbox directory.
22
+
23
+ Run the script with the following to enable your new environment:
24
+
25
+ $ source bin/activate_sandbox
26
+
27
+ When you want to leave the environment:
28
+
29
+ $ deactivate_sandbox
30
+
31
+ == NOTES:
32
+
33
+ * It creates an environment that has its own installation directory for Gems.
34
+ * It doesn't share gems with other sandbox environments.
35
+ * It (optionally) doesn't use the globally installed gems either.
36
+ * It will use a local to the sandbox .gemrc file
37
+
38
+ == FEATURES/PROBLEMS:
39
+
40
+ Activating your sandbox environment will change your HOME directory
41
+ temporarily to the sandbox directory. Other environment variables are set to
42
+ enable this funtionality, so if you may experience odd behavior. Everything
43
+ should be reset when you deactivate the sandbox.
44
+
45
+ == USAGE:
46
+
47
+ Create a new sandbox (rake gem installed by default):
48
+ $ cd ~/ruby-projects
49
+ $ sandbox my-new-sandbox
50
+
51
+ Create a new sandbox with output (rake gem installed by default):
52
+ $ cd ~/ruby-projects
53
+ $ sandbox my-new-sandbox -v
54
+ creating new sandbox in /home/nkryptic/ruby-projects/my-new-sandbox
55
+ installing gems:
56
+ gem: rake
57
+
58
+ Create a new sandbox with no gems installed:
59
+ $ cd ~/ruby-projects
60
+ $ sandbox my-new-sandbox -n
61
+ creating new sandbox in /home/nkryptic/ruby-projects/my-new-sandbox
62
+ installing gems:
63
+
64
+ Create a new sandbox with specific gems:
65
+ $ cd ~/ruby-projects
66
+ $ sandbox my-new-sandbox -g rake,rails
67
+ creating new sandbox in /home/nkryptic/ruby-projects/my-new-sandbox
68
+ installing gems:
69
+ gem: rake
70
+ gem: rails
71
+ gem: rspec
72
+
73
+ == FUTURE PLANS:
74
+
75
+ I hope to expand the full version branch to allow for installing both rubygems
76
+ and ruby as part of the sandbox. This would enable experimentation with
77
+ different versions of both and exclude the requirement on needing rubygems in
78
+ the first place.
79
+
80
+ == REQUIREMENTS:
81
+
82
+ * ruby
83
+ * rubygems (currently, until full version complete)
84
+
85
+ == INSTALL:
86
+
87
+ sudo gem install nkryptic-sandbox -s http://gems.github.com
88
+
89
+ or
90
+
91
+ sudo gem sources --add http://gems.github.com
92
+ sudo gem install nkryptic-sandbox
93
+
94
+ == LICENSE:
95
+
96
+ (The MIT License)
97
+
98
+ Copyright (c) 2008 Jacob Radford
99
+
100
+ Permission is hereby granted, free of charge, to any person obtaining
101
+ a copy of this software and associated documentation files (the
102
+ 'Software'), to deal in the Software without restriction, including
103
+ without limitation the rights to use, copy, modify, merge, publish,
104
+ distribute, sublicense, and/or sell copies of the Software, and to
105
+ permit persons to whom the Software is furnished to do so, subject to
106
+ the following conditions:
107
+
108
+ The above copyright notice and this permission notice shall be
109
+ included in all copies or substantial portions of the Software.
110
+
111
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
112
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
113
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
114
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
115
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
116
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
117
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'lib/sandbox' unless defined? Sandbox
5
+
6
+ begin
7
+ require 'echoe'
8
+
9
+ Echoe.new( 'sandbox', Sandbox::Version::STRING ) do |p|
10
+ # p.rubyforge_name = 'nkryptic'
11
+ # p.summary = "Create virtual ruby/rubygems sandboxes."
12
+ p.description = "Create virtual ruby/rubygems sandboxes."
13
+ p.url = "http://github.com/nkryptic/sandbox"
14
+ p.author = "Jacob Radford"
15
+ p.email = "nkryptic@gmail.com"
16
+ p.ignore_pattern = [ "tmp/*", "script/*" ]
17
+ p.development_dependencies = [
18
+ 'echoe ~> 3.0',
19
+ 'rspec ~> 1.1.0',
20
+ 'mocha ~> 0.9',
21
+ ]
22
+ # p.dependencies = ['ParseTree >=2.1.1', 'ruby2ruby >=1.1.8']
23
+ end
24
+
25
+ rescue LoadError => boom
26
+ puts "You are missing a dependency required for meta-operations on this gem."
27
+ puts "#{boom.to_s.capitalize}."
28
+ end
29
+
30
+ Dir[ "#{File.dirname(__FILE__)}/tasks/*.rake" ].sort.each { |ext| load ext }
31
+
32
+ # desc 'Generate RDoc documentation for Sandbox.'
33
+ # Rake::RDocTask.new( :rdoc ) do |rdoc|
34
+ # files = [ 'README', 'LICENSE', 'lib/**/*.rb' ]
35
+ # rdoc.rdoc_files.add( files )
36
+ # rdoc.main = "README" # page to start on
37
+ # rdoc.title = "sandbox"
38
+ # # rdoc.template = File.exists?( t="/Users/chris/ruby/projects/err/rock/template.rb" ) ? t : "/var/www/rock/template.rb"
39
+ # rdoc.rdoc_dir = 'doc' # rdoc output folder
40
+ # rdoc.options << '--inline-source'
41
+ # end
data/TODO ADDED
@@ -0,0 +1,14 @@
1
+
2
+ * allow gem versions to be specified when installing
3
+ * better documentation
4
+ * of the codebase
5
+ * more specs
6
+ * why not try for 100% coverage
7
+ * improve ui output
8
+ * use verbosity level
9
+ * include more messages about status
10
+ * move to ui class?
11
+ * user config
12
+ * list of gems to install
13
+ ~/.sandbox/config
14
+
data/bin/sandbox ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require 'sandbox/cli'
6
+ Sandbox::CLI.execute( ARGV )
@@ -0,0 +1,13 @@
1
+ Feature: Development processes of newgem itself (rake tasks)
2
+
3
+ As a Newgem maintainer or contributor
4
+ I want rake tasks to maintain and release the gem
5
+ So that I can spend time on the tests and code, and not excessive time on maintenance processes
6
+
7
+ Scenario: Generate RubyGem
8
+ Given this project is active project folder
9
+ And 'pkg' folder is deleted
10
+ When task 'rake gem' is invoked
11
+ Then folder 'pkg' is created
12
+ And file with name matching 'pkg/*.gem' is created else you should run "rake manifest" to fix this
13
+ And gem spec key 'rdoc_options' contains /--mainREADME.rdoc/
@@ -0,0 +1,174 @@
1
+ def in_project_folder(&block)
2
+ project_folder = @active_project_folder || @tmp_root
3
+ FileUtils.chdir(project_folder, &block)
4
+ end
5
+
6
+ def in_home_folder(&block)
7
+ FileUtils.chdir(@home_path, &block)
8
+ end
9
+
10
+ Given %r{^a safe folder} do
11
+ FileUtils.rm_rf @tmp_root = File.dirname(__FILE__) + "/../../tmp"
12
+ FileUtils.mkdir_p @tmp_root
13
+ FileUtils.mkdir_p @home_path = File.expand_path(File.join(@tmp_root, "home"))
14
+ @lib_path = File.expand_path(File.dirname(__FILE__) + '/../../lib')
15
+ Given "env variable $HOME set to '#{@home_path}'"
16
+ end
17
+
18
+ Given %r{^this project is active project folder} do
19
+ Given "a safe folder"
20
+ @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
21
+ end
22
+
23
+ Given %r{^env variable \$([\w_]+) set to '(.*)'} do |env_var, value|
24
+ ENV[env_var] = value
25
+ end
26
+
27
+ def force_local_lib_override(project_name = @project_name)
28
+ rakefile = File.read(File.join(project_name, 'Rakefile'))
29
+ File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
30
+ f << "$:.unshift('#{@lib_path}')\n"
31
+ f << rakefile
32
+ end
33
+ end
34
+
35
+ def setup_active_project_folder project_name
36
+ @active_project_folder = File.join(@tmp_root, project_name)
37
+ @project_name = project_name
38
+ end
39
+
40
+ Given %r{'(.*)' folder is deleted} do |folder|
41
+ in_project_folder do
42
+ FileUtils.rm_rf folder
43
+ end
44
+ end
45
+
46
+ When %r{^'(.*)' generator is invoked with arguments '(.*)'$} do |generator, arguments|
47
+ FileUtils.chdir(@active_project_folder) do
48
+ if Object.const_defined?("APP_ROOT")
49
+ APP_ROOT.replace(FileUtils.pwd)
50
+ else
51
+ APP_ROOT = FileUtils.pwd
52
+ end
53
+ run_generator(generator, arguments.split(' '), SOURCES)
54
+ end
55
+ end
56
+
57
+ When %r{run executable '(.*)' with arguments '(.*)'} do |executable, arguments|
58
+ @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
59
+ FileUtils.chdir(@active_project_folder) do
60
+ system "ruby #{executable} #{arguments} > #{@stdout}"
61
+ end
62
+ end
63
+
64
+ When %r{^task 'rake (.*)' is invoked$} do |task|
65
+ @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
66
+ FileUtils.chdir(@active_project_folder) do
67
+ system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
68
+ end
69
+ end
70
+
71
+ Then %r{^folder '(.*)' is created} do |folder|
72
+ in_project_folder do
73
+ File.exists?(folder).should be_true
74
+ end
75
+ end
76
+
77
+ Then %r{^file '(.*)' (is|is not) created} do |file, is|
78
+ in_project_folder do
79
+ File.exists?(file).should(is == 'is' ? be_true : be_false)
80
+ end
81
+ end
82
+
83
+ Then %r{^file with name matching '(.*)' is created} do |pattern|
84
+ in_project_folder do
85
+ Dir[pattern].should_not be_empty
86
+ end
87
+ end
88
+
89
+ Then %r{gem file '(.*)' and generated file '(.*)' should be the same} do |gem_file, project_file|
90
+ File.exists?(gem_file).should be_true
91
+ File.exists?(project_file).should be_true
92
+ gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
93
+ project_file_contents = File.read(File.join(@active_project_folder, project_file))
94
+ project_file_contents.should == gem_file_contents
95
+ end
96
+
97
+ Then %r{^output same as contents of '(.*)'$} do |file|
98
+ expected_output = File.read(File.join(File.dirname(__FILE__) + "/../expected_outputs", file))
99
+ actual_output = File.read(File.dirname(__FILE__) + "/../../tmp/#{@stdout}")
100
+ actual_output.should == expected_output
101
+ end
102
+
103
+ Then %r{^(does|does not) invoke generator '(.*)'$} do |does_invoke, generator|
104
+ actual_output = File.read(File.dirname(__FILE__) + "/../../tmp/#{@stdout}")
105
+ does_invoke == "does" ?
106
+ actual_output.should(match(/dependency\s+#{generator}/)) :
107
+ actual_output.should_not(match(/dependency\s+#{generator}/))
108
+ end
109
+
110
+ Then %r{help options '(.*)' and '(.*)' are displayed} do |opt1, opt2|
111
+ actual_output = File.read(@stdout)
112
+ actual_output.should match(/#{opt1}/)
113
+ actual_output.should match(/#{opt2}/)
114
+ end
115
+
116
+ Then %r{^output (does|does not) match \/(.*)\/} do |does, regex|
117
+ actual_output = File.read(@stdout)
118
+ (does == 'does') ?
119
+ actual_output.should(match(/#{regex}/)) :
120
+ actual_output.should_not(match(/#{regex}/))
121
+ end
122
+
123
+ Then %r{^contents of file '(.*)' (does|does not) match \/(.*)\/} do |file, does, regex|
124
+ in_project_folder do
125
+ actual_output = File.read(file)
126
+ (does == 'does') ?
127
+ actual_output.should(match(/#{regex}/)) :
128
+ actual_output.should_not(match(/#{regex}/))
129
+ end
130
+ end
131
+
132
+ Then %r{^all (\d+) tests pass} do |expected_test_count|
133
+ expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
134
+ actual_output = File.read(@stdout)
135
+ actual_output.should match(expected)
136
+ end
137
+
138
+ Then %r{^all (\d+) examples pass} do |expected_test_count|
139
+ expected = %r{^#{expected_test_count} examples?, 0 failures}
140
+ actual_output = File.read(@stdout)
141
+ actual_output.should match(expected)
142
+ end
143
+
144
+ Then %r{^yaml file '(.*)' contains (\{.*\})} do |file, yaml|
145
+ in_project_folder do
146
+ yaml = eval yaml
147
+ YAML.load(File.read(file)).should == yaml
148
+ end
149
+ end
150
+
151
+ Then %r{^Rakefile can display tasks successfully} do
152
+ @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
153
+ FileUtils.chdir(@active_project_folder) do
154
+ system "rake -T > #{@stdout} 2> #{@stdout}"
155
+ end
156
+ actual_output = File.read(@stdout)
157
+ actual_output.should match(/^rake\s+\w+\s+#\s.*/)
158
+ end
159
+
160
+ Then %r{^task 'rake (.*)' is executed successfully} do |task|
161
+ @stdout.should_not be_nil
162
+ actual_output = File.read(@stdout)
163
+ actual_output.should_not match(/^Don't know how to build task '#{task}'/)
164
+ actual_output.should_not match(/Error/i)
165
+ end
166
+
167
+ Then %r{^gem spec key '(.*)' contains \/(.*)\/} do |key, regex|
168
+ in_project_folder do
169
+ gem_file = Dir["pkg/*.gem"].first
170
+ gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
171
+ spec_value = gem_spec.send(key.to_sym)
172
+ spec_value.to_s.should match(/#{regex}/)
173
+ end
174
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + "/../../lib/sandbox"
2
+
3
+ # gem 'cucumber'
4
+ # require 'cucumber'
5
+ # gem 'rspec'
6
+ # require 'spec'
7
+
8
+ begin
9
+ require 'cucumber'
10
+ require 'spec'
11
+ rescue LoadError
12
+ require 'rubygems'
13
+ require 'cucumber'
14
+ require 'spec'
15
+ end
@@ -0,0 +1,185 @@
1
+
2
+ require 'optparse'
3
+ require 'sandbox'
4
+
5
+ module Sandbox
6
+ class CLI
7
+
8
+ DEFAULTS = {
9
+ :gems => [ 'rake', ]
10
+ }
11
+
12
+ ## CLASS METHODS
13
+ class << self
14
+
15
+ # invokes sandbox via command-line ARGV as the options
16
+ def execute( args = ARGV )
17
+ verify_environment!
18
+ parse( args ).execute!
19
+ rescue Exception => error
20
+ handle_error( error )
21
+ end
22
+
23
+ # returns a new CLI instance which has parsed the given arguments.
24
+ # will load the command to execute based upon the arguements.
25
+ # if an error occurs, it will print out simple error message and exit
26
+ def parse( args )
27
+ cli = new
28
+ cli.parse_args!( args )
29
+ cli
30
+ end
31
+
32
+ def verify_environment!
33
+ raise LoadedSandboxError if ENV[ 'SANDBOX' ]
34
+ end
35
+
36
+ # pretty error handling
37
+ def handle_error( error )
38
+ case error
39
+ when Sandbox::Error
40
+ puts error.message
41
+ when StandardError #, Timeout::Error
42
+ message = [ "Error: #{error.message}" ]
43
+ message.concat( error.backtrace.collect { |bt| " #{bt}" } ) if Sandbox.really_verbose?
44
+ puts message.join( "\n" )
45
+ when Interrupt
46
+ puts "Interrupted"
47
+ else
48
+ raise error
49
+ end
50
+ end
51
+
52
+ end
53
+ ## END CLASS METHODS
54
+
55
+ ## PUBLIC INSTANCE METHODS
56
+ public
57
+
58
+ # The options for this execution.
59
+ attr_reader :options
60
+
61
+ # setup of a new CLI instance
62
+ def initialize
63
+ @options = DEFAULTS.dup
64
+ @parser = nil
65
+ end
66
+
67
+
68
+ # perform the sandbox creation
69
+ def execute!
70
+ targets = options.delete( :args )
71
+
72
+ if targets.size < 1
73
+ raise Sandbox::Error.new( 'no target specified - see `sandbox --help` for assistance' )
74
+ elsif targets.size > 1
75
+ raise Sandbox::Error.new( 'multiple targets specified - see `sandbox --help` for assistance' )
76
+ end
77
+
78
+ options[ :target ] = targets[0]
79
+
80
+ Sandbox::Installer.new( options ).populate
81
+ end
82
+
83
+ # processes +args+ to:
84
+ #
85
+ # * load global option for the application
86
+ # * determine command name to lookup in CommandManager
87
+ # * load command and have it process any add't options
88
+ # * catches exceptions for unknown switches or commands
89
+ def parse_args!( args )
90
+ options[ :original_args ] = args.dup
91
+ parser.parse!( args )
92
+ rescue OptionParser::ParseError => ex
93
+ raise_parse_error( ex.reason, ex.args )
94
+ else
95
+ options[ :args ] = args
96
+ end
97
+
98
+ def parser
99
+ @parser ||= create_parser
100
+ end
101
+
102
+ def create_parser
103
+ OptionParser.new do |o|
104
+ o.set_summary_indent(' ')
105
+ o.program_name = 'sandbox TARGET'
106
+ o.define_head "Create virtual ruby/rubygems sandboxes."
107
+ o.separator ""
108
+
109
+ o.separator "ARGUMENTS:"
110
+ o.separator " TARGET Target path to new sandbox. Must not exist beforehand."
111
+ o.separator ""
112
+
113
+ o.separator "OPTIONS"
114
+ o.on( '-g', '--gems gem1,gem2', Array, 'Gems to install after sandbox is created. (defaults to [rake])' ) { |gems| @options[ :gems ] = gems }
115
+ o.on( '-n', '--no-gems', 'Do not install any gems after sandbox is created.)' ) { @options[ :gems ] = [] }
116
+ o.on( '-q', '--quiet', 'Show less output. (multiple allowed)' ) { |f| Sandbox.decrease_verbosity }
117
+ o.on( '-v', '--verbose', 'Show more output. (multiple allowed)' ) { |f| Sandbox.increase_verbosity }
118
+ o.on_tail( '-h', '--help', 'Show this help message and exit.' ) { puts o; exit }
119
+ o.on_tail( '-H', '--long-help', 'Show the full description about the program' ) { puts long_help; exit }
120
+ o.on_tail( '-V', '--version', 'Display the program version and exit.' ) { puts Sandbox::Version::STRING; exit }
121
+ o.separator ""
122
+ end
123
+ end
124
+
125
+ def show_help
126
+ puts parser
127
+ end
128
+
129
+ def long_help
130
+ unindent( <<-HELP )
131
+ --------------------------------------------------------------------------------
132
+ Sandbox is a utility to create sandboxed Ruby/Rubygems environments.
133
+
134
+ It is meant to address the following issues:
135
+ 1. Conflicts with unspecified gem dependency versions.
136
+ 2. Applications can have their own gem repositories.
137
+ 3. Permissions for installing your own gems.
138
+ 4. Ability to try gems out without installing into your global repository.
139
+ 5. A Simple way to enable this.
140
+
141
+ Running from your own gem repositories is fairly straight-forward, but
142
+ managing the necessary environment is a pain. This utility will create a new
143
+ environment which may be activated by the script `bin/activate` in your
144
+ sandbox directory.
145
+
146
+ Run the script with the following to enable your new environment:
147
+ $ source bin/activate
148
+
149
+ When you want to leave the environment:
150
+ $ deactivate
151
+
152
+ NOTES:
153
+ 1. It creates an environment that has its own installation directory for Gems.
154
+ 2. It doesn't share gems with other sandbox environments.
155
+ 3. It (optionally) doesn't use the globally installed gems either.
156
+ 4. It will use a local to the sandbox .gemrc file
157
+
158
+ WARNINGS:
159
+ Activating your sandbox environment will change your HOME directory
160
+ temporarily to the sandbox directory. Other environment variables are set to
161
+ enable this funtionality, so if you may experience odd behavior. Everything
162
+ should be reset when you deactivate the sandbox.
163
+ HELP
164
+ end
165
+
166
+ def unindent( output )
167
+ indent = output[/\A\s*/]
168
+ output.strip.gsub(/^#{indent}/, "")
169
+ end
170
+
171
+ ## END PUBLIC INSTANCE METHODS
172
+
173
+
174
+ ## PRIVATE INSTANCE METHODS
175
+ private
176
+
177
+ def raise_parse_error( reason, args=[] )
178
+ raise Sandbox::ParseError.new( reason, args )
179
+ end
180
+
181
+ ## END PRIVATE INSTANCE METHODS
182
+
183
+ end
184
+
185
+ end
@@ -0,0 +1,43 @@
1
+
2
+ module Sandbox
3
+
4
+ class Error < StandardError
5
+
6
+ def initialize( msg=nil )
7
+ super msg
8
+ end
9
+
10
+ def message
11
+ out = []
12
+ value = super
13
+ out << "Sandbox error: #{value}"
14
+ out.concat( backtrace.collect { |bt| " #{bt}" } ) if Sandbox.really_verbose?
15
+ out.join( "\n" )
16
+ end
17
+
18
+ end
19
+
20
+ class LoadedSandboxError < Sandbox::Error
21
+
22
+ def initialize( msg=nil )
23
+ msg ||= "You cannot run sandbox from a loaded sandbox environment"
24
+ end
25
+
26
+ end
27
+
28
+ class ParseError < Sandbox::Error
29
+
30
+ def initialize( reason=nil, args=[] )
31
+ if args.is_a?( Array ) and args.size > 0
32
+ msg = "#{reason} => #{args.join( ' ' )}"
33
+ elsif args.is_a?( String ) and args.length > 0
34
+ msg = "#{reason} => #{args}"
35
+ else
36
+ msg = reason
37
+ end
38
+ super msg
39
+ end
40
+
41
+ end
42
+
43
+ end