tennpipes-base 3.6.6
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +294 -0
- data/Rakefile +1 -0
- data/bin/tennpipes +8 -0
- data/lib/tennpipes-base.rb +196 -0
- data/lib/tennpipes-base/application.rb +175 -0
- data/lib/tennpipes-base/application/application_setup.rb +202 -0
- data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
- data/lib/tennpipes-base/application/flash.rb +229 -0
- data/lib/tennpipes-base/application/params_protection.rb +129 -0
- data/lib/tennpipes-base/application/routing.rb +1002 -0
- data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
- data/lib/tennpipes-base/caller.rb +53 -0
- data/lib/tennpipes-base/cli/adapter.rb +33 -0
- data/lib/tennpipes-base/cli/base.rb +105 -0
- data/lib/tennpipes-base/cli/console.rb +20 -0
- data/lib/tennpipes-base/cli/launcher.rb +103 -0
- data/lib/tennpipes-base/cli/rake.rb +50 -0
- data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
- data/lib/tennpipes-base/command.rb +38 -0
- data/lib/tennpipes-base/ext/sinatra.rb +29 -0
- data/lib/tennpipes-base/filter.rb +52 -0
- data/lib/tennpipes-base/images/404.png +0 -0
- data/lib/tennpipes-base/images/500.png +0 -0
- data/lib/tennpipes-base/loader.rb +202 -0
- data/lib/tennpipes-base/logger.rb +492 -0
- data/lib/tennpipes-base/module.rb +58 -0
- data/lib/tennpipes-base/mounter.rb +308 -0
- data/lib/tennpipes-base/path_router.rb +119 -0
- data/lib/tennpipes-base/path_router/compiler.rb +110 -0
- data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
- data/lib/tennpipes-base/path_router/matcher.rb +123 -0
- data/lib/tennpipes-base/path_router/route.rb +169 -0
- data/lib/tennpipes-base/reloader.rb +309 -0
- data/lib/tennpipes-base/reloader/rack.rb +26 -0
- data/lib/tennpipes-base/reloader/storage.rb +55 -0
- data/lib/tennpipes-base/router.rb +98 -0
- data/lib/tennpipes-base/server.rb +119 -0
- data/lib/tennpipes-base/tasks.rb +21 -0
- data/lib/tennpipes-base/version.rb +20 -0
- data/lib/tennpipes-base/version.rb~ +20 -0
- data/test/fixtures/app_gem/Gemfile +4 -0
- data/test/fixtures/app_gem/app/app.rb +3 -0
- data/test/fixtures/app_gem/app_gem.gemspec +17 -0
- data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
- data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
- data/test/fixtures/apps/complex.rb +32 -0
- data/test/fixtures/apps/demo_app.rb +7 -0
- data/test/fixtures/apps/demo_demo.rb +7 -0
- data/test/fixtures/apps/demo_project/api/app.rb +7 -0
- data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
- data/test/fixtures/apps/demo_project/app.rb +7 -0
- data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
- data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
- data/test/fixtures/apps/helpers/support.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
- data/test/fixtures/apps/mountable_apps/static.html +1 -0
- data/test/fixtures/apps/precompiled_app.rb +19 -0
- data/test/fixtures/apps/simple.rb +32 -0
- data/test/fixtures/apps/static.rb +10 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
- data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
- data/test/fixtures/dependencies/a.rb +9 -0
- data/test/fixtures/dependencies/b.rb +4 -0
- data/test/fixtures/dependencies/c.rb +1 -0
- data/test/fixtures/dependencies/circular/e.rb +13 -0
- data/test/fixtures/dependencies/circular/f.rb +2 -0
- data/test/fixtures/dependencies/circular/g.rb +2 -0
- data/test/fixtures/dependencies/d.rb +4 -0
- data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
- data/test/fixtures/reloadable_apps/main/app.rb +10 -0
- data/test/helper.rb +30 -0
- data/test/test_application.rb +185 -0
- data/test/test_core.rb +93 -0
- data/test/test_csrf_protection.rb +208 -0
- data/test/test_dependencies.rb +57 -0
- data/test/test_filters.rb +389 -0
- data/test/test_flash.rb +168 -0
- data/test/test_locale.rb +21 -0
- data/test/test_logger.rb +295 -0
- data/test/test_mounter.rb +302 -0
- data/test/test_params_protection.rb +195 -0
- data/test/test_reloader_complex.rb +74 -0
- data/test/test_reloader_external.rb +21 -0
- data/test/test_reloader_simple.rb +101 -0
- data/test/test_reloader_system.rb +113 -0
- data/test/test_restful_routing.rb +33 -0
- data/test/test_router.rb +281 -0
- data/test/test_routing.rb +2328 -0
- metadata +301 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Tennpipes
|
|
2
|
+
module Reloader
|
|
3
|
+
##
|
|
4
|
+
# This class acts as a Rack middleware to be added to the application stack.
|
|
5
|
+
# This middleware performs a check and reload for source files at the start
|
|
6
|
+
# of each request, but also respects a specified cool down time
|
|
7
|
+
# during which no further action will be taken.
|
|
8
|
+
#
|
|
9
|
+
class Rack
|
|
10
|
+
def initialize(app, cooldown=1)
|
|
11
|
+
@app = app
|
|
12
|
+
@cooldown = cooldown
|
|
13
|
+
@last = (Time.now - cooldown)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Invoked in order to perform the reload as part of the request stack.
|
|
17
|
+
def call(env)
|
|
18
|
+
if @cooldown && Time.now > @last + @cooldown
|
|
19
|
+
Thread.list.size > 1 ? Thread.exclusive { Tennpipes.reload! } : Tennpipes.reload!
|
|
20
|
+
@last = Time.now
|
|
21
|
+
end
|
|
22
|
+
@app.call(env)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Tennpipes
|
|
2
|
+
module Reloader
|
|
3
|
+
module Storage
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
def clear!
|
|
7
|
+
files.each_key do |file|
|
|
8
|
+
remove(file)
|
|
9
|
+
Reloader.remove_feature(file)
|
|
10
|
+
end
|
|
11
|
+
@files = {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def remove(name)
|
|
15
|
+
file = files[name] || return
|
|
16
|
+
file[:constants].each{ |constant| Reloader.remove_constant(constant) }
|
|
17
|
+
file[:features].each{ |feature| Reloader.remove_feature(feature) }
|
|
18
|
+
files.delete(name)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prepare(name)
|
|
22
|
+
file = remove(name)
|
|
23
|
+
@old_entries ||= {}
|
|
24
|
+
@old_entries[name] = {
|
|
25
|
+
:constants => ObjectSpace.classes,
|
|
26
|
+
:features => old_features = Set.new($LOADED_FEATURES.dup)
|
|
27
|
+
}
|
|
28
|
+
features = file && file[:features] || []
|
|
29
|
+
features.each{ |feature| Reloader.safe_load(feature, :force => true) }
|
|
30
|
+
Reloader.remove_feature(name) if old_features.include?(name)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def commit(name)
|
|
34
|
+
entry = {
|
|
35
|
+
:constants => ObjectSpace.new_classes(@old_entries[name][:constants]),
|
|
36
|
+
:features => Set.new($LOADED_FEATURES) - @old_entries[name][:features] - [name]
|
|
37
|
+
}
|
|
38
|
+
files[name] = entry
|
|
39
|
+
@old_entries.delete(name)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def rollback(name)
|
|
43
|
+
new_constants = ObjectSpace.new_classes(@old_entries[name][:constants])
|
|
44
|
+
new_constants.each{ |klass| Reloader.remove_constant(klass) }
|
|
45
|
+
@old_entries.delete(name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def files
|
|
51
|
+
@files ||= {}
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module Tennpipes
|
|
2
|
+
##
|
|
3
|
+
# This class is an extended version of Rack::URLMap.
|
|
4
|
+
#
|
|
5
|
+
# Tennpipes::Router like Rack::URLMap dispatches in such a way that the
|
|
6
|
+
# longest paths are tried first, since they are most specific.
|
|
7
|
+
#
|
|
8
|
+
# Features:
|
|
9
|
+
#
|
|
10
|
+
# * Map a path to the specified App
|
|
11
|
+
# * Ignore server names (this solve issues with vhost and domain aliases)
|
|
12
|
+
# * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases)
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
#
|
|
16
|
+
# routes = Tennpipes::Router.new do
|
|
17
|
+
# map(:path => "/", :to => TennpipesWeb, :host => "tennpipes.local")
|
|
18
|
+
# map(:path => "/", :to => Admin, :host => "admin.tennpipes.local")
|
|
19
|
+
# end
|
|
20
|
+
# run routes
|
|
21
|
+
#
|
|
22
|
+
# routes = Tennpipes::Router.new do
|
|
23
|
+
# map(:path => "/", :to => TennpipesWeb, :host => /*.tennpipes.local/)
|
|
24
|
+
# end
|
|
25
|
+
# run routes
|
|
26
|
+
#
|
|
27
|
+
# @api semipublic
|
|
28
|
+
class Router
|
|
29
|
+
def initialize(*mapping, &block)
|
|
30
|
+
@mapping = []
|
|
31
|
+
mapping.each { |m| map(m) }
|
|
32
|
+
instance_eval(&block) if block
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Map a route path and host to a specified application.
|
|
37
|
+
#
|
|
38
|
+
# @param [Hash] options
|
|
39
|
+
# The options to map.
|
|
40
|
+
# @option options [Sinatra::Application] :to
|
|
41
|
+
# The class of the application to mount.
|
|
42
|
+
# @option options [String] :path ("/")
|
|
43
|
+
# The path to map the specified application.
|
|
44
|
+
# @option options [String] :host
|
|
45
|
+
# The host to map the specified application.
|
|
46
|
+
#
|
|
47
|
+
# @example
|
|
48
|
+
# map(:path => "/", :to => TennpipesWeb, :host => "tennpipes.local")
|
|
49
|
+
#
|
|
50
|
+
# @return [Array] The sorted route mappings.
|
|
51
|
+
# @api semipublic
|
|
52
|
+
def map(options={})
|
|
53
|
+
path = options[:path] || "/"
|
|
54
|
+
host = options[:host]
|
|
55
|
+
app = options[:to]
|
|
56
|
+
|
|
57
|
+
raise ArgumentError, "paths need to start with /" if path[0] != ?/
|
|
58
|
+
raise ArgumentError, "app is required" if app.nil?
|
|
59
|
+
|
|
60
|
+
path = path.chomp('/')
|
|
61
|
+
match = Regexp.new("^#{Regexp.quote(path).gsub('/', '/+')}(.*)", nil, 'n')
|
|
62
|
+
host = Regexp.new("^#{Regexp.quote(host)}$", true, 'n') unless host.nil? || host.is_a?(Regexp)
|
|
63
|
+
|
|
64
|
+
@mapping << [host, path, match, app]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The call handler setup to route a request given the mappings specified.
|
|
68
|
+
def call(env)
|
|
69
|
+
began_at = Time.now
|
|
70
|
+
path_info = env["PATH_INFO"].to_s
|
|
71
|
+
script_name = env['SCRIPT_NAME']
|
|
72
|
+
http_host = env['HTTP_HOST']
|
|
73
|
+
last_result = nil
|
|
74
|
+
|
|
75
|
+
@mapping.each do |host, path, match, app|
|
|
76
|
+
next unless host.nil? || http_host =~ host
|
|
77
|
+
next unless path_info =~ match && rest = $1
|
|
78
|
+
next unless rest.empty? || rest[0] == ?/
|
|
79
|
+
|
|
80
|
+
rest = "/" if rest.empty?
|
|
81
|
+
|
|
82
|
+
env['SCRIPT_NAME'] = script_name + path
|
|
83
|
+
env['PATH_INFO'] = rest
|
|
84
|
+
last_result = app.call(env)
|
|
85
|
+
|
|
86
|
+
cascade_setting = app.respond_to?(:cascade) ? app.cascade : true
|
|
87
|
+
cascade_statuses = cascade_setting.respond_to?(:include?) ? cascade_setting : Mounter::DEFAULT_CASCADE
|
|
88
|
+
break unless cascade_setting && cascade_statuses.include?(last_result[0])
|
|
89
|
+
end
|
|
90
|
+
last_result || begin
|
|
91
|
+
env['SCRIPT_NAME'] = script_name
|
|
92
|
+
env['PATH_INFO'] = path_info
|
|
93
|
+
Tennpipes::Logger::Rack.new(nil,'/').send(:log, env, 404, {}, began_at) if logger.debug?
|
|
94
|
+
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
module Tennpipes
|
|
2
|
+
##
|
|
3
|
+
# Runs the Tennpipes apps as a self-hosted server using:
|
|
4
|
+
# thin, mongrel, or WEBrick in that order.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# Tennpipes.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found
|
|
8
|
+
# Tennpipes.run!("0.0.0.0", "4000", "mongrel") # use => host: "0.0.0.0", port: "4000", adapter: "mongrel"
|
|
9
|
+
#
|
|
10
|
+
def self.run!(options={})
|
|
11
|
+
Tennpipes.load!
|
|
12
|
+
Server.start(*detect_application(options))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
#
|
|
19
|
+
def self.detect_application(options)
|
|
20
|
+
default_config_file = 'config.ru'
|
|
21
|
+
if (config_file = options.delete(:config)) || File.file?(default_config_file)
|
|
22
|
+
config_file ||= default_config_file
|
|
23
|
+
fail "Rack config file `#{config_file}` must have `.ru` extension" unless config_file =~ /\.ru$/
|
|
24
|
+
rack_app, rack_options = Rack::Builder.parse_file(config_file)
|
|
25
|
+
[rack_app, rack_options.merge(options)]
|
|
26
|
+
else
|
|
27
|
+
[Tennpipes.application, options]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# This module builds a Tennpipes server to run the project based on available handlers.
|
|
33
|
+
#
|
|
34
|
+
class Server < Rack::Server
|
|
35
|
+
DEFAULT_ADDRESS = { :Host => '127.0.0.1', :Port => 3000 }
|
|
36
|
+
|
|
37
|
+
# Server Handlers
|
|
38
|
+
Handlers = [:thin, :puma, :'spider-gazelle', :mongrel, :trinidad, :webrick]
|
|
39
|
+
|
|
40
|
+
# Starts the application on the available server with specified options.
|
|
41
|
+
def self.start(app, options={})
|
|
42
|
+
options = options.to_hash.symbolize_keys
|
|
43
|
+
options.update(parse_server_options(options.delete(:options)))
|
|
44
|
+
options.update(detect_address(options))
|
|
45
|
+
options[:pid] = prepare_pid(options[:pid]) if options[:daemonize]
|
|
46
|
+
options[:server] = detect_rack_handler if options[:server].blank?
|
|
47
|
+
# disable Webrick AccessLog
|
|
48
|
+
options[:AccessLog] = []
|
|
49
|
+
new(options, app).start
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def initialize(options, app)
|
|
53
|
+
@options, @app = options, app
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Starts the application on the available server with specified options.
|
|
57
|
+
def start
|
|
58
|
+
puts "=> Tennpipes/#{Tennpipes.version} has taken the stage #{Tennpipes.env} at http://#{options[:Host]}:#{options[:Port]}"
|
|
59
|
+
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
|
60
|
+
super do |server|
|
|
61
|
+
server.threaded = true if server.respond_to?(:threaded=)
|
|
62
|
+
end
|
|
63
|
+
ensure
|
|
64
|
+
puts "<= Tennpipes leaves the gun, takes the cannoli" unless options[:daemonize]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The application the server will run.
|
|
68
|
+
def app
|
|
69
|
+
@app
|
|
70
|
+
end
|
|
71
|
+
alias :wrapped_app :app
|
|
72
|
+
|
|
73
|
+
def options
|
|
74
|
+
@options
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private
|
|
78
|
+
|
|
79
|
+
# Detects the supported handler to use.
|
|
80
|
+
#
|
|
81
|
+
# @example
|
|
82
|
+
# detect_rack_handler => <ThinHandler>
|
|
83
|
+
#
|
|
84
|
+
def self.detect_rack_handler
|
|
85
|
+
Handlers.each do |handler|
|
|
86
|
+
begin
|
|
87
|
+
return handler if Rack::Handler.get(handler.to_s.downcase)
|
|
88
|
+
rescue LoadError
|
|
89
|
+
rescue NameError
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
fail "Server handler (#{Handlers.join(', ')}) not found."
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Prepares a directory for pid file.
|
|
96
|
+
#
|
|
97
|
+
def self.prepare_pid(pid)
|
|
98
|
+
pid = 'tmp/pids/server.pid' if pid.blank?
|
|
99
|
+
FileUtils.mkdir_p(File.dirname(pid))
|
|
100
|
+
File.expand_path(pid)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Parses an array of server options.
|
|
104
|
+
#
|
|
105
|
+
def self.parse_server_options(options)
|
|
106
|
+
parsed_server_options = Array(options).flat_map{ |option| option.split('=', 2) }
|
|
107
|
+
Hash[*parsed_server_options].symbolize_keys
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Detects Host and Port for Rack server.
|
|
111
|
+
#
|
|
112
|
+
def self.detect_address(options)
|
|
113
|
+
address = DEFAULT_ADDRESS.merge options.slice(:Host, :Port)
|
|
114
|
+
address[:Host] = options[:host] if options[:host].present?
|
|
115
|
+
address[:Port] = options[:port] if options[:port].present?
|
|
116
|
+
address
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Tennpipes
|
|
2
|
+
##
|
|
3
|
+
# This module it's used for bootstrap with tennpipes rake
|
|
4
|
+
# third party tasks, in your gem/plugin/extension you
|
|
5
|
+
# need only do this:
|
|
6
|
+
#
|
|
7
|
+
# @example
|
|
8
|
+
# Tennpipes::Tasks.files << yourtask.rb
|
|
9
|
+
# Tennpipes::Tasks.files.concat(Dir["/path/to/all/my/tasks/*.rb"])
|
|
10
|
+
# Tennpipes::Tasks.files.unshift("yourtask.rb")
|
|
11
|
+
#
|
|
12
|
+
module Tasks
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Returns a list of files to handle with tennpipes rake
|
|
16
|
+
#
|
|
17
|
+
def self.files
|
|
18
|
+
@files ||= []
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Manages current Tennpipes version for use in gem generation.
|
|
3
|
+
#
|
|
4
|
+
# We put this in a separate file so you can get tennpipes version
|
|
5
|
+
# without include full tennpipes core.
|
|
6
|
+
#
|
|
7
|
+
module Tennpipes
|
|
8
|
+
# The version constant for the current version of Tennpipes.
|
|
9
|
+
VERSION = '3.6.6' unless defined?(Tennpipes::VERSION)
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# The current Tennpipes version.
|
|
13
|
+
#
|
|
14
|
+
# @return [String]
|
|
15
|
+
# The version number.
|
|
16
|
+
#
|
|
17
|
+
def self.version
|
|
18
|
+
VERSION
|
|
19
|
+
end
|
|
20
|
+
end # Tennpipes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Manages current Tennpipes version for use in gem generation.
|
|
3
|
+
#
|
|
4
|
+
# We put this in a separate file so you can get tennpipes version
|
|
5
|
+
# without include full tennpipes core.
|
|
6
|
+
#
|
|
7
|
+
module Tennpipes
|
|
8
|
+
# The version constant for the current version of Tennpipes.
|
|
9
|
+
VERSION = '0.0.2' unless defined?(Tennpipes::VERSION)
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# The current Tennpipes version.
|
|
13
|
+
#
|
|
14
|
+
# @return [String]
|
|
15
|
+
# The version number.
|
|
16
|
+
#
|
|
17
|
+
def self.version
|
|
18
|
+
VERSION
|
|
19
|
+
end
|
|
20
|
+
end # Tennpipes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require File.expand_path('../lib/app_gem/version', __FILE__)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |gem|
|
|
5
|
+
gem.authors = ["Florian Gilcher"]
|
|
6
|
+
gem.email = ["florian.gilcher@asquera.de"]
|
|
7
|
+
gem.description = %q{TODO: Write a gem description}
|
|
8
|
+
gem.summary = %q{TODO: Write a gem summary}
|
|
9
|
+
gem.homepage = ""
|
|
10
|
+
|
|
11
|
+
gem.files = `git ls-files`.split($\)
|
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
14
|
+
gem.name = "app_gem"
|
|
15
|
+
gem.require_paths = ["app", "lib"]
|
|
16
|
+
gem.version = AppGem::VERSION
|
|
17
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
TENNPIPES_ROOT = File.dirname(__FILE__) unless defined? TENNPIPES_ROOT
|
|
2
|
+
|
|
3
|
+
module LibDemo
|
|
4
|
+
def self.give_me_a_random
|
|
5
|
+
@rand ||= rand(100)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Complex1Demo < Tennpipes::Application
|
|
10
|
+
set :reload, true
|
|
11
|
+
get("/old"){ "Old Sinatra Way" }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Complex2Demo < Tennpipes::Application
|
|
15
|
+
set :reload, true
|
|
16
|
+
get("/old"){ "Old Sinatra Way" }
|
|
17
|
+
|
|
18
|
+
controllers :var do
|
|
19
|
+
get(:destroy){ params.inspect }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
get("/"){ "The magick number is: 12!" } # Change only the number!!!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Complex1Demo.controllers do
|
|
26
|
+
get("/"){ "Given random #{LibDemo.give_me_a_random}" }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Complex2Demo.controllers do
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Tennpipes.load!
|