pistol 0.0.1

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.
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
+