pistol 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Michel Martens, Damian Janowski and Cyril David
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all 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,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ Pistol
2
+ ======
3
+
4
+ _n. A small tool designed to reload your rack application._
5
+
6
+ Get it!
7
+ -------
8
+
9
+ $ gem install pistol
10
+
11
+ Usage
12
+ -----
13
+
14
+ # app.rb
15
+ require "sinatra/base"
16
+ require "pistol"
17
+
18
+ class App < Sinatra::Base
19
+ use Pistol, :files => Dir[__FILE__, "./app/**/*.rb"]
20
+ end
21
+
22
+ Dir["./app/**/*.rb"].each { |file| require file }
23
+
24
+ ### What this does:
25
+
26
+ 1. It marks `app.rb` as the main application file. It's assumed that app.rb
27
+ handles all the loading, boiler plate, etc.
28
+ 2. It reloads everything in `app/**/*.rb`. You can of course specify
29
+ other paths (e.g. `./config/*.rb`, `./lib/*.rb`).
30
+
31
+ ### Only in development?
32
+
33
+ Sure. Simply change it to:
34
+
35
+ class App < Sinatra::Base
36
+ configure :development do
37
+ use Pistol, :files => Dir[__FILE__, "./app/**/*.rb"]
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ task :start_app do
2
+ require "./test/fixtures/helloworld/app.rb"
3
+ require "logger"
4
+
5
+ Thread.new do
6
+ Rack::Handler::WEBrick.run(App.new,
7
+ :Port => 9595,
8
+ :Logger => ::Logger.new(File.open("/dev/null", "w")),
9
+ :AccessLog => []
10
+ )
11
+ end
12
+
13
+ # Let's simply wait for the sinatra app to start.
14
+ sleep 2
15
+ end
16
+
17
+ task :test => :start_app do
18
+ require "cutest"
19
+ Cutest.run(Dir["test/*_test.rb"])
20
+ end
@@ -0,0 +1,47 @@
1
+ class Pistol
2
+ VERSION = "0.0.1"
3
+
4
+ attr :options
5
+
6
+ def initialize(app, options = {})
7
+ @options = optimize_options(options)
8
+ @app = app
9
+ @app_file = options[:files].first
10
+ @last = last_mtime
11
+ end
12
+
13
+ def call(env)
14
+ current = last_mtime
15
+
16
+ if current >= @last
17
+ if Thread.list.size > 1
18
+ Thread.exclusive { reload! }
19
+ else
20
+ reload!
21
+ end
22
+
23
+ @last = current
24
+ end
25
+
26
+ @app.call(env)
27
+ end
28
+
29
+ private
30
+ def reload!
31
+ options[:files].each { |file| $LOADED_FEATURES.delete(file) }
32
+
33
+ @app.class.reset! if @app.class.respond_to?(:reset!)
34
+ require @app_file
35
+ end
36
+
37
+ def last_mtime
38
+ options[:files].map { |file| ::File.mtime(file) }.max
39
+ end
40
+
41
+ def optimize_options(options)
42
+ opts = options.dup
43
+ opts[:files] ||= Dir["./app/**/*.rb"]
44
+ opts[:files].map! { |file| File.expand_path(file) }
45
+ opts
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ require "sinatra/base"
2
+ require File.expand_path("./app/article", File.dirname(__FILE__))
3
+ require File.expand_path("./lib/book", File.dirname(__FILE__))
4
+ require File.expand_path("../../../lib/pistol", File.dirname(__FILE__))
5
+
6
+ class App < Sinatra::Base
7
+ set :root, lambda { |*args| File.join(File.dirname(__FILE__), *args) }
8
+ set :port, 9595
9
+
10
+ use Pistol, :files => Dir[__FILE__, root("app/**/*.rb")]
11
+
12
+ get "/hello" do
13
+ "Hello"
14
+ end
15
+
16
+ get "/article" do
17
+ Article.content
18
+ end
19
+
20
+ get "/book" do
21
+ Book.title
22
+ end
23
+ end
24
+
25
+ App.run! if __FILE__ == $0
@@ -0,0 +1,5 @@
1
+ class Article
2
+ def self.content
3
+ "Hello World v1"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Book
2
+ def self.title
3
+ "Sinatra Book"
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ require "cutest"
2
+ require "open-uri"
3
+
4
+ TEST_SERVER = "http://localhost:9595"
5
+
6
+ module Kernel
7
+ private
8
+ def get(path)
9
+ open([TEST_SERVER, path].join).read
10
+ end
11
+
12
+ def app_root(*args)
13
+ File.join(File.dirname(__FILE__), "fixtures", "helloworld", *args)
14
+ end
15
+
16
+ def modify(file, old, new)
17
+ path = app_root(file)
18
+
19
+ prev = File.read(path)
20
+ change(path, prev.gsub(old, new))
21
+ FileUtils.touch(path)
22
+
23
+ yield
24
+ ensure
25
+ change(app_root(file), prev)
26
+ end
27
+
28
+ def updated(file)
29
+ FileUtils.touch(app_root(file))
30
+ yield
31
+ end
32
+
33
+ def change(file, data)
34
+ File.open(file, "w") { |f| f.write data }
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path("./helper", File.dirname(__FILE__))
2
+
3
+ test "/hello" do
4
+ assert "Hello" == get("/hello")
5
+ end
6
+
7
+ test "/hello when modified" do
8
+ modify("app.rb", %{"Hello"}, %{"New Hello"}) do
9
+ assert "New Hello" == get("/hello")
10
+ end
11
+ end
12
+
13
+ test "/article changes when Article is changed" do
14
+ assert "Hello World v1" == get("/article")
15
+
16
+ modify("app/article.rb", %{"Hello World v1"}, %{"Hello World v2"}) do
17
+ assert "Hello World v2" == get("/article")
18
+ end
19
+ end
20
+
21
+ test "/book doesn't change since Book is in lib" do
22
+ assert "Sinatra Book" == get("/book")
23
+
24
+ modify("lib/book.rb", %{"Sinatra Book"}, %{"Rack Book"}) do
25
+ assert "Sinatra Book" == get("/book")
26
+ end
27
+ end
File without changes
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pistol
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Michel Martens
13
+ - Damian Janowski
14
+ - Cyril David
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-10-08 00:00:00 +08:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: cutest
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 1
32
+ - 0
33
+ version: "1.0"
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: sinatra
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 1
46
+ - 0
47
+ version: "1.0"
48
+ type: :development
49
+ version_requirements: *id002
50
+ description: |-
51
+ Extremely lightweight reloading tool for rack &
52
+ sinatra apps.
53
+ email:
54
+ - michel@soveran.com
55
+ - djanowski@dimaion.com
56
+ - cyx@pipetodevnull.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files: []
62
+
63
+ files:
64
+ - lib/pistol.rb
65
+ - README.markdown
66
+ - LICENSE
67
+ - Rakefile
68
+ - test/fixtures/helloworld/app/article.rb
69
+ - test/fixtures/helloworld/app.rb
70
+ - test/fixtures/helloworld/lib/article.rb
71
+ - test/fixtures/helloworld/lib/book.rb
72
+ - test/helper.rb
73
+ - test/pistol_test.rb
74
+ - test/sinatra_test.rb
75
+ has_rdoc: true
76
+ homepage: http://github.com/monk/pistol
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options: []
81
+
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project: pistol
103
+ rubygems_version: 1.3.7
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: The light tool for the reloading job.
107
+ test_files: []
108
+