piggly 1.2.1 → 2.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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +163 -0
  3. data/Rakefile +29 -15
  4. data/bin/piggly +4 -244
  5. data/lib/piggly.rb +19 -17
  6. data/lib/piggly/command.rb +9 -0
  7. data/lib/piggly/command/base.rb +148 -0
  8. data/lib/piggly/command/report.rb +162 -0
  9. data/lib/piggly/command/test.rb +157 -0
  10. data/lib/piggly/command/trace.rb +90 -0
  11. data/lib/piggly/command/untrace.rb +78 -0
  12. data/lib/piggly/compiler.rb +7 -5
  13. data/lib/piggly/compiler/cache_dir.rb +119 -0
  14. data/lib/piggly/compiler/coverage_report.rb +63 -0
  15. data/lib/piggly/compiler/trace_compiler.rb +105 -0
  16. data/lib/piggly/config.rb +47 -22
  17. data/lib/piggly/dumper.rb +9 -0
  18. data/lib/piggly/dumper/index.rb +121 -0
  19. data/lib/piggly/dumper/qualified_name.rb +36 -0
  20. data/lib/piggly/dumper/qualified_type.rb +81 -0
  21. data/lib/piggly/dumper/reified_procedure.rb +142 -0
  22. data/lib/piggly/dumper/skeleton_procedure.rb +102 -0
  23. data/lib/piggly/installer.rb +84 -42
  24. data/lib/piggly/parser.rb +43 -49
  25. data/lib/piggly/parser/grammar.tt +289 -313
  26. data/lib/piggly/parser/nodes.rb +270 -211
  27. data/lib/piggly/parser/traversal.rb +35 -33
  28. data/lib/piggly/parser/treetop_ruby19_patch.rb +1 -1
  29. data/lib/piggly/profile.rb +81 -60
  30. data/lib/piggly/reporter.rb +5 -18
  31. data/lib/piggly/reporter/base.rb +103 -0
  32. data/lib/piggly/reporter/html_dsl.rb +63 -0
  33. data/lib/piggly/reporter/index.rb +108 -0
  34. data/lib/piggly/reporter/procedure.rb +104 -0
  35. data/lib/piggly/reporter/resources/highlight.js +21 -0
  36. data/lib/piggly/reporter/{piggly.css → resources/piggly.css} +52 -12
  37. data/lib/piggly/reporter/{sortable.js → resources/sortable.js} +0 -0
  38. data/lib/piggly/tags.rb +280 -0
  39. data/lib/piggly/task.rb +191 -40
  40. data/lib/piggly/util.rb +8 -27
  41. data/lib/piggly/util/blankslate.rb +114 -0
  42. data/lib/piggly/util/cacheable.rb +19 -0
  43. data/lib/piggly/util/enumerable.rb +44 -0
  44. data/lib/piggly/util/file.rb +17 -0
  45. data/lib/piggly/util/process_queue.rb +96 -0
  46. data/lib/piggly/util/thunk.rb +39 -0
  47. data/lib/piggly/version.rb +8 -8
  48. data/spec/examples/compiler/cacheable_spec.rb +190 -0
  49. data/spec/examples/compiler/report_spec.rb +25 -0
  50. data/spec/{compiler → examples/compiler}/trace_spec.rb +7 -57
  51. data/spec/examples/config_spec.rb +61 -0
  52. data/spec/examples/dumper/index_spec.rb +197 -0
  53. data/spec/examples/dumper/procedure_spec.rb +116 -0
  54. data/spec/{grammar → examples/grammar}/expression_spec.rb +60 -60
  55. data/spec/{grammar → examples/grammar}/statements/assignment_spec.rb +15 -15
  56. data/spec/examples/grammar/statements/declaration_spec.rb +21 -0
  57. data/spec/{grammar → examples/grammar}/statements/exception_spec.rb +10 -10
  58. data/spec/{grammar → examples/grammar}/statements/if_spec.rb +47 -34
  59. data/spec/{grammar → examples/grammar}/statements/loop_spec.rb +5 -5
  60. data/spec/{grammar → examples/grammar}/statements/sql_spec.rb +11 -11
  61. data/spec/{grammar → examples/grammar}/tokens/comment_spec.rb +11 -11
  62. data/spec/{grammar → examples/grammar}/tokens/datatype_spec.rb +14 -8
  63. data/spec/{grammar → examples/grammar}/tokens/identifier_spec.rb +26 -10
  64. data/spec/{grammar → examples/grammar}/tokens/keyword_spec.rb +5 -5
  65. data/spec/{grammar → examples/grammar}/tokens/label_spec.rb +7 -7
  66. data/spec/{grammar → examples/grammar}/tokens/literal_spec.rb +1 -1
  67. data/spec/examples/grammar/tokens/lval_spec.rb +50 -0
  68. data/spec/{grammar → examples/grammar}/tokens/number_spec.rb +1 -1
  69. data/spec/{grammar → examples/grammar}/tokens/sqlkeywords_spec.rb +1 -1
  70. data/spec/{grammar → examples/grammar}/tokens/string_spec.rb +9 -9
  71. data/spec/{grammar → examples/grammar}/tokens/whitespace_spec.rb +1 -1
  72. data/spec/examples/installer_spec.rb +59 -0
  73. data/spec/examples/parser/nodes_spec.rb +73 -0
  74. data/spec/examples/parser/traversal_spec.rb +14 -0
  75. data/spec/examples/parser_spec.rb +115 -0
  76. data/spec/examples/profile_spec.rb +153 -0
  77. data/spec/{reporter/html_spec.rb → examples/reporter/html/dsl_spec.rb} +0 -0
  78. data/spec/examples/reporter/html/index_spec.rb +0 -0
  79. data/spec/examples/reporter/html_spec.rb +1 -0
  80. data/spec/examples/reporter_spec.rb +0 -0
  81. data/spec/{compiler → examples}/tags_spec.rb +10 -10
  82. data/spec/examples/task_spec.rb +0 -0
  83. data/spec/examples/util/cacheable_spec.rb +41 -0
  84. data/spec/examples/util/enumerable_spec.rb +64 -0
  85. data/spec/examples/util/file_spec.rb +40 -0
  86. data/spec/examples/util/process_queue_spec.rb +16 -0
  87. data/spec/examples/util/thunk_spec.rb +58 -0
  88. data/spec/examples/version_spec.rb +0 -0
  89. data/spec/issues/007_spec.rb +25 -0
  90. data/spec/issues/008_spec.rb +73 -0
  91. data/spec/issues/018_spec.rb +25 -0
  92. data/spec/spec_helper.rb +253 -9
  93. metadata +136 -93
  94. data/README.markdown +0 -116
  95. data/lib/piggly/compiler/cache.rb +0 -151
  96. data/lib/piggly/compiler/pretty.rb +0 -67
  97. data/lib/piggly/compiler/queue.rb +0 -46
  98. data/lib/piggly/compiler/tags.rb +0 -244
  99. data/lib/piggly/compiler/trace.rb +0 -91
  100. data/lib/piggly/filecache.rb +0 -40
  101. data/lib/piggly/parser/parser.rb +0 -11794
  102. data/lib/piggly/reporter/html.rb +0 -207
  103. data/spec/compiler/cache_spec.rb +0 -9
  104. data/spec/compiler/pretty_spec.rb +0 -9
  105. data/spec/compiler/queue_spec.rb +0 -3
  106. data/spec/compiler/rewrite_spec.rb +0 -3
  107. data/spec/config_spec.rb +0 -58
  108. data/spec/filecache_spec.rb +0 -70
  109. data/spec/fixtures/snippets.sql +0 -158
  110. data/spec/grammar/tokens/lval_spec.rb +0 -50
  111. data/spec/parser_spec.rb +0 -8
  112. data/spec/profile_spec.rb +0 -5
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6bc3e3b06dfb2ce02fc63e702216f7144165c2a0
4
+ data.tar.gz: 15a2d1da931923920ffce34f726096c3f31e8492
5
+ SHA512:
6
+ metadata.gz: 8409f7c8adde74c01dfaeb3dcf0e1a6df10b5e8d7552701d38586f938d47e9727457c34a3b2a539f1ad54ceb4e5450909bddfc3f4b43485a2094fd9dc045f97c
7
+ data.tar.gz: b4d409e5ab4f45112f27444720fa56ce6e034e8c9244c466a2f249fcf0cb3032269287ca8eb48927c01245e7e1e62bf42a0b15a32f3df408ed3278a962eeb1dc
@@ -0,0 +1,163 @@
1
+ # Piggly
2
+
3
+ PostgreSQL PL/pgSQL stored procedure code coverage [![Build Status](https://secure.travis-ci.org/kputnam/piggly.png)](http://travis-ci.org/kputnam/piggly)
4
+
5
+ ![Screenshot](http://kputnam.github.com/piggly/images/example.png)
6
+
7
+ ## Purpose
8
+
9
+ PL/pgSQL doesn't have much in the way of developer tools, and writing automated tests for
10
+ stored procedures can be much easier when you know what you haven't tested. Code coverage
11
+ allows you to see which parts of your code haven't been executed.
12
+
13
+ Piggly is a tool (written in Ruby, but you can write your tests in any language) to track
14
+ code coverage of PostgreSQL PL/pgSQL stored procedures. It reports on code coverage to help
15
+ you identify untested parts of your code.
16
+
17
+ ## How Does It Work?
18
+
19
+ Piggly tracks the execution of PostgreSQL's PL/pgSQL stored procedures by recompiling
20
+ the stored procedure with instrumentation code. Basically, RAISE WARNING statements notify the
21
+ client of an execution event (e.g., a branch condition evaluating to true or false). It records
22
+ these events and generates prettified source code that is annotated with coverage details.
23
+
24
+ ## Features
25
+
26
+ * Readable and easily-navigable reports (see [example] [5])
27
+ * Language agnostic - write your tests in Ruby, Python, Java, SQL scripts etc
28
+ * Branch, block, and loop coverage analysis
29
+ * Instrumenting source-to-source compiler
30
+ * Low test execution overhead
31
+ * Reduced compilation times by use of disk caching
32
+ * Possible to aggregate coverage across multiple runs
33
+
34
+ ## Limitations
35
+
36
+ * Not all PL/pgSQL grammar is currently supported, but the grammar is easy to modify
37
+ * Cannot parse nested dollar-quoted strings, eg $A$ ... $B$ ... $B$ ... $A$
38
+ * SQL statements are not instrumented, so their branches (COALESCE, WHERE-clauses, etc) aren't tracked
39
+
40
+ ## Requirements
41
+
42
+ * [Treetop] [2]: `gem install treetop`
43
+ * The [ruby-pg driver] [3]: `gem install pg`
44
+ * The examples require ActiveRecord: `gem install activerecord`
45
+
46
+ ## How to Install
47
+
48
+ To install the latest from github:
49
+
50
+ $ git clone git://github.com/kputnam/piggly.git
51
+ $ cd piggly
52
+ $ bundle install
53
+ $ bundle exec rake spec
54
+
55
+ $ rake gem
56
+ $ gem install pkg/*.gem --no-rdoc --no-ri
57
+
58
+ To install the latest release:
59
+
60
+ $ gem install piggly
61
+
62
+ ## Usage
63
+
64
+ Your stored procedures must already be loaded in the database. Configure your database connection in
65
+ a file named `config/database.yml` relative to where you want to run piggly. You can also specify the
66
+ `-d PATH` to an existing configuration file. The contents of the file follow ActiveRecord conventions:
67
+
68
+ piggly:
69
+ adapter: postgresql
70
+ database: cookbook
71
+ username: kputnam
72
+ password: secret
73
+ host: localhost
74
+
75
+ Here we'll add some stored procedures to the database we described above:
76
+
77
+ $ cat example/proc/*.sql | psql -U kputnam -h localhost cookbook
78
+
79
+ Note the connection is expected to be named `piggly` but you may specify the `-k DATABASE` option to
80
+ use a different connection name (eg `-k development` in Rails). See also `example/config/database.yml`.
81
+
82
+ Now you are ready to recompile and install your stored procedures. This reads the configuration from
83
+ `./config/database.yml` relative to the current working directory.
84
+
85
+ $ piggly trace
86
+ compiling 5 procedures
87
+ Compiling scramble
88
+ Compiling scramble
89
+ Compiling numberedargs
90
+ Compiling snippets
91
+ Compiling iterate
92
+ tracing 5 procedures
93
+
94
+ This caches the original version (without instrumentation) in `piggly/cache` so you can restore them
95
+ later. Piggly will only recompile procedures that have changed in the database since it last
96
+ made a copy in `piggly/cache`.
97
+
98
+ *WARNING*: piggly fetches your code from the database and replaces it (in the database) with the
99
+ instrumented code. If you run `piggly trace` twice consecutively, the second time will cause an error
100
+ because you are trying to re-instrument code that has already been instrumented. You need to run
101
+ `piggly untrace` or restore your original stored procedures manually before you can trace them again.
102
+
103
+ Now you're ready to execute your tests. Make sure your connection is configured to log `RAISE WARNING`
104
+ messages to a file -- or you can log them to `STDERR` and redirect that to a file. For instance you
105
+ might run:
106
+
107
+ $ ant test 2> messages.txt
108
+ $ make test 2> messages.txt
109
+ etc.
110
+
111
+ To build the coverage report, have piggly read that file in by executing `piggly report < messages.txt`,
112
+ or `piggly report -f messages.txt`. You don't actually need the intermediate file, you can pipe your
113
+ test suite directly in like `ant test 2>&1 | piggly report`.
114
+
115
+ Once the report is built you can open it in `piggly/reports/index.html`.
116
+
117
+ ## Running the Examples
118
+
119
+ $ cd piggly
120
+ $ bundle install
121
+ $ cat example/README
122
+ ...
123
+
124
+ $ ./example/run-tests
125
+ compiling 5 procedures
126
+ Compiling scramble
127
+ Compiling scramble
128
+ Compiling numberedargs
129
+ Compiling snippets
130
+ Compiling iterate
131
+ tracing 5 procedures
132
+ Loaded suite /home/kputnam/wd/piggly/example/test/iterate_test
133
+ Started
134
+ ......
135
+ Finished in 0.199236 seconds.
136
+
137
+ 6 tests, 6 assertions, 0 failures, 0 errors, 0 skips
138
+
139
+ Test run options: --seed 25290
140
+ clearing previous coverage
141
+ storing coverage profile
142
+ creating index
143
+ creating reports
144
+ reporting coverage for scramble
145
+ reporting coverage for scramble
146
+ reporting coverage for numberedargs
147
+ reporting coverage for snippets
148
+ reporting coverage for iterate: +0.0% block, +0.0% branch, +0.0% loop
149
+ restoring 5 procedures
150
+ OK, view /home/kputnam/wd/piggly/example/piggly/reports/index.html
151
+
152
+ $ ls -alh example/reports/index.html
153
+ -rw-r--r-- 1 kputnam kputnam 1.4K 2010-04-28 11:21 example/reports/index.html
154
+
155
+ ## Bugs & Issues
156
+
157
+ Please report any issues or feature requests on the [github tracker] [4].
158
+
159
+ [1]: http://github.com/relevance/rcov/
160
+ [2]: http://github.com/nathansobo/treetop
161
+ [3]: http://bitbucket.org/ged/ruby-pg/
162
+ [4]: http://github.com/kputnam/piggly/issues
163
+ [5]: http://kputnam.github.com/piggly/reports/index.html
data/Rakefile CHANGED
@@ -1,19 +1,33 @@
1
- dir = File.dirname(__FILE__)
2
- require 'rubygems'
3
- require 'rake'
4
-
5
1
  begin
6
- require 'spec/rake/spectask'
7
- Spec::Rake::SpecTask.new do |t|
8
- t.pattern = 'spec/**/*_spec.rb'
9
- end
10
- task :default => :spec
11
- rescue Exception
2
+ require "rubygems"
3
+ require "bundler/setup"
4
+ rescue LoadError
5
+ warn "couldn't load bundler:"
6
+ warn " #{$!}"
12
7
  end
13
8
 
14
- require 'rake/gempackagetask'
15
- load './piggly.gemspec'
16
- Rake::GemPackageTask.new(Piggly.gemspec) do |pkg|
17
- pkg.need_tar = false
18
- pkg.need_zip = false
9
+ begin # rspec-2
10
+ require "rspec/core/rake_task"
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.verbose = false
13
+ t.pattern = "spec/**/*_spec.rb"
14
+ t.rspec_opts = "--color --format=p"
15
+ end
16
+ rescue LoadError => first
17
+ begin # rspec-1
18
+ require "spec/rake/spectask"
19
+ Spec::Rake::SpecTask.new do |t|
20
+ t.pattern = "spec/**/*_spec.rb"
21
+ t.spec_opts << "--color"
22
+ t.spec_opts << "--format=p"
23
+ end
24
+ rescue LoadError => second
25
+ task :spec do
26
+ warn "couldn't load rspec version 1 or 2:"
27
+ warn " #{first}"
28
+ warn " #{second}"
29
+ end
30
+ end
19
31
  end
32
+
33
+ task :default => :spec
data/bin/piggly CHANGED
@@ -1,248 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'rubygems'
4
- $:.push File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
5
- require 'piggly'
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), *%w(.. lib)))
3
+ require "piggly"
6
4
 
