sake 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. data/LICENSE +18 -0
  2. data/Manifest.txt +8 -0
  3. data/README +76 -0
  4. data/Rakefile +23 -0
  5. data/bin/sake +5 -0
  6. data/lib/help.rb +32 -0
  7. data/lib/sake.rb +529 -0
  8. data/lib/server.rb +42 -0
  9. metadata +61 -0
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2007 Chris Wanstrath
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ ./bin/sake
2
+ ./lib/sake.rb
3
+ ./lib/server.rb
4
+ ./lib/help.rb
5
+ ./Manifest.txt
6
+ ./Rakefile
7
+ ./README
8
+ ./LICENSE
data/README ADDED
@@ -0,0 +1,76 @@
1
+ = Sake. Best served warm.
2
+
3
+ Sick of copy & pasting your badass custom Rakefiles into every new Rails app
4
+ you start? Fed up with writing one-off admistrative scripts and leaving them
5
+ everything?
6
+
7
+ No longer. Sake is a tool which helps you maintain a set of system level Rake tasks.
8
+
9
+ Get started:
10
+
11
+ $ sudo gem install sake
12
+ $ sake -h
13
+
14
+ Show all Sake tasks (but no local Rake tasks), optionally only those matching a pattern.
15
+ $ sake -T
16
+ $ sake -T db
17
+
18
+ Show tasks in a Rakefile, optionally only those matching a pattern.
19
+ $ sake -T file.rake
20
+ $ sake -T file.rake db
21
+
22
+ Install tasks from a Rakefile, optionally specifying specific tasks.
23
+ $ sake -i Rakefile
24
+ $ sake -i Rakefile db:remigrate
25
+ $ sake -i Rakefile db:remigrate routes
26
+
27
+ Examine the source of a Rake task.
28
+ $ sake -e routes
29
+
30
+ Want to share just a few tasks, bundle them up?
31
+ $ sake -e routes remigrate > my_tasks.rake
32
+
33
+ You can also examine the source of a task not yet installed.
34
+ $ sake -e Rakefile db:remigrate
35
+
36
+ Uninstall an installed task.
37
+ $ sake -u db:remigrate
38
+
39
+ Can be passed one or more tasks.
40
+
41
+ Invoke a Sake task.
42
+ $ sake <taskname>
43
+
44
+ Some Sake tasks may depend on tasks which exist only locally.
45
+
46
+ For instance, you may have a db:version sake task which depends
47
+ on the 'environment' Rake task. The 'environment' Rake task is one
48
+ defined by Rails to load its environment. This db:version task will
49
+ work when your current directory is within a Rails app because
50
+ Sake knows how to find Rake tasks. This task will not work,
51
+ however, in any other directory (unless a task named 'environment'
52
+ indeed exists).
53
+
54
+ Sake can also serve its tasks over a network by launching a Mongrel handler.
55
+ Pass the -S switch to start Sake in server mode.
56
+
57
+ $ sake -S
58
+
59
+ You can, of course, specify a port.
60
+ $ sake -S -p 1111
61
+
62
+ You can also daemonize your server for long term serving fun.
63
+ $ sake -S -d
64
+
65
+ == Special Thanks
66
+
67
+ * Ryan Davis
68
+ * Eric Hodel
69
+ * Josh Susser
70
+ * Brian Donovan
71
+ * Zack Chandler
72
+
73
+ == Author
74
+
75
+ >> Chris Wanstrath
76
+ => chris@ozmm.org
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ require 'lib/sake' unless defined? Sake
5
+
6
+ begin
7
+ require 'echoe'
8
+
9
+ Echoe.new('sake', Sake::Version::String) do |p|
10
+ p.rubyforge_name = 'err'
11
+ p.summary = "Sake tastes great and helps maintain system-level Rake files."
12
+ p.description = "Sake tastes great and helps maintain system-level Rake files."
13
+ p.url = "http://errtheblog.com/"
14
+ p.author = 'Chris Wanstrath'
15
+ p.email = "chris@ozmm.org"
16
+ p.extra_deps << ['ruby2ruby', '>=1.1.6']
17
+ p.test_globs = 'test/*_test.rb'
18
+ end
19
+
20
+ rescue LoadError => boom
21
+ puts "You are missing a dependency required for meta-operations on this gem."
22
+ puts "#{boom.to_s.capitalize}."
23
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'sake'
4
+
5
+ Sake.new(ARGV).run
@@ -0,0 +1,32 @@
1
+ class Sake
2
+ module Help
3
+ extend self
4
+
5
+ def display
6
+ die <<-end_help
7
+ Usage: sake [options]
8
+
9
+ Any <file> can be either a local file or a remote URL (such as a web page).
10
+
11
+ -T Show installed Sake tasks.
12
+ -T pattern Show installed Sake tasks matching <pattern>.
13
+ -T file Show tasks in <file>.
14
+ -T file pattern Show tasks in <file>.
15
+
16
+ -i file Install all tasks from <file>.
17
+ -i file tasks Install tasks from <file>. Can be one or more tasks.
18
+
19
+ -u tasks Uninstalls one or more tasks.
20
+
21
+ -e file Show the source for all tasks from <file>.
22
+ -e file tasks Show the source for <task> as defined in <file>.
23
+
24
+ -S Start a Mongrel handler and serve your installed Sake tasks
25
+ over port 4567.
26
+ -p Set the port to serve Sake tasks on. Defaults to 4567. Only
27
+ works with -S.
28
+ -d Start and daemonize a Sake server. Only works with -S.
29
+ end_help
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,529 @@
1
+ ##
2
+ # Sake. Best served warm.
3
+ #
4
+ # >> Chris Wanstrath
5
+ # => chris@ozmm.org
6
+
7
+ require 'rubygems'
8
+ require 'rake'
9
+ require 'fileutils'
10
+ require 'open-uri'
11
+ begin
12
+ require 'ruby2ruby'
13
+ rescue LoadError
14
+ die "# Sake requires the ruby2ruby gem and Ruby 1.8.6."
15
+ end
16
+ require File.dirname(__FILE__) + '/help'
17
+
18
+ ##
19
+ # Show all Sake tasks (but no local Rake tasks), optionally only those matching a pattern.
20
+ # $ sake -T
21
+ # $ sake -T db
22
+ #
23
+ # Show tasks in a Rakefile, optionally only those matching a pattern.
24
+ # $ sake -T file.rake
25
+ # $ sake -T file.rake db
26
+ #
27
+ # Install tasks from a Rakefile, optionally specifying specific tasks.
28
+ # $ sake -i Rakefile
29
+ # $ sake -i Rakefile db:remigrate
30
+ # $ sake -i Rakefile db:remigrate routes
31
+ #
32
+ # Examine the source of a Rake task.
33
+ # $ sake -e routes
34
+ #
35
+ # You can also examine the source of a task not yet installed.
36
+ # $ sake -e Rakefile db:remigrate
37
+ #
38
+ # Uninstall an installed task.
39
+ # $ sake -u db:remigrate
40
+ #
41
+ # Can be passed one or more tasks.
42
+ #
43
+ # Invoke a Sake task.
44
+ # $ sake <taskname>
45
+ #
46
+ # Some Sake tasks may depend on tasks which exist only locally.
47
+ #
48
+ # For instance, you may have a db:version sake task which depends
49
+ # on the 'environment' Rake task. The 'environment' Rake task is one
50
+ # defined by Rails to load its environment. This db:version task will
51
+ # work when your current directory is within a Rails app because
52
+ # Sake knows how to find Rake tasks. This task will not work,
53
+ # however, in any other directory (unless a task named 'environment'
54
+ # indeed exists).
55
+ #
56
+ # Sake can also serve its tasks over a network by launching a Mongrel handler.
57
+ # Pass the -S switch to start Sake in server mode.
58
+ #
59
+ # $ sake -S
60
+ #
61
+ # You can, of course, specify a port.
62
+ # $ sake -S -p 1111
63
+ #
64
+ # You can also daemonize your server for long term serving fun.
65
+ # $ sake -S -d
66
+ #
67
+ class Sake
68
+ module Version
69
+ Major = '1'
70
+ Minor = '0'
71
+ Tweak = '0'
72
+ String = [ Major, Minor, Tweak ].join('.')
73
+ end
74
+
75
+ ##
76
+ # The `application' class, this is basically the controller
77
+ # which decides what to do then executes.
78
+ def initialize(args)
79
+ @args = args
80
+ Rake.application
81
+ Rake.application.options.silent = true
82
+ end
83
+
84
+ ##
85
+ # This method figures out what to do and does it.
86
+ # Basically a big switch. Note the seemingly random
87
+ # return statements: return if you don't want run_rake invoked.
88
+ # Some actions do want it invoked, however, so they don't return
89
+ # (like version, which prints a Sake version then trusts Rake to do
90
+ # likewise).
91
+ def run
92
+ ##
93
+ # Show Sake tasks in the store or in a file, optionally searching for a pattern.
94
+ # $ sake -T
95
+ # $ sake -T db
96
+ # $ sake -T file.rake
97
+ # $ sake -T file.rake db
98
+ if index = @args.index('-T')
99
+ begin
100
+ tasks = TasksFile.parse(@args[index + 1]).tasks
101
+ pattern = @args[index + 2]
102
+ rescue
103
+ tasks = Store.tasks.sort
104
+ pattern = @args[index + 1]
105
+ end
106
+
107
+ return show_tasks(tasks, pattern)
108
+
109
+ ##
110
+ # Install a Rakefile or a single Rake task
111
+ # $ sake -i Rakefile
112
+ # $ sake -i Rakefile db:migrate
113
+ elsif index = @args.index('-i')
114
+ return install(index)
115
+
116
+ ##
117
+ # Uninstall one or more Rake tasks from the Sake store.
118
+ elsif index = @args.index('-u')
119
+ return uninstall(index)
120
+
121
+ ##
122
+ # Examine a Rake task
123
+ # $ sake -e routes
124
+ # $ sake -e Rakefile db:remigrate
125
+ elsif index = @args.index('-e')
126
+ return examine(index)
127
+
128
+ ##
129
+ # Start a Mongrel handler which will serve local Rake tasks
130
+ # to anyone who wants them.
131
+ #
132
+ # $ sake -S
133
+ #
134
+ # Set a port
135
+ # $ sake -S -p 1111
136
+ #
137
+ # Daemonize
138
+ # $ sake -S -d
139
+ elsif @args.include? '-S'
140
+ return serve_tasks
141
+
142
+ ##
143
+ # Prints Sake and Rake versions.
144
+ elsif @args.include? '--version'
145
+ version
146
+
147
+ ##
148
+ # Prints out the help screen.
149
+ elsif @args.include? '-h' or @args.include? '--help'
150
+ return Help.display
151
+ end
152
+
153
+ ##
154
+ # Runs Rake proper, including our ~/.sake tasks.
155
+ run_rake
156
+ end
157
+
158
+ private
159
+
160
+ def show_tasks(tasks = [], pattern = nil)
161
+ Rake.application.show(tasks, pattern)
162
+ end
163
+
164
+ def install(index)
165
+ die "# I need a Rakefile." unless file = @args[index+1]
166
+
167
+ tasks = TasksFile.parse(file).tasks
168
+
169
+ # We may want to install a specific task
170
+ unless (target_tasks = @args[index + 2..-1]).empty?
171
+ tasks = tasks.select { |task| target_tasks.include? task.name }
172
+ end
173
+
174
+ # No duplicates.
175
+ tasks.each do |task|
176
+ if Store.has_task? task
177
+ puts "# Task `#{task}' already exists in #{Store.path}"
178
+ else
179
+ puts "# Installing task `#{task}'"
180
+ Store.add_task task
181
+ end
182
+ end
183
+
184
+ # Commit.
185
+ Store.save!
186
+ end
187
+
188
+ def uninstall(index)
189
+ die "# -u option needs one or more installed tasks" if (tasks = @args[index+1..-1]).empty?
190
+
191
+ tasks.each do |name|
192
+ if task = Store.tasks[name]
193
+ puts "# Uninstalling `#{task}'. Here it is, for reference:", task.to_ruby, ''
194
+ Store.remove_task(task)
195
+ else
196
+ puts "# You don't have task `#{name}' installed.", ''
197
+ end
198
+ end
199
+
200
+ Store.save!
201
+ end
202
+
203
+ ##
204
+ # There is a lot of guesswork inside this method. Sorry.
205
+ def examine(index)
206
+ # Can be -e file task or -e task, which defaults to Store.path
207
+ if @args[index + 2]
208
+ file = @args[index + 1]
209
+ task = @args[index + 2]
210
+ else
211
+ task = @args[index + 1]
212
+ end
213
+
214
+ # They didn't pass any args in, so just show the ~/.sake file
215
+ unless task
216
+ die Store.tasks.to_ruby
217
+ end
218
+
219
+ # Try to find the task we think they asked for.
220
+ tasks = file ? TasksFile.parse(file).tasks : Store.tasks
221
+
222
+ if tasks[task]
223
+ die tasks[task].to_ruby
224
+ end
225
+
226
+ # Didn't find the task. See if it's a file and, if so, spit
227
+ # it out.
228
+ unless (tasks = TasksFile.parse(task).tasks).empty?
229
+ die tasks.to_ruby
230
+ end
231
+
232
+ # Failure. On all counts.
233
+ error = "# Can't find task (or file) `#{task}'"
234
+ error << " in #{file}" if file
235
+ die error
236
+ end
237
+
238
+ def serve_tasks
239
+ require File.dirname(__FILE__) + '/server'
240
+ Server.start(@args)
241
+ end
242
+
243
+ def version
244
+ puts "sake, version #{Version::String}"
245
+ end
246
+
247
+ def run_rake
248
+ import Sake::Store.path
249
+ Rake.application.run
250
+ end
251
+
252
+ ##
253
+ # Lets us do:
254
+ # tasks = TasksFile.parse('Rakefile').tasks
255
+ # task = tasks['db:remigrate']
256
+ class TasksArray < Array
257
+ def [](name_or_index)
258
+ if name_or_index.is_a? String
259
+ detect { |task| task.name == name_or_index }
260
+ else
261
+ super
262
+ end
263
+ end
264
+
265
+ ##
266
+ # The source of all these tasks.
267
+ def to_ruby
268
+ map { |task| task.to_ruby }.join("\n")
269
+ end
270
+ end
271
+
272
+ ##
273
+ # This class represents a Rake task file, in the traditional sense.
274
+ # It takes on parameter: the path to a Rakefile. When instantiated,
275
+ # it will read the file and parse out the rake tasks, storing them in
276
+ # a 'tasks' array. This array can be accessed directly:
277
+ #
278
+ # file = Sake::TasksFile.parse('Rakefile')
279
+ # puts file.tasks.inspect
280
+ #
281
+ # The parse method also works with remote files, as its implementation
282
+ # uses open-uri's open().
283
+ #
284
+ # Sake::TasksFile.parse('Rakefile')
285
+ # Sake::TasksFile.parse('http://errtheblog.com/code/errake')
286
+ class TasksFile
287
+ attr_reader :tasks
288
+
289
+ ##
290
+ # The idea here is that we may be sucking in Rakefiles from an untrusted
291
+ # source. While we're happy to let the user audit the code of any Rake
292
+ # task before running it, we'd rather not be responsible for executing a
293
+ # `rm -rf` in the Rakefile itself. To ensure this, we need to set a
294
+ # safelevel before parsing the Rakefile in question.
295
+ def self.parse(file)
296
+ body = open(file).read
297
+
298
+ instance = new
299
+ Thread.new { instance.instance_eval "$SAFE = 3\n#{body}" }.join
300
+ instance
301
+ end
302
+
303
+ def initialize
304
+ @namespace = []
305
+ @tasks = TasksArray.new
306
+ @comment = nil
307
+ end
308
+
309
+ ##
310
+ # We fake out an approximation of the Rake DSL in order to build
311
+ # our tasks array.
312
+ private
313
+
314
+ ##
315
+ # Set a namespace for the duration of the block. Namespaces can be
316
+ # nested.
317
+ def namespace(name)
318
+ @namespace << name
319
+ yield
320
+ @namespace.delete name
321
+ end
322
+
323
+ ##
324
+ # Describe the following task.
325
+ def desc(comment)
326
+ @comment = comment
327
+ end
328
+
329
+ ##
330
+ # Define a task and any dependencies it may have.
331
+ def task(name, &block)
332
+ # If we're passed a hash, we know it has one key (the name of
333
+ # the task) pointing to a single or multiple dependencies.
334
+ if name.is_a? Hash
335
+ deps = name.values.first
336
+ name = name.keys.first
337
+ end
338
+
339
+ # Our namespace is really just a convenience method. Essentially,
340
+ # a namespace is just part of the task name.
341
+ name = [ @namespace, name ].flatten * ':'
342
+
343
+ # Sake's version of a rake task
344
+ task = Task.new(name, deps, @comment, &block)
345
+
346
+ @tasks << task
347
+
348
+ # We sucked up the last 'desc' declaration if it existed, so now clear
349
+ # it -- we don't want tasks without a description given one.
350
+ @comment = nil
351
+ end
352
+
353
+ public
354
+
355
+ ##
356
+ # Call to_ruby on all our tasks and return a concat'd string of them.
357
+ def to_ruby
358
+ @tasks.to_ruby
359
+ end
360
+
361
+ ##
362
+ # Add tasks to this TasksFile. Can accept another TasksFile object or
363
+ # an array of Task objects.
364
+ def add_tasks(tasks)
365
+ Array(tasks.is_a?(TasksFile) ? tasks.tasks : tasks).each do |task|
366
+ add_task task
367
+ end
368
+ end
369
+
370
+ ##
371
+ # Single task version of add_tasks
372
+ def add_task(task)
373
+ @tasks << task
374
+ end
375
+
376
+ ##
377
+ # Does this task exist?
378
+ def has_task?(task)
379
+ @tasks.map { |t| t.to_s }.include? task.to_s
380
+ end
381
+
382
+ ##
383
+ # Hunt for and remove a particular task.
384
+ def remove_task(target_task)
385
+ @tasks.reject! { |task| task.name == target_task.name }
386
+ end
387
+ end
388
+
389
+ ##
390
+ # This is Sake's version of a Rake task. Please handle with care.
391
+ class Task
392
+ attr_reader :name, :comment
393
+
394
+ def initialize(name, deps = nil, comment = nil, &block)
395
+ @name = name
396
+ @comment = comment
397
+ @deps = Array(deps)
398
+ @body = block
399
+ end
400
+
401
+ ##
402
+ # Turn ourselves back into Rake task plaintext.
403
+ def to_ruby
404
+ out = ''
405
+ out << "desc '#{@comment}'\n" if @comment
406
+ out << "task '#{@name}'"
407
+
408
+ if @deps.any?
409
+ deps = @deps.map { |dep| "'#{dep}'" }.join(', ')
410
+ out << " => [ #{deps} ]"
411
+ end
412
+
413
+ out << " do\n"
414
+
415
+ # get rid of the proc { / } lines
416
+ out << @body.to_ruby.split("\n")[1...-1].join("\n")
417
+
418
+ out << "\nend\n"
419
+ end
420
+
421
+ ##
422
+ # String-ish duck typing
423
+ def <=>(other)
424
+ to_s <=> other.to_s
425
+ end
426
+
427
+ def to_s; @name end
428
+ def inspect; @name.inspect end
429
+ end
430
+
431
+ ##
432
+ # The store is, as of writing, a single Rakefile: ~/.sake
433
+ # When we add new tasks, we just re-build this file. Over
434
+ # and over.
435
+ module Store
436
+ extend self
437
+
438
+ ##
439
+ # Everything we can't catch gets sent to our tasks_file.
440
+ # Common examples are #tasks or #add_task.
441
+ def method_missing(*args, &block)
442
+ tasks_file.send(*args, &block)
443
+ end
444
+
445
+ def tasks_file
446
+ FileUtils.touch(path) unless path.is_file?
447
+ @tasks_file ||= TasksFile.parse(path)
448
+ end
449
+
450
+ def path
451
+ File.join(File.expand_path('~'), '.sake')
452
+ end
453
+
454
+ def save!
455
+ File.open(path, 'w') do |file|
456
+ file.puts tasks_file.to_ruby
457
+ end
458
+ end
459
+ end
460
+ end
461
+
462
+ module Rake # :nodoc: all
463
+ class Application
464
+ ##
465
+ # Show the tasks as 'sake' tasks.
466
+ def printf(*args)
467
+ args[0].sub!('rake', 'sake') if args[0].is_a? String
468
+ super
469
+ end
470
+
471
+ ##
472
+ # Show tasks that don't have comments'
473
+ def display_tasks_and_comments(tasks = nil, pattern = nil)
474
+ tasks ||= self.tasks
475
+
476
+ if pattern ||= options.show_task_pattern
477
+ tasks = tasks.select { |t| t.name[pattern] || t.comment.to_s[pattern] }
478
+ end
479
+
480
+ width = tasks.collect { |t| t.name.length }.max
481
+
482
+ tasks.each do |t|
483
+ comment = " # #{t.comment}" if t.comment
484
+ printf "sake %-#{width}s#{comment}\n", t.name
485
+ end
486
+ end
487
+ alias_method :show, :display_tasks_and_comments
488
+
489
+ ##
490
+ # Run Sake even if no Rakefile exists in the current directory.
491
+ alias_method :sake_original_have_rakefile, :have_rakefile
492
+ def have_rakefile(*args)
493
+ @rakefile ||= ''
494
+ sake_original_have_rakefile(*args) || true
495
+ end
496
+ end
497
+
498
+ class Task
499
+ ##
500
+ # We want only run a Sake task -- not any other matching
501
+ # or duplicate tasks.
502
+ def enhance(deps=nil, &block)
503
+ @prerequisites |= deps if deps
504
+ @actions = [block] if block_given?
505
+ self
506
+ end
507
+ end
508
+ end
509
+
510
+ ##
511
+ # Hacks which give us "Rakefile".is_file?
512
+ class String # :nodoc:
513
+ def is_file?
514
+ File.exists? self
515
+ end
516
+ end
517
+
518
+ class Nil # :nodoc:
519
+ def is_file?
520
+ false
521
+ end
522
+ end
523
+
524
+ def die(*message) # :nodoc:
525
+ puts message
526
+ exit
527
+ end
528
+
529
+ Sake.new(ARGV).run if $0 == __FILE__
@@ -0,0 +1,42 @@
1
+ require 'sake' unless defined? Sake
2
+ require 'mongrel'
3
+
4
+ class Sake
5
+ module Server
6
+ extend self
7
+
8
+ def start(args)
9
+ if index = args.index('-p')
10
+ port = args[index+1].to_i
11
+ else
12
+ port = 4567
13
+ end
14
+
15
+ daemoned = args.include? '-d'
16
+
17
+ config = Mongrel::Configurator.new :host => "127.0.0.1" do
18
+ daemonize(:cwd => '.', :log_file => 'sake.log') if daemoned
19
+ listener(:port => port) { uri "/", :handler => Handler.new }
20
+ run
21
+ end
22
+
23
+ puts "# Serving warm sake tasks on port #{port}..." unless daemoned
24
+ config.join
25
+ end
26
+
27
+ class Handler < Mongrel::HttpHandler
28
+ def process(request, response)
29
+ uri = request.params['PATH_INFO'].sub(/^\//, '')
30
+ status = uri.empty? ? 200 : 404
31
+ body = status == 200 ? Store.to_ruby : 'Not Found'
32
+
33
+ response.start(status) do |headers, output|
34
+ headers['Content-Type'] = 'text/plain'
35
+ output.write body
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ Sake::Server.start(ARGV) if $0 == __FILE__
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: sake
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-06-23 00:00:00 -07:00
8
+ summary: Sake tastes great and helps maintain system-level Rake files.
9
+ require_paths:
10
+ - lib
11
+ email: chris@ozmm.org
12
+ homepage: http://errtheblog.com/
13
+ rubyforge_project: err
14
+ description: Sake tastes great and helps maintain system-level Rake files.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Chris Wanstrath
31
+ files:
32
+ - ./bin/sake
33
+ - ./lib/sake.rb
34
+ - ./lib/server.rb
35
+ - ./lib/help.rb
36
+ - ./Manifest.txt
37
+ - ./Rakefile
38
+ - ./README
39
+ - ./LICENSE
40
+ test_files: []
41
+
42
+ rdoc_options: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ executables:
47
+ - sake
48
+ extensions: []
49
+
50
+ requirements: []
51
+
52
+ dependencies:
53
+ - !ruby/object:Gem::Dependency
54
+ name: ruby2ruby
55
+ version_requirement:
56
+ version_requirements: !ruby/object:Gem::Version::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.1.6
61
+ version: