sinatra-reloader 0.4.0.a

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ Sinatra::Reloader
2
+ =================
3
+
4
+ Advanced code reloader for [Sinatra](http://sinatrarb.com). Reloads only files that have
5
+ changed and automatically detects orphaned routes that have to be removed. Most other
6
+ implementations delete all routes and reload all code if one file changed, which takes way
7
+ more time than reloading only one file, especially in larger projects. Files defining
8
+ routes will be added to the reload list per default. Avoid reloading with dont_reload. Add
9
+ other files to the reload list with also_reload.
10
+
11
+ BigBand
12
+ -------
13
+
14
+ Sinatra::Reloader is part of the [BigBand](http://github.com/rkh/big_band) stack.
15
+ Check it out if you are looking for other fancy Sinatra extensions.
16
+
17
+ BigBand will setup the reloader automatically, but only in development mode.
18
+
19
+ Usage
20
+ -----
21
+
22
+ require "sinatra/base"
23
+ require "sinatra/reloader"
24
+
25
+ class Foo < Sinatra::Base
26
+ configure(:development) do
27
+ register Sinatra::Reloader
28
+ also_reload "app/models/*.rb"
29
+ dont_reload "lib/**/*.rb"
30
+ end
31
+ end
@@ -0,0 +1,121 @@
1
+ require "monkey"
2
+ require "sinatra/base"
3
+ require "sinatra/sugar"
4
+ require "sinatra/advanced_routes"
5
+
6
+ module Sinatra
7
+ Base.ignore_caller
8
+
9
+ # Advanced reloader for sinatra. Reloads only files that have changed and automatically
10
+ # detects orphaned routes that have to be removed. Files defining routes will be added
11
+ # to the reload list per default. Avoid reloading with dont_reload. Add other files to
12
+ # the reload list with also_reload.
13
+ #
14
+ # Usage:
15
+ #
16
+ # require "big_band"
17
+ # class Foo < Sinatra::Base
18
+ # configure(:development) do
19
+ # register BigBand::Reloader
20
+ # also_reload "app/models/*.rb"
21
+ # dont_reload "lib/**/*.rb"
22
+ # end
23
+ # end
24
+ #
25
+ # Per default this will only be acitvated in development mode.
26
+ module Reloader
27
+
28
+ class FileWatcher < Array
29
+
30
+ attr_reader :file, :mtime
31
+
32
+ extend Enumerable
33
+ @map ||= {}
34
+
35
+ def self.register(route)
36
+ new(route.file) << route if route.file?
37
+ end
38
+
39
+ def self.new(file)
40
+ @map[file.expand_path] ||= super
41
+ end
42
+
43
+ class << self
44
+ alias [] new
45
+ end
46
+
47
+ def self.each(&block)
48
+ @map.values.each(&block)
49
+ end
50
+
51
+ def initialize(file)
52
+ @reload = true
53
+ @file, @mtime = file, File.mtime(file)
54
+ super()
55
+ end
56
+
57
+ def changed?
58
+ !File.exist? file or @mtime != File.mtime(file)
59
+ end
60
+
61
+ def dont_reload!(dont = true)
62
+ @reload = !dont
63
+ end
64
+
65
+ def reload?
66
+ @reload and changed?
67
+ end
68
+
69
+ def reload
70
+ reload! if reload?
71
+ end
72
+
73
+ def reload!
74
+ each { |route| route.deactivate }
75
+ $LOADED_FEATURES.delete file
76
+ clear
77
+ if File.exist? file
78
+ @mtime = File.mtime(file)
79
+ require file
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ module ClassMethods
86
+ def dont_reload(*files)
87
+ if [true, false].include? files.last then dont = files.pop
88
+ else dont = true
89
+ end
90
+ files.flatten.each do |file|
91
+ Dir.glob(file) { |f| FileWatcher[f].dont_reload! dont }
92
+ end
93
+ end
94
+
95
+ def also_reload(*files)
96
+ dont_reload(files, false)
97
+ end
98
+ end
99
+
100
+ def self.registered(klass)
101
+ klass.register AdvancedRoutes
102
+ klass.extend ClassMethods
103
+ klass.each_route { |route| advanced_route_added(route) }
104
+ klass.before { Reloader.reload_routes }
105
+ end
106
+
107
+ def self.advanced_route_added(route)
108
+ FileWatcher.register(route)
109
+ end
110
+
111
+ def self.thread_safe?
112
+ Thread and Thread.list.size > 1 and Thread.respond_to? :exclusive
113
+ end
114
+
115
+ def self.reload_routes(thread_safe = true)
116
+ return Thread.exclusive { reload_routes(false) } if thread_safe and thread_safe?
117
+ FileWatcher.each { |file| file.reload }
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe Sinatra::Reloader do
4
+
5
+ def app_file(file, content, go_sleeping = true)
6
+ sleep 1 if go_sleeping
7
+ file = File.expand_path(file, @temp_dir)
8
+ File.open(file, "w") { |f| f << "class ExampleApp < Sinatra::Base; #{content}; end" }
9
+ require file
10
+ file
11
+ end
12
+
13
+ def app
14
+ ExampleApp
15
+ end
16
+
17
+ before :all do
18
+ @temp_dir ||= File.expand_path "../../temp", __FILE__
19
+ rm_rf @temp_dir
20
+ mkdir_p @temp_dir
21
+ class ExampleApp < Sinatra::Base
22
+ register Sinatra::Reloader
23
+ end
24
+ end
25
+
26
+ after :all do
27
+ rm_rf @temp_dir
28
+ end
29
+
30
+ it "should reload files" do
31
+ app_file("example_app.rb", "get('/foo') { 'foo' }")
32
+ browse_route(:get, '/foo').body.should == 'foo'
33
+ app_file("example_app.rb", "get('/foo') { 'bar' }")
34
+ browse_route(:get, '/foo').body.should == 'bar'
35
+ end
36
+
37
+ it "should not affact other routes" do
38
+ app_file("example_app.rb", "get('/foo') { 'foo' }")
39
+ app_file("example_app2.rb", "get('/bar') { 'bar' }", false)
40
+ browse_route(:get, '/bar').body.should == 'bar'
41
+ app_file("example_app.rb", "get('/foo') { 'bar' }")
42
+ browse_route(:get, '/bar').body.should == 'bar'
43
+ end
44
+
45
+ it "should respect dont_reload" do
46
+ file = app_file("example_app3.rb", "get('/baz') { 'foo' }", false)
47
+ app.dont_reload file
48
+ app_file("example_app3.rb", "get('/baz') { 'bar' }")
49
+ browse_route(:get, '/baz').body.should == 'foo'
50
+ end
51
+
52
+ end
@@ -0,0 +1,6 @@
1
+ require "sinatra/rspec"
2
+ require "sinatra/reloader"
3
+ require "fileutils"
4
+ require "monkey"
5
+ Sinatra::Base.set :environment, :test
6
+ include FileUtils
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-reloader
3
+ version: &id001 !ruby/object:Gem::Version
4
+ version: 0.4.0.a
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Haase
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-16 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: monkey-lib
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - *id001
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: sinatra-advanced-routes
26
+ type: :runtime
27
+ version_requirement:
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "="
31
+ - *id001
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: sinatra-sugar
35
+ type: :runtime
36
+ version_requirement:
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "="
40
+ - *id001
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: sinatra-test-helper
44
+ type: :development
45
+ version_requirement:
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "="
49
+ - *id001
50
+ version:
51
+ - !ruby/object:Gem::Dependency
52
+ name: sinatra
53
+ type: :runtime
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.9.4
60
+ version:
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ type: :development
64
+ version_requirement:
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.3.0
70
+ version:
71
+ description: Smart and fast code reloader for Sinatra (part of BigBand).
72
+ email: konstantin.mailinglists@googlemail.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files: []
78
+
79
+ files:
80
+ - lib/sinatra/reloader.rb
81
+ - spec/sinatra/reloader_spec.rb
82
+ - spec/spec_helper.rb
83
+ - README.md
84
+ has_rdoc: yard
85
+ homepage: http://github.com/rkh/sinatra-reloader
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options: []
90
+
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ version:
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.3.1
104
+ version:
105
+ requirements: []
106
+
107
+ rubyforge_project:
108
+ rubygems_version: 1.3.5
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Smart and fast code reloader for Sinatra (part of BigBand).
112
+ test_files: []
113
+