sinatra-bundles 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.md +20 -0
  5. data/Rakefile +47 -0
  6. data/VERSION +1 -0
  7. data/lib/sinatra-bundles.rb +0 -0
  8. data/lib/sinatra/bundles.rb +111 -0
  9. data/spec/app.rb +11 -0
  10. data/spec/production_app.rb +12 -0
  11. data/spec/public/javascripts/test1.js +5 -0
  12. data/spec/public/javascripts/test2.js +5 -0
  13. data/spec/public/stylesheets/test1.css +3 -0
  14. data/spec/public/stylesheets/test2.css +3 -0
  15. data/spec/sinatra-bundles_spec.rb +154 -0
  16. data/spec/spec.opts +2 -0
  17. data/spec/spec_helper.rb +17 -0
  18. data/vendor/cache/sinatra-0.10.1.gem +0 -0
  19. data/vendor/gems/sinatra-0.10.1/AUTHORS +43 -0
  20. data/vendor/gems/sinatra-0.10.1/CHANGES +467 -0
  21. data/vendor/gems/sinatra-0.10.1/LICENSE +22 -0
  22. data/vendor/gems/sinatra-0.10.1/README.jp.rdoc +552 -0
  23. data/vendor/gems/sinatra-0.10.1/README.rdoc +622 -0
  24. data/vendor/gems/sinatra-0.10.1/Rakefile +129 -0
  25. data/vendor/gems/sinatra-0.10.1/lib/sinatra.rb +7 -0
  26. data/vendor/gems/sinatra-0.10.1/lib/sinatra/base.rb +1143 -0
  27. data/vendor/gems/sinatra-0.10.1/lib/sinatra/images/404.png +0 -0
  28. data/vendor/gems/sinatra-0.10.1/lib/sinatra/images/500.png +0 -0
  29. data/vendor/gems/sinatra-0.10.1/lib/sinatra/main.rb +28 -0
  30. data/vendor/gems/sinatra-0.10.1/lib/sinatra/showexceptions.rb +303 -0
  31. data/vendor/gems/sinatra-0.10.1/lib/sinatra/tilt.rb +509 -0
  32. data/vendor/gems/sinatra-0.10.1/sinatra.gemspec +86 -0
  33. data/vendor/gems/sinatra-0.10.1/test/base_test.rb +160 -0
  34. data/vendor/gems/sinatra-0.10.1/test/builder_test.rb +65 -0
  35. data/vendor/gems/sinatra-0.10.1/test/contest.rb +64 -0
  36. data/vendor/gems/sinatra-0.10.1/test/erb_test.rb +81 -0
  37. data/vendor/gems/sinatra-0.10.1/test/erubis_test.rb +82 -0
  38. data/vendor/gems/sinatra-0.10.1/test/extensions_test.rb +100 -0
  39. data/vendor/gems/sinatra-0.10.1/test/filter_test.rb +195 -0
  40. data/vendor/gems/sinatra-0.10.1/test/haml_test.rb +90 -0
  41. data/vendor/gems/sinatra-0.10.1/test/helper.rb +76 -0
  42. data/vendor/gems/sinatra-0.10.1/test/helpers_test.rb +573 -0
  43. data/vendor/gems/sinatra-0.10.1/test/mapped_error_test.rb +186 -0
  44. data/vendor/gems/sinatra-0.10.1/test/middleware_test.rb +68 -0
  45. data/vendor/gems/sinatra-0.10.1/test/request_test.rb +33 -0
  46. data/vendor/gems/sinatra-0.10.1/test/response_test.rb +42 -0
  47. data/vendor/gems/sinatra-0.10.1/test/result_test.rb +98 -0
  48. data/vendor/gems/sinatra-0.10.1/test/route_added_hook_test.rb +59 -0
  49. data/vendor/gems/sinatra-0.10.1/test/routing_test.rb +878 -0
  50. data/vendor/gems/sinatra-0.10.1/test/sass_test.rb +79 -0
  51. data/vendor/gems/sinatra-0.10.1/test/server_test.rb +47 -0
  52. data/vendor/gems/sinatra-0.10.1/test/sinatra_test.rb +13 -0
  53. data/vendor/gems/sinatra-0.10.1/test/static_test.rb +87 -0
  54. data/vendor/gems/sinatra-0.10.1/test/templates_test.rb +155 -0
  55. data/vendor/gems/sinatra-0.10.1/test/views/error.builder +3 -0
  56. data/vendor/gems/sinatra-0.10.1/test/views/error.erb +3 -0
  57. data/vendor/gems/sinatra-0.10.1/test/views/error.erubis +3 -0
  58. data/vendor/gems/sinatra-0.10.1/test/views/error.haml +3 -0
  59. data/vendor/gems/sinatra-0.10.1/test/views/error.sass +2 -0
  60. data/vendor/gems/sinatra-0.10.1/test/views/foo/hello.test +1 -0
  61. data/vendor/gems/sinatra-0.10.1/test/views/hello.builder +1 -0
  62. data/vendor/gems/sinatra-0.10.1/test/views/hello.erb +1 -0
  63. data/vendor/gems/sinatra-0.10.1/test/views/hello.erubis +1 -0
  64. data/vendor/gems/sinatra-0.10.1/test/views/hello.haml +1 -0
  65. data/vendor/gems/sinatra-0.10.1/test/views/hello.sass +2 -0
  66. data/vendor/gems/sinatra-0.10.1/test/views/hello.test +1 -0
  67. data/vendor/gems/sinatra-0.10.1/test/views/layout2.builder +3 -0
  68. data/vendor/gems/sinatra-0.10.1/test/views/layout2.erb +2 -0
  69. data/vendor/gems/sinatra-0.10.1/test/views/layout2.erubis +2 -0
  70. data/vendor/gems/sinatra-0.10.1/test/views/layout2.haml +2 -0
  71. data/vendor/gems/sinatra-0.10.1/test/views/layout2.test +1 -0
  72. data/vendor/specifications/sinatra-0.10.1.gemspec +40 -0
  73. metadata +169 -0
@@ -0,0 +1,622 @@
1
+ = Sinatra
2
+
3
+ Sinatra is a DSL for quickly creating web applications in Ruby with minimal
4
+ effort:
5
+
6
+ # myapp.rb
7
+ require 'rubygems'
8
+ require 'sinatra'
9
+ get '/' do
10
+ 'Hello world!'
11
+ end
12
+
13
+ Install the gem and run with:
14
+
15
+ sudo gem install sinatra
16
+ ruby myapp.rb
17
+
18
+ View at: http://localhost:4567
19
+
20
+ == Routes
21
+
22
+ In Sinatra, a route is an HTTP method paired with an URL matching pattern.
23
+ Each route is associated with a block:
24
+
25
+ get '/' do
26
+ .. show something ..
27
+ end
28
+
29
+ post '/' do
30
+ .. create something ..
31
+ end
32
+
33
+ put '/' do
34
+ .. update something ..
35
+ end
36
+
37
+ delete '/' do
38
+ .. annihilate something ..
39
+ end
40
+
41
+ Routes are matched in the order they are defined. The first route that
42
+ matches the request is invoked.
43
+
44
+ Route patterns may include named parameters, accessible via the
45
+ <tt>params</tt> hash:
46
+
47
+ get '/hello/:name' do
48
+ # matches "GET /hello/foo" and "GET /hello/bar"
49
+ # params[:name] is 'foo' or 'bar'
50
+ "Hello #{params[:name]}!"
51
+ end
52
+
53
+ You can also access named parameters via block parameters:
54
+
55
+ get '/hello/:name' do |n|
56
+ "Hello #{n}!"
57
+ end
58
+
59
+ Route patterns may also include splat (or wildcard) parameters, accessible
60
+ via the <tt>params[:splat]</tt> array.
61
+
62
+ get '/say/*/to/*' do
63
+ # matches /say/hello/to/world
64
+ params[:splat] # => ["hello", "world"]
65
+ end
66
+
67
+ get '/download/*.*' do
68
+ # matches /download/path/to/file.xml
69
+ params[:splat] # => ["path/to/file", "xml"]
70
+ end
71
+
72
+ Route matching with Regular Expressions:
73
+
74
+ get %r{/hello/([\w]+)} do
75
+ "Hello, #{params[:captures].first}!"
76
+ end
77
+
78
+ Or with a block parameter:
79
+
80
+ get %r{/hello/([\w]+)} do |c|
81
+ "Hello, #{c}!"
82
+ end
83
+
84
+ Routes may include a variety of matching conditions, such as the user agent:
85
+
86
+ get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
87
+ "You're using Songbird version #{params[:agent][0]}"
88
+ end
89
+
90
+ get '/foo' do
91
+ # Matches non-songbird browsers
92
+ end
93
+
94
+ == Static Files
95
+
96
+ Static files are served from the <tt>./public</tt> directory. You can specify
97
+ a different location by setting the <tt>:public</tt> option:
98
+
99
+ set :public, File.dirname(__FILE__) + '/static'
100
+
101
+ Note that the public directory name is not included in the URL. A file
102
+ <tt>./public/css/style.css</tt> is made available as
103
+ <tt>http://example.com/css/style.css</tt>.
104
+
105
+ == Views / Templates
106
+
107
+ Templates are assumed to be located directly under the <tt>./views</tt>
108
+ directory. To use a different views directory:
109
+
110
+ set :views, File.dirname(__FILE__) + '/templates'
111
+
112
+ One important thing to remember is that you always have to reference
113
+ templates with symbols, even if they're in a subdirectory (in this
114
+ case use <tt>:'subdir/template'</tt>). Rendering methods will render
115
+ any strings passed to them directly.
116
+
117
+ === Haml Templates
118
+
119
+ The haml gem/library is required to render HAML templates:
120
+
121
+ ## You'll need to require haml in your app
122
+ require 'haml'
123
+
124
+ get '/' do
125
+ haml :index
126
+ end
127
+
128
+ Renders <tt>./views/index.haml</tt>.
129
+
130
+ {Haml's options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html]
131
+ can be set globally through Sinatra's configurations,
132
+ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
133
+ and overridden on an individual basis.
134
+
135
+ set :haml, {:format => :html5 } # default Haml format is :xhtml
136
+
137
+ get '/' do
138
+ haml :index, :haml_options => {:format => :html4 } # overridden
139
+ end
140
+
141
+
142
+ === Erb Templates
143
+
144
+ ## You'll need to require erb in your app
145
+ require 'erb'
146
+
147
+ get '/' do
148
+ erb :index
149
+ end
150
+
151
+ Renders <tt>./views/index.erb</tt>
152
+
153
+ === Erubis
154
+
155
+ The erubis gem/library is required to render builder templates:
156
+
157
+ ## You'll need to require erubis in your app
158
+ require 'erubis'
159
+
160
+ get '/' do
161
+ erubis :index
162
+ end
163
+
164
+ Renders <tt>./views/index.erubis</tt>
165
+
166
+ === Builder Templates
167
+
168
+ The builder gem/library is required to render builder templates:
169
+
170
+ ## You'll need to require builder in your app
171
+ require 'builder'
172
+
173
+ get '/' do
174
+ content_type 'application/xml', :charset => 'utf-8'
175
+ builder :index
176
+ end
177
+
178
+ Renders <tt>./views/index.builder</tt>.
179
+
180
+ === Sass Templates
181
+
182
+ The sass gem/library is required to render Sass templates:
183
+
184
+ ## You'll need to require haml or sass in your app
185
+ require 'sass'
186
+
187
+ get '/stylesheet.css' do
188
+ content_type 'text/css', :charset => 'utf-8'
189
+ sass :stylesheet
190
+ end
191
+
192
+ Renders <tt>./views/stylesheet.sass</tt>.
193
+
194
+ {Sass' options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html]
195
+ can be set globally through Sinatra's configurations,
196
+ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
197
+ and overridden on an individual basis.
198
+
199
+ set :sass, {:style => :compact } # default Sass style is :nested
200
+
201
+ get '/stylesheet.css' do
202
+ content_type 'text/css', :charset => 'utf-8'
203
+ sass :stylesheet, :style => :expanded # overridden
204
+ end
205
+
206
+ === Inline Templates
207
+
208
+ get '/' do
209
+ haml '%div.title Hello World'
210
+ end
211
+
212
+ Renders the inlined template string.
213
+
214
+ === Accessing Variables in Templates
215
+
216
+ Templates are evaluated within the same context as route handlers. Instance
217
+ variables set in route handlers are direcly accessible by templates:
218
+
219
+ get '/:id' do
220
+ @foo = Foo.find(params[:id])
221
+ haml '%h1= @foo.name'
222
+ end
223
+
224
+ Or, specify an explicit Hash of local variables:
225
+
226
+ get '/:id' do
227
+ foo = Foo.find(params[:id])
228
+ haml '%h1= foo.name', :locals => { :foo => foo }
229
+ end
230
+
231
+ This is typically used when rendering templates as partials from within
232
+ other templates.
233
+
234
+ === Inline Templates
235
+
236
+ Templates may be defined at the end of the source file:
237
+
238
+ require 'rubygems'
239
+ require 'sinatra'
240
+
241
+ get '/' do
242
+ haml :index
243
+ end
244
+
245
+ __END__
246
+
247
+ @@ layout
248
+ %html
249
+ = yield
250
+
251
+ @@ index
252
+ %div.title Hello world!!!!!
253
+
254
+ NOTE: Inline templates defined in the source file that requires sinatra
255
+ are automatically loaded. Call `enable :inline_templates` explicitly if you
256
+ have inline templates in other source files.
257
+
258
+ === Named Templates
259
+
260
+ Templates may also be defined using the top-level <tt>template</tt> method:
261
+
262
+ template :layout do
263
+ "%html\n =yield\n"
264
+ end
265
+
266
+ template :index do
267
+ '%div.title Hello World!'
268
+ end
269
+
270
+ get '/' do
271
+ haml :index
272
+ end
273
+
274
+ If a template named "layout" exists, it will be used each time a template
275
+ is rendered. You can disable layouts by passing <tt>:layout => false</tt>.
276
+
277
+ get '/' do
278
+ haml :index, :layout => !request.xhr?
279
+ end
280
+
281
+ == Helpers
282
+
283
+ Use the top-level <tt>helpers</tt> method to define helper methods for use in
284
+ route handlers and templates:
285
+
286
+ helpers do
287
+ def bar(name)
288
+ "#{name}bar"
289
+ end
290
+ end
291
+
292
+ get '/:name' do
293
+ bar(params[:name])
294
+ end
295
+
296
+ == Filters
297
+
298
+ Before filters are evaluated before each request within the context of the
299
+ request and can modify the request and response. Instance variables set in
300
+ filters are accessible by routes and templates:
301
+
302
+ before do
303
+ @note = 'Hi!'
304
+ request.path_info = '/foo/bar/baz'
305
+ end
306
+
307
+ get '/foo/*' do
308
+ @note #=> 'Hi!'
309
+ params[:splat] #=> 'bar/baz'
310
+ end
311
+
312
+ After filter are evaluated after each request within the context of the
313
+ request and can also modify the request and response. Instance variables
314
+ set in before filters and routes are accessible by after filters:
315
+
316
+ after do
317
+ puts response.status
318
+ end
319
+
320
+ == Halting
321
+
322
+ To immediately stop a request within a filter or route use:
323
+
324
+ halt
325
+
326
+ You can also specify the status when halting ...
327
+
328
+ halt 410
329
+
330
+ Or the body ...
331
+
332
+ halt 'this will be the body'
333
+
334
+ Or both ...
335
+
336
+ halt 401, 'go away!'
337
+
338
+ With headers ...
339
+
340
+ halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
341
+
342
+ == Passing
343
+
344
+ A route can punt processing to the next matching route using <tt>pass</tt>:
345
+
346
+ get '/guess/:who' do
347
+ pass unless params[:who] == 'Frank'
348
+ 'You got me!'
349
+ end
350
+
351
+ get '/guess/*' do
352
+ 'You missed!'
353
+ end
354
+
355
+ The route block is immediately exited and control continues with the next
356
+ matching route. If no matching route is found, a 404 is returned.
357
+
358
+ == Configuration
359
+
360
+ Run once, at startup, in any environment:
361
+
362
+ configure do
363
+ ...
364
+ end
365
+
366
+ Run only when the environment (RACK_ENV environment variable) is set to
367
+ <tt>:production</tt>:
368
+
369
+ configure :production do
370
+ ...
371
+ end
372
+
373
+ Run when the environment is set to either <tt>:production</tt> or
374
+ <tt>:test</tt>:
375
+
376
+ configure :production, :test do
377
+ ...
378
+ end
379
+
380
+ == Error handling
381
+
382
+ Error handlers run within the same context as routes and before filters, which
383
+ means you get all the goodies it has to offer, like <tt>haml</tt>, <tt>erb</tt>,
384
+ <tt>halt</tt>, etc.
385
+
386
+ === Not Found
387
+
388
+ When a <tt>Sinatra::NotFound</tt> exception is raised, or the response's status
389
+ code is 404, the <tt>not_found</tt> handler is invoked:
390
+
391
+ not_found do
392
+ 'This is nowhere to be found'
393
+ end
394
+
395
+ === Error
396
+
397
+ The +error+ handler is invoked any time an exception is raised from a route
398
+ block or a filter. The exception object can be obtained from the
399
+ <tt>sinatra.error</tt> Rack variable:
400
+
401
+ error do
402
+ 'Sorry there was a nasty error - ' + env['sinatra.error'].name
403
+ end
404
+
405
+ Custom errors:
406
+
407
+ error MyCustomError do
408
+ 'So what happened was...' + request.env['sinatra.error'].message
409
+ end
410
+
411
+ Then, if this happens:
412
+
413
+ get '/' do
414
+ raise MyCustomError, 'something bad'
415
+ end
416
+
417
+ You get this:
418
+
419
+ So what happened was... something bad
420
+
421
+ Alternatively, you can install error handler for a status code:
422
+
423
+ error 403 do
424
+ 'Access forbidden'
425
+ end
426
+
427
+ get '/secret' do
428
+ 403
429
+ end
430
+
431
+ Or a range:
432
+
433
+ error 400..510 do
434
+ 'Boom'
435
+ end
436
+
437
+ Sinatra installs special <tt>not_found</tt> and <tt>error</tt> handlers when
438
+ running under the development environment.
439
+
440
+ == Mime types
441
+
442
+ When using <tt>send_file</tt> or static files you may have mime types Sinatra
443
+ doesn't understand. Use +mime_type+ to register them by file extension:
444
+
445
+ mime_type :foo, 'text/foo'
446
+
447
+ You can also use it with the +content_type+ helper:
448
+
449
+ content_type :foo
450
+
451
+ == Rack Middleware
452
+
453
+ Sinatra rides on Rack[http://rack.rubyforge.org/], a minimal standard
454
+ interface for Ruby web frameworks. One of Rack's most interesting capabilities
455
+ for application developers is support for "middleware" -- components that sit
456
+ between the server and your application monitoring and/or manipulating the
457
+ HTTP request/response to provide various types of common functionality.
458
+
459
+ Sinatra makes building Rack middleware pipelines a cinch via a top-level
460
+ +use+ method:
461
+
462
+ require 'sinatra'
463
+ require 'my_custom_middleware'
464
+
465
+ use Rack::Lint
466
+ use MyCustomMiddleware
467
+
468
+ get '/hello' do
469
+ 'Hello World'
470
+ end
471
+
472
+ The semantics of +use+ are identical to those defined for the
473
+ Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL
474
+ (most frequently used from rackup files). For example, the +use+ method
475
+ accepts multiple/variable args as well as blocks:
476
+
477
+ use Rack::Auth::Basic do |username, password|
478
+ username == 'admin' && password == 'secret'
479
+ end
480
+
481
+ Rack is distributed with a variety of standard middleware for logging,
482
+ debugging, URL routing, authentication, and session handling. Sinatra uses
483
+ many of of these components automatically based on configuration so you
484
+ typically don't have to +use+ them explicitly.
485
+
486
+ == Testing
487
+
488
+ Sinatra tests can be written using any Rack-based testing library
489
+ or framework. {Rack::Test}[http://gitrdoc.com/brynary/rack-test] is
490
+ recommended:
491
+
492
+ require 'my_sinatra_app'
493
+ require 'rack/test'
494
+
495
+ class MyAppTest < Test::Unit::TestCase
496
+ include Rack::Test::Methods
497
+
498
+ def app
499
+ Sinatra::Application
500
+ end
501
+
502
+ def test_my_default
503
+ get '/'
504
+ assert_equal 'Hello World!', last_response.body
505
+ end
506
+
507
+ def test_with_params
508
+ get '/meet', :name => 'Frank'
509
+ assert_equal 'Hello Frank!', last_response.body
510
+ end
511
+
512
+ def test_with_rack_env
513
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
514
+ assert_equal "You're using Songbird!", last_response.body
515
+ end
516
+ end
517
+
518
+ NOTE: The built-in Sinatra::Test module and Sinatra::TestHarness class
519
+ are deprecated as of the 0.9.2 release.
520
+
521
+ == Sinatra::Base - Middleware, Libraries, and Modular Apps
522
+
523
+ Defining your app at the top-level works well for micro-apps but has
524
+ considerable drawbacks when building reuseable components such as Rack
525
+ middleware, Rails metal, simple libraries with a server component, or
526
+ even Sinatra extensions. The top-level DSL pollutes the Object namespace
527
+ and assumes a micro-app style configuration (e.g., a single application
528
+ file, ./public and ./views directories, logging, exception detail page,
529
+ etc.). That's where Sinatra::Base comes into play:
530
+
531
+ require 'sinatra/base'
532
+
533
+ class MyApp < Sinatra::Base
534
+ set :sessions, true
535
+ set :foo, 'bar'
536
+
537
+ get '/' do
538
+ 'Hello world!'
539
+ end
540
+ end
541
+
542
+ The MyApp class is an independent Rack component that can act as
543
+ Rack middleware, a Rack application, or Rails metal. You can +use+ or
544
+ +run+ this class from a rackup +config.ru+ file; or, control a server
545
+ component shipped as a library:
546
+
547
+ MyApp.run! :host => 'localhost', :port => 9090
548
+
549
+ The methods available to Sinatra::Base subclasses are exactly as those
550
+ available via the top-level DSL. Most top-level apps can be converted to
551
+ Sinatra::Base components with two modifications:
552
+
553
+ * Your file should require +sinatra/base+ instead of +sinatra+;
554
+ otherwise, all of Sinatra's DSL methods are imported into the main
555
+ namespace.
556
+ * Put your app's routes, error handlers, filters, and options in a subclass
557
+ of Sinatra::Base.
558
+
559
+ +Sinatra::Base+ is a blank slate. Most options are disabled by default,
560
+ including the built-in server. See {Options and Configuration}[http://sinatra.github.com/configuration.html]
561
+ for details on available options and their behavior.
562
+
563
+ SIDEBAR: Sinatra's top-level DSL is implemented using a simple delegation
564
+ system. The +Sinatra::Application+ class -- a special subclass of
565
+ Sinatra::Base -- receives all :get, :put, :post, :delete, :before,
566
+ :error, :not_found, :configure, and :set messages sent to the
567
+ top-level. Have a look at the code for yourself: here's the
568
+ {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
569
+ being {included into the main namespace}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25].
570
+
571
+ == Command line
572
+
573
+ Sinatra applications can be run directly:
574
+
575
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
576
+
577
+ Options are:
578
+
579
+ -h # help
580
+ -p # set the port (default is 4567)
581
+ -h # set the host (default is 0.0.0.0)
582
+ -e # set the environment (default is development)
583
+ -s # specify rack server/handler (default is thin)
584
+ -x # turn on the mutex lock (default is off)
585
+
586
+ == The Bleeding Edge
587
+
588
+ If you would like to use Sinatra's latest bleeding code, create a local
589
+ clone and run your app with the <tt>sinatra/lib</tt> directory on the
590
+ <tt>LOAD_PATH</tt>:
591
+
592
+ cd myapp
593
+ git clone git://github.com/sinatra/sinatra.git
594
+ ruby -Isinatra/lib myapp.rb
595
+
596
+ Alternatively, you can add the <tt>sinatra/lib</tt> directory to the
597
+ <tt>LOAD_PATH</tt> in your application:
598
+
599
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
600
+ require 'rubygems'
601
+ require 'sinatra'
602
+
603
+ get '/about' do
604
+ "I'm running version " + Sinatra::VERSION
605
+ end
606
+
607
+ To update the Sinatra sources in the future:
608
+
609
+ cd myproject/sinatra
610
+ git pull
611
+
612
+ == More
613
+
614
+ * {Project Website}[http://sinatra.github.com/] - Additional documentation,
615
+ news, and links to other resources.
616
+ * {Contributing}[http://sinatra.github.com/contributing.html] - Find a bug? Need
617
+ help? Have a patch?
618
+ * {Lighthouse}[http://sinatra.lighthouseapp.com] - Issue tracking and release
619
+ planning.
620
+ * {Twitter}[http://twitter.com/sinatra]
621
+ * {Mailing List}[http://groups.google.com/group/sinatrarb]
622
+ * {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] on http://freenode.net