sinatra-sugar 0.4.0.a
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/README.md +46 -0
- data/lib/sinatra/sugar.rb +188 -0
- data/spec/sinatra/sugar_spec.rb +39 -0
- data/spec/spec_helper.rb +3 -0
- metadata +95 -0
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
Sinatra::Sugar
|
2
|
+
==============
|
3
|
+
|
4
|
+
Basic [Sinatra](http://sinatrarb.com) extension (mainly extending Sinatra's standard methods, like set or register).
|
5
|
+
Also it features a more advanced path guessing than Sinatra::Base.
|
6
|
+
|
7
|
+
Normally you do not have to register this module manually, as the other extensions will do so if necessary.
|
8
|
+
|
9
|
+
BigBand
|
10
|
+
-------
|
11
|
+
|
12
|
+
Sinatra::Sugar is part of the [BigBand](http://github.com/rkh/big_band) stack.
|
13
|
+
Check it out if you are looking for other fancy Sinatra extensions.
|
14
|
+
|
15
|
+
More advanced set
|
16
|
+
-----------------
|
17
|
+
|
18
|
+
- Adds set\_#{key} and set_value hooks to set.
|
19
|
+
- Merges the old value with the new one, if both are hashes:
|
20
|
+
|
21
|
+
set :haml, :format => :html5, :escape_html => true
|
22
|
+
set :haml, :excape_html => false
|
23
|
+
haml # => { :format => :html5, :escape_html => false }
|
24
|
+
|
25
|
+
- Allowes passing a block:
|
26
|
+
|
27
|
+
set(:foo) { Time.now }
|
28
|
+
|
29
|
+
- Defines a helper to access #{key} and #{key}? unless a helper/method with that name already exists.
|
30
|
+
|
31
|
+
More advanced register
|
32
|
+
----------------------
|
33
|
+
|
34
|
+
If an exntesion is registered twice, the registered hook will only be called once.
|
35
|
+
|
36
|
+
Ability to extend command line options
|
37
|
+
--------------------------------------
|
38
|
+
|
39
|
+
Example:
|
40
|
+
|
41
|
+
require "sinatra"
|
42
|
+
require "sinatra/sugar"
|
43
|
+
|
44
|
+
configure do
|
45
|
+
run_option_parser.on("-i") { puts "yes, -i is a nice option" }
|
46
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "monkey"
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module Sugar
|
6
|
+
module BaseMethods
|
7
|
+
Base.extend self
|
8
|
+
|
9
|
+
def callers_to_ignore
|
10
|
+
class << Sinatra::Base
|
11
|
+
CALLERS_TO_IGNORE
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def ignore_caller(pattern = nil)
|
16
|
+
case pattern
|
17
|
+
when String then Dir.glob(pattern) { |file| ignore_caller File.expand_path(file).to_sym }
|
18
|
+
when Symbol then ignore_caller Regexp.new(Regexp.escape(pattern.to_s))
|
19
|
+
when Regexp then callers_to_ignore << pattern
|
20
|
+
when nil then ignore_caller caller.first[/^[^:]*/].to_sym
|
21
|
+
when Array then pattern.each { |p| ignore_caller p }
|
22
|
+
else raise ArgumentError, "cannot handle #{pattern.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
|
29
|
+
attr_writer :root, :guessed_root
|
30
|
+
|
31
|
+
# More advanced set:
|
32
|
+
# - Adds set_#{key} and set_value hooks to set.
|
33
|
+
# - Merges the old value with the new one, if both are hashes:
|
34
|
+
# set :haml, :format => :html5, :escape_html => true
|
35
|
+
# set :haml, :excape_html => false
|
36
|
+
# haml # => { :format => :html5, :escape_html => false }
|
37
|
+
# - Allowes passing a block:
|
38
|
+
# set(:foo) { Time.now }
|
39
|
+
# - Defines a helper to access #{key} and #{key}? unless a helper/method with that name already exists.
|
40
|
+
def set(key, value = self, &block)
|
41
|
+
# FIXME: refactor, refactor, refactor
|
42
|
+
if block_given?
|
43
|
+
raise ArgumentError, "both a value and a block given" if value != self
|
44
|
+
value = block
|
45
|
+
end
|
46
|
+
symbolized = (key.to_sym if key.respond_to? :to_sym)
|
47
|
+
old_value = (send(symbolized) if symbolized and respond_to? symbolized)
|
48
|
+
value = old_value.merge value if value.is_a? Hash and old_value.is_a? Hash
|
49
|
+
super(key, value)
|
50
|
+
if symbolized
|
51
|
+
method_names = instance_methods.map { |m| m.to_s }
|
52
|
+
define_method(key) { self.class.send(key) } unless method_names.include? key.to_s
|
53
|
+
define_method("#{key}?") { self.class.send("#{key}?") } unless method_names.include? "#{key}?"
|
54
|
+
end
|
55
|
+
# HACK: Sinatra::Base.set uses recursion and in the final step value always
|
56
|
+
# is a Proc. Also, if value is a Proc no step ever follows. I abuse this to
|
57
|
+
# invoke the hooks only once per set.
|
58
|
+
if value.is_a? Proc
|
59
|
+
invoke_hook "set_#{key}", self
|
60
|
+
invoke_hook :set_value, self, key
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
# More advanced register:
|
66
|
+
# - If an exntesion is registered twice, the registered hook will only be called once.
|
67
|
+
def register(*extensions, &block)
|
68
|
+
extensions.reject! { |e| self.extensions.include? e }
|
69
|
+
super(*extensions, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Short hand so you can skip those ugly File.expand_path(File.join(File.dirname(__FILE__), ...))
|
73
|
+
# lines.
|
74
|
+
def root_path(*args)
|
75
|
+
relative = File.join(*args)
|
76
|
+
return relative if relative.expand_path == relative
|
77
|
+
root.expand_path / relative
|
78
|
+
end
|
79
|
+
|
80
|
+
# Like root_path, but does return an array instead of a string. Optionally takes a block that will
|
81
|
+
# be called for each entry once.
|
82
|
+
#
|
83
|
+
# Example:
|
84
|
+
# class Foo < BigBand
|
85
|
+
# root_glob("app", "{models,views,controllers}", "*.rb") { |file| load file }
|
86
|
+
# end
|
87
|
+
def root_glob(*args, &block)
|
88
|
+
Dir.glob(root_path(*args), &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Whether or not to start a webserver.
|
92
|
+
def run?
|
93
|
+
@run ||= true
|
94
|
+
@run and !@running and app_file? and $0.expand_path == app_file.expand_path
|
95
|
+
end
|
96
|
+
|
97
|
+
# Disable automatically running this class as soon it is subclassed.
|
98
|
+
def inherited
|
99
|
+
super
|
100
|
+
@run = false
|
101
|
+
end
|
102
|
+
|
103
|
+
# The application's root directory. BigBand will guess if missing.
|
104
|
+
def root
|
105
|
+
return ".".expand_path unless app_file?
|
106
|
+
return @root if @root
|
107
|
+
@guessed_root ||= begin
|
108
|
+
dir = app_file.expand_path.dirname
|
109
|
+
if dir.basename == "lib" and not (dir / "lib").directory?
|
110
|
+
dir.dirname
|
111
|
+
else
|
112
|
+
dir
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns true if the #root is known.
|
118
|
+
def root?
|
119
|
+
!!@root || app_file?
|
120
|
+
end
|
121
|
+
|
122
|
+
# Option parser for #run!
|
123
|
+
def run_option_parser
|
124
|
+
@run_option_parser ||= begin
|
125
|
+
require 'optparse'
|
126
|
+
OptionParser.new do |op|
|
127
|
+
op.on('-x') { set :lock, true }
|
128
|
+
op.on('-e env') { |val| set :environment, val.to_sym }
|
129
|
+
op.on('-s server') { |val| set :server, val }
|
130
|
+
op.on('-p port') { |val| set :port, val.to_i }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Extended #run!, offers an extandable option parser for
|
136
|
+
# BigBand with the same standard options as the one of
|
137
|
+
# Sinatra#Default (see #run_option_parser).
|
138
|
+
def run!(options = {})
|
139
|
+
run_option_parser.parse!(ARGV.dup) unless ARGV.empty?
|
140
|
+
@running = true
|
141
|
+
super(options)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
module InstanceMethods
|
147
|
+
|
148
|
+
# See BigBand::BasicExtentions::ClassMethods#root_path
|
149
|
+
def root_path(*args)
|
150
|
+
self.class.root_path(*args)
|
151
|
+
end
|
152
|
+
|
153
|
+
# See BigBand::BasicExtentions::ClassMethods#root_path
|
154
|
+
def root_glob(*args, &block)
|
155
|
+
self.class.root_glob(*args, &block)
|
156
|
+
end
|
157
|
+
|
158
|
+
# See BigBand::BasicExtentions::ClassMethods#root
|
159
|
+
def root
|
160
|
+
self.class.root
|
161
|
+
end
|
162
|
+
|
163
|
+
# See BigBand::BasicExtentions::ClassMethods#root?
|
164
|
+
def root?
|
165
|
+
self.class.root
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.registered(klass)
|
171
|
+
klass.set :app_file, klass.caller_files.first.expand_path unless klass.app_file?
|
172
|
+
klass.extend ClassMethods
|
173
|
+
klass.send :include, InstanceMethods
|
174
|
+
klass.set :haml, :format => :html5, :escape_html => true
|
175
|
+
klass.use Rack::Session::Cookie
|
176
|
+
klass.enable :sessions
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.set_app_file(klass)
|
180
|
+
klass.guessed_root = nil
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
Base.ignore_caller
|
186
|
+
register Sugar
|
187
|
+
|
188
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(__FILE__ + "/../../spec_helper.rb")
|
2
|
+
|
3
|
+
describe Sinatra::Sugar do
|
4
|
+
|
5
|
+
before { app :Sugar }
|
6
|
+
|
7
|
+
describe "set" do
|
8
|
+
|
9
|
+
it "adds hooks to Sinatra::Base#set" do
|
10
|
+
extension = Module.new
|
11
|
+
extension.should_receive(:set_foo).with(app)
|
12
|
+
extension.should_receive(:set_value).with(app, :foo)
|
13
|
+
app.register extension
|
14
|
+
app.set :foo, 42
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows passing a block" do
|
18
|
+
app.set(:foo) { 42 }
|
19
|
+
app.foo.should == 42
|
20
|
+
end
|
21
|
+
|
22
|
+
it "merges hash values" do
|
23
|
+
app.set :foo, :bar => 42
|
24
|
+
app.set :foo, :baz => 23
|
25
|
+
app.foo[:bar].should == 42
|
26
|
+
app.foo[:baz].should == 23
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "register" do
|
32
|
+
it "registers an extension only once" do
|
33
|
+
extension = Module.new
|
34
|
+
extension.should_receive(:registered).once.with(app)
|
35
|
+
10.times { app.register extension }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-sugar
|
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-15 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-test-helper
|
26
|
+
type: :development
|
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
|
35
|
+
type: :runtime
|
36
|
+
version_requirement:
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.9.4
|
42
|
+
version:
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: rspec
|
45
|
+
type: :development
|
46
|
+
version_requirement:
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 1.3.0
|
52
|
+
version:
|
53
|
+
description: Some extensions to the sinatra default behavior (usefull for other Sintatra extensions, part of BigBand).
|
54
|
+
email: konstantin.mailinglists@googlemail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- lib/sinatra/sugar.rb
|
63
|
+
- spec/sinatra/sugar_spec.rb
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
- README.md
|
66
|
+
has_rdoc: yard
|
67
|
+
homepage: http://github.com/rkh/sinatra-sugar
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
version:
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.3.1
|
86
|
+
version:
|
87
|
+
requirements: []
|
88
|
+
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.3.5
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: Some extensions to the sinatra default behavior (usefull for other Sintatra extensions, part of BigBand).
|
94
|
+
test_files: []
|
95
|
+
|