7
5
  # Number of children to fork for parallel tasks
8
- Piggly::Queue.children = 2
6
+ Piggly::Util::ProcessQueue.concurrent = 2
9
7
 
10
- STDOUT.sync = true
11
-
12
- module Piggly
13
- module Command
14
- class << self
15
-
16
- def main
17
- benchmark do
18
- sources, tests = parse_options
19
- load_tests(tests)
20
- connect_to_database
21
- compile_procs(sources)
22
- install_procs(sources)
23
- clear_coverage
24
- execute_tests
25
- store_coverage
26
- uninstall_procs(sources)
27
- create_index(sources)
28
- create_reports(sources)
29
- exit! 0 # avoid running tests again
30
- end
31
- end
32
-
33
- private
34
-
35
- def benchmark
36
- start = Time.now
37
- yield
38
- puts " > Completed in #{'%0.2f' % (Time.now - start)} seconds"
39
- end
40
-
41
- def parse_options
42
- proc_paths = []
43
-
44
- opts = OptionParser.new do |opts|
45
- opts.on("-I", "--include PATHS", "Prepend paths to $: (colon separated list)") do |paths|
46
- $:.concat paths.split(':')
47
- end
48
-
49
- opts.on("-o", "--output PATH", "Report output directory") do |dir|
50
- Piggly::Config.report_root = dir
51
- end
52
-
53
- opts.on("-c", "--cache-root PATH", "Compiler cache directory") do |dir|
54
- Piggly::Config.cache_root = dir
55
- end
56
-
57
- opts.on("-s", "--proc-files PATH", "Stored procedures file list (may be specified many times)") do |dir|
58
- proc_paths << dir
59
- end
60
-
61
- # opts.on("-T", "--trace-prefix PATH", "Trace prefix") do |str|
62
- # Piggly::Config.trace_prefix = str
63
- # end
64
-
65
- opts.on("-a", "--aggregate", "Aggregate data from the previous run") do
66
- Piggly::Config.aggregate = true
67
- end
68
-
69
- opts.on("--version", "Show version") do
70
- puts "piggly #{Piggly::VERSION::STRING} #{Piggly::VERSION::RELEASE_DATE}"
71
- exit
72
- end
73
-
74
- opts.on("-h", "--help", "Show this message") do
75
- puts opts
76
- exit 0
77
- end
78
- end
79
-
80
- if index = ARGV.index('--')
81
- extra = ARGV.slice!(index..-1).slice(1..-1)
82
- else
83
- extra = []
84
- end
85
-
86
- begin
87
- opts.parse! ARGV
88
- raise OptionParser::MissingArgument, "no tests specified" if ARGV.empty?
89
- rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument
90
- puts opts
91
- puts
92
- puts $!.message
93
- exit -1
94
- end
95
-
96
- proc_paths = proc_paths.map{|p| Dir[p] }.flatten.sort
97
- test_paths = ARGV.map{|p| Dir[p] }.flatten.sort
98
-
99
- ARGV.clear
100
-
101
- return proc_paths, test_paths
102
- end
103
-
104
- def load_tests(tests)
105
- puts "Loading #{tests.size} test files"
106
-
107
- benchmark { tests.each{|file| load file } }
108
-
109
- # # TODO: this doesn't seem right, but workaround RSpec executing each spec twice
110
- # if defined? Spec::Runner::ExampleGroupRunner
111
- # Spec::Runner::ExampleGroupRunner.send(:define_method, :load_files) do |*args|
112
- # # don't do anything, we already loaded the files
113
- # end
114
- # end
115
- end
116
-
117
- def connect_to_database
118
- ActiveRecord::Base.connection.active?
119
- rescue
120
- ActiveRecord::Base.establish_connection
121
- end
122
-
123
- def compile_procs(sources)
124
- stale = sources.select{|f| Piggly::TraceCompiler.stale?(f) }
125
-
126
- # build the parser if needed
127
- Piggly::Parser.parser
128
-
129
- puts "Compiling #{stale.size} files"
130
- benchmark do
131
- stale.each do |file|
132
- Piggly::Queue.child do
133
- begin
134
- Piggly::TraceCompiler.cache(file)
135
- # rescue Errno::ENOENT, Piggly::Parser::Failure
136
- # puts "! #{File.basename file}"
137
- rescue
138
- puts
139
- puts "#{$!.class}: #{$!.message}"
140
- puts $!.backtrace.join("\n")
141
- end
142
- end
143
- end
144
- Piggly::Queue.start
145
- end
146
- end
147
-
148
- def install_procs(sources)
149
- puts "Installing #{sources.size} proc files"
150
-
151
- benchmark do
152
- sources.each do |file|
153
- begin
154
- Piggly::Installer.trace_proc(file)
155
- rescue Errno::ENOENT, Piggly::Parser::Failure
156
- # puts "! #{File.basename file}"
157
- rescue
158
- puts
159
- puts "#{$!.class}: #{$!.message}"
160
- puts $!.backtrace.join("\n")
161
- end
162
- end
163
-
164
- Piggly::Installer.install_trace
165
- end
166
- end
167
-
168
- def clear_coverage
169
- unless Piggly::Config.aggregate
170
- puts "Clearing previous run's profile"
171
- benchmark { Piggly::Profile.clear }
172
- end
173
- end
174
-
175
- def execute_tests
176
- if defined? Test::Unit::AutoRunner
177
- Test::Unit::AutoRunner.run
178
- elsif defined? Spec::Runner
179
- Spec::Runner.run
180
- else
181
- raise "Neither RSpec nor Test::Unit were detected"
182
- end
183
- end
184
-
185
- def store_coverage
186
- puts "Storing coverage profile"
187
- benchmark { Piggly::Profile.store }
188
- end
189
-
190
- def uninstall_procs(sources)
191
- puts "Removing trace code"
192
- benchmark do
193
- sources.each do |file|
194
- begin
195
- Piggly::Installer.untrace_proc(file)
196
- rescue Errno::ENOENT, Piggly::Parser::Failure
197
- # puts "! #{File.basename file}"
198
- rescue
199
- puts
200
- puts "#{$!.class}: #{$!.message}"
201
- puts $!.backtrace.join("\n")
202
- end
203
- end
204
-
205
- Piggly::Installer.uninstall_trace
206
- end
207
- end
208
-
209
- def create_index(sources)
210
- puts "Creating index"
211
- benchmark do
212
- Piggly::Reporter.install('piggly.css', 'sortable.js')
213
- Piggly::HtmlReporter::Index.output(sources)
214
- end
215
- end
216
-
217
- def create_reports(sources)
218
- puts "Creating reports"
219
- summary = Hash.new{|h,k| h[k] = Hash.new[:count => 0, :percent => 0]}
220
-
221
- benchmark do
222
- sources.each do |file|
223
- Piggly::Queue.child do
224
- begin
225
- summary = Piggly::Profile.summary(file)
226
- pretty = Piggly::PrettyCompiler.compile(file, Piggly::Profile)
227
-
228
- Piggly::HtmlReporter.output(file, pretty, summary)
229
- rescue Errno::ENOENT, Piggly::Parser::Failure
230
- # puts "! #{File.basename file}"
231
- rescue
232
- puts "#{$!.class}: #{$!.message}"
233
- puts $!.backtrace.join("\n")
234
- end
235
- end
236
- end
237
-
238
- Piggly::Queue.start
239
- end
240
- end
241
-
242
- end
243
- end
244
- end
245
-
246
- if __FILE__ == $0
247
- Piggly::Command.main
248
- end
8
+ Piggly::Command::Base.main(ARGV)