tennpipes-base 3.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.rdoc +294 -0
  4. data/Rakefile +1 -0
  5. data/bin/tennpipes +8 -0
  6. data/lib/tennpipes-base.rb +196 -0
  7. data/lib/tennpipes-base/application.rb +175 -0
  8. data/lib/tennpipes-base/application/application_setup.rb +202 -0
  9. data/lib/tennpipes-base/application/authenticity_token.rb +25 -0
  10. data/lib/tennpipes-base/application/flash.rb +229 -0
  11. data/lib/tennpipes-base/application/params_protection.rb +129 -0
  12. data/lib/tennpipes-base/application/routing.rb +1002 -0
  13. data/lib/tennpipes-base/application/show_exceptions.rb +50 -0
  14. data/lib/tennpipes-base/caller.rb +53 -0
  15. data/lib/tennpipes-base/cli/adapter.rb +33 -0
  16. data/lib/tennpipes-base/cli/base.rb +105 -0
  17. data/lib/tennpipes-base/cli/console.rb +20 -0
  18. data/lib/tennpipes-base/cli/launcher.rb +103 -0
  19. data/lib/tennpipes-base/cli/rake.rb +50 -0
  20. data/lib/tennpipes-base/cli/rake_tasks.rb +72 -0
  21. data/lib/tennpipes-base/command.rb +38 -0
  22. data/lib/tennpipes-base/ext/sinatra.rb +29 -0
  23. data/lib/tennpipes-base/filter.rb +52 -0
  24. data/lib/tennpipes-base/images/404.png +0 -0
  25. data/lib/tennpipes-base/images/500.png +0 -0
  26. data/lib/tennpipes-base/loader.rb +202 -0
  27. data/lib/tennpipes-base/logger.rb +492 -0
  28. data/lib/tennpipes-base/module.rb +58 -0
  29. data/lib/tennpipes-base/mounter.rb +308 -0
  30. data/lib/tennpipes-base/path_router.rb +119 -0
  31. data/lib/tennpipes-base/path_router/compiler.rb +110 -0
  32. data/lib/tennpipes-base/path_router/error_handler.rb +8 -0
  33. data/lib/tennpipes-base/path_router/matcher.rb +123 -0
  34. data/lib/tennpipes-base/path_router/route.rb +169 -0
  35. data/lib/tennpipes-base/reloader.rb +309 -0
  36. data/lib/tennpipes-base/reloader/rack.rb +26 -0
  37. data/lib/tennpipes-base/reloader/storage.rb +55 -0
  38. data/lib/tennpipes-base/router.rb +98 -0
  39. data/lib/tennpipes-base/server.rb +119 -0
  40. data/lib/tennpipes-base/tasks.rb +21 -0
  41. data/lib/tennpipes-base/version.rb +20 -0
  42. data/lib/tennpipes-base/version.rb~ +20 -0
  43. data/test/fixtures/app_gem/Gemfile +4 -0
  44. data/test/fixtures/app_gem/app/app.rb +3 -0
  45. data/test/fixtures/app_gem/app_gem.gemspec +17 -0
  46. data/test/fixtures/app_gem/lib/app_gem.rb +7 -0
  47. data/test/fixtures/app_gem/lib/app_gem/version.rb +3 -0
  48. data/test/fixtures/apps/complex.rb +32 -0
  49. data/test/fixtures/apps/demo_app.rb +7 -0
  50. data/test/fixtures/apps/demo_demo.rb +7 -0
  51. data/test/fixtures/apps/demo_project/api/app.rb +7 -0
  52. data/test/fixtures/apps/demo_project/api/lib/api_lib.rb +3 -0
  53. data/test/fixtures/apps/demo_project/app.rb +7 -0
  54. data/test/fixtures/apps/external_apps/fake_lib.rb +1 -0
  55. data/test/fixtures/apps/external_apps/fake_root.rb +2 -0
  56. data/test/fixtures/apps/helpers/class_methods_helpers.rb +4 -0
  57. data/test/fixtures/apps/helpers/instance_methods_helpers.rb +4 -0
  58. data/test/fixtures/apps/helpers/support.rb +1 -0
  59. data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
  60. data/test/fixtures/apps/kiq.rb +3 -0
  61. data/test/fixtures/apps/lib/myklass.rb +2 -0
  62. data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
  63. data/test/fixtures/apps/models/child.rb +2 -0
  64. data/test/fixtures/apps/models/parent.rb +5 -0
  65. data/test/fixtures/apps/mountable_apps/rack_apps.rb +15 -0
  66. data/test/fixtures/apps/mountable_apps/static.html +1 -0
  67. data/test/fixtures/apps/precompiled_app.rb +19 -0
  68. data/test/fixtures/apps/simple.rb +32 -0
  69. data/test/fixtures/apps/static.rb +10 -0
  70. data/test/fixtures/apps/system.rb +13 -0
  71. data/test/fixtures/apps/system_class_methods_demo.rb +7 -0
  72. data/test/fixtures/apps/system_instance_methods_demo.rb +7 -0
  73. data/test/fixtures/dependencies/a.rb +9 -0
  74. data/test/fixtures/dependencies/b.rb +4 -0
  75. data/test/fixtures/dependencies/c.rb +1 -0
  76. data/test/fixtures/dependencies/circular/e.rb +13 -0
  77. data/test/fixtures/dependencies/circular/f.rb +2 -0
  78. data/test/fixtures/dependencies/circular/g.rb +2 -0
  79. data/test/fixtures/dependencies/d.rb +4 -0
  80. data/test/fixtures/reloadable_apps/external/app/app.rb +6 -0
  81. data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +6 -0
  82. data/test/fixtures/reloadable_apps/main/app.rb +10 -0
  83. data/test/helper.rb +30 -0
  84. data/test/test_application.rb +185 -0
  85. data/test/test_core.rb +93 -0
  86. data/test/test_csrf_protection.rb +208 -0
  87. data/test/test_dependencies.rb +57 -0
  88. data/test/test_filters.rb +389 -0
  89. data/test/test_flash.rb +168 -0
  90. data/test/test_locale.rb +21 -0
  91. data/test/test_logger.rb +295 -0
  92. data/test/test_mounter.rb +302 -0
  93. data/test/test_params_protection.rb +195 -0
  94. data/test/test_reloader_complex.rb +74 -0
  95. data/test/test_reloader_external.rb +21 -0
  96. data/test/test_reloader_simple.rb +101 -0
  97. data/test/test_reloader_system.rb +113 -0
  98. data/test/test_restful_routing.rb +33 -0
  99. data/test/test_router.rb +281 -0
  100. data/test/test_routing.rb +2328 -0
  101. metadata +301 -0
@@ -0,0 +1,50 @@
1
+ module Tennpipes
2
+ ##
3
+ # This module extend Sinatra::ShowExceptions adding Tennpipes as "Framework".
4
+ #
5
+ # @private
6
+ class ShowExceptions < Sinatra::ShowExceptions
7
+ if Sinatra::VERSION <= '1.4.5'
8
+ def call(env)
9
+ @app.call(env)
10
+ rescue Exception => e
11
+ errors, env["rack.errors"] = env["rack.errors"], @@eats_errors
12
+
13
+ if prefers_plain_text?(env)
14
+ content_type = "text/plain"
15
+ exception_string = dump_exception(e)
16
+ else
17
+ content_type = "text/html"
18
+ exception_string = pretty(env, e)
19
+ end
20
+
21
+ env["rack.errors"] = errors
22
+
23
+ # Post 893a2c50 in rack/rack, the #pretty method above, implemented in
24
+ # Rack::ShowExceptions, returns a String instead of an array.
25
+ body = Array(exception_string)
26
+
27
+ [
28
+ 500,
29
+ {"Content-Type" => content_type,
30
+ "Content-Length" => Rack::Utils.bytesize(body.join).to_s},
31
+ body
32
+ ]
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def frame_class(frame)
39
+ if frame.filename =~ /lib\/sinatra.*\.rb|lib\/tennpipes.*\.rb/
40
+ "framework"
41
+ elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
42
+ frame.filename =~ /\/bin\/(\w+)$/ ||
43
+ frame.filename =~ /Ruby\/Gems/
44
+ "system"
45
+ else
46
+ "app"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ module Tennpipes
2
+
3
+ # List of callers in a Tennpipes application that should be ignored as part of a stack trace.
4
+ TENNPIPES_IGNORE_CALLERS = [
5
+ %r{lib/tennpipes-.*$},
6
+ %r{/tennpipes-.*/(lib|bin)},
7
+ %r{/bin/tennpipes$},
8
+ %r{/sinatra(/(base|main|show_?exceptions))?\.rb$},
9
+ %r{lib/tilt.*\.rb$},
10
+ %r{lib/rack.*\.rb$},
11
+ %r{lib/mongrel.*\.rb$},
12
+ %r{lib/shotgun.*\.rb$},
13
+ %r{bin/shotgun$},
14
+ %r{\(.*\)},
15
+ %r{shoulda/context\.rb$},
16
+ %r{mocha/integration},
17
+ %r{test/unit},
18
+ %r{rake_test_loader\.rb},
19
+ %r{custom_require\.rb$},
20
+ %r{active_support},
21
+ %r{/thor}
22
+ ] unless defined?(TENNPIPES_IGNORE_CALLERS)
23
+
24
+ ##
25
+ # Add rubinius (and hopefully other VM implementations) ignore patterns ...
26
+ #
27
+ TENNPIPES_IGNORE_CALLERS.concat(RUBY_IGNORE_CALLERS) if defined?(RUBY_IGNORE_CALLERS)
28
+
29
+ private
30
+ ##
31
+ # The filename for the file that is the direct caller (first caller).
32
+ #
33
+ # @return [String]
34
+ # The file the caller method exists in.
35
+ #
36
+ def self.first_caller
37
+ caller_files.first
38
+ end
39
+
40
+ #
41
+ # Like +Kernel#caller+ but excluding certain magic entries and without
42
+ # line / method information; the resulting array contains filenames only.
43
+ #
44
+ # @return [Array<String>]
45
+ # The files of the calling methods.
46
+ #
47
+ def self.caller_files
48
+ caller(1).
49
+ map { |line| line.split(/:(?=\d|in )/)[0,2] }.
50
+ reject { |file,line| TENNPIPES_IGNORE_CALLERS.any? { |pattern| file =~ pattern } }.
51
+ map { |file,line| file }
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ module Tennpipes
2
+ module Cli
3
+ module Adapter
4
+ class << self
5
+ # Start for the given options a rackup handler
6
+ def start(options)
7
+ Tennpipes.run!(options.symbolize_keys)
8
+ end
9
+
10
+ # Method that stop (if exist) a running Tennpipes.application
11
+ def stop(options)
12
+ options.symbolize_keys!
13
+ if File.exist?(options[:pid])
14
+ pid = File.read(options[:pid]).to_i
15
+ puts "=> Sending INT to process with pid #{pid}"
16
+ begin
17
+ Process.kill(2, pid)
18
+ rescue Errno::ESRCH, RangeError => error
19
+ puts error.message
20
+ exit
21
+ rescue Errno::EPERM => error
22
+ puts error.message
23
+ abort
24
+ end
25
+ else
26
+ puts "=> #{options[:pid]} not found!"
27
+ abort
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,105 @@
1
+ require 'tennpipes-base/cli/launcher'
2
+
3
+ module Tennpipes
4
+ module Cli
5
+ class Base < Launcher
6
+ desc "rake", "Execute rake tasks."
7
+ method_option :environment, :type => :string, :aliases => "-e"
8
+ method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit."
9
+ method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace."
10
+ def rake(*args)
11
+ prepare :rake
12
+ args << "-T" if options[:list]
13
+ args << options[:list] unless options[:list].nil? || options[:list].to_s == "list"
14
+ args << "--trace" if options[:trace]
15
+ args << "--verbose" if options[:verbose]
16
+ ARGV.clear
17
+ ARGV.concat(args)
18
+ puts "=> Executing Rake #{ARGV.join(' ')} ..."
19
+ load File.expand_path('../rake.rb', __FILE__)
20
+ Rake.application.init
21
+ Rake.application.instance_variable_set(:@rakefile, __FILE__)
22
+ load File.expand_path('Rakefile')
23
+ Rake.application.top_level
24
+ end
25
+
26
+ desc "console", "Boots up the Tennpipes application irb console (alternatively use 'c')."
27
+ map "c" => :console
28
+ def console(*args)
29
+ prepare :console
30
+ require File.expand_path("../../version", __FILE__)
31
+ ARGV.clear
32
+ require 'irb'
33
+ begin
34
+ require "irb/completion"
35
+ rescue LoadError
36
+ end
37
+ require File.expand_path('config/boot.rb')
38
+ puts "=> Loading #{Tennpipes.env} console (Tennpipes v.#{Tennpipes.version})"
39
+ require File.expand_path('../console', __FILE__)
40
+ IRB.start
41
+ end
42
+
43
+ desc "generate", "Executes the Tennpipes generator with given options (alternatively use 'gen' or 'g')."
44
+ map ["gen", "g"] => :generate
45
+ def generate(*args)
46
+ begin
47
+ # We try to load the vendored tennpipes-init if exist
48
+ tennpipes_gen_path = File.expand_path('../../../../../tennpipes-init/lib', __FILE__)
49
+ $:.unshift(tennpipes_gen_path) if File.directory?(tennpipes_gen_path) && !$:.include?(tennpipes_gen_path)
50
+ require 'tennpipes-base/command'
51
+ require 'tennpipes-init/command'
52
+ ARGV.shift
53
+ ARGV << 'help' if ARGV.empty?
54
+ Tennpipes.bin_gen(*ARGV)
55
+ rescue
56
+ puts "<= You need tennpipes-init! Run: gem install tennpipes-init"
57
+ end
58
+ end
59
+
60
+ desc "version", "Show current Tennpipes version."
61
+ map ["-v", "--version"] => :version
62
+ def version
63
+ require 'tennpipes-base/version'
64
+ puts "Tennpipes v. #{Tennpipes.version}"
65
+ end
66
+
67
+ desc "runner", "Run a piece of code in the Tennpipes application environment (alternatively use 'run' or 'r')."
68
+ map ["run", "r"] => :runner
69
+ def runner(*args)
70
+ prepare :runner
71
+
72
+ code_or_file = args.shift
73
+ abort "Please specify code or file" if code_or_file.nil?
74
+
75
+ require File.expand_path('config/boot.rb')
76
+
77
+ if File.exist?(code_or_file)
78
+ eval(File.read(code_or_file), nil, code_or_file)
79
+ else
80
+ eval(code_or_file)
81
+ end
82
+ end
83
+
84
+ protected
85
+
86
+ def self.banner(task=nil, *args)
87
+ "tennpipes #{task.name}"
88
+ end
89
+
90
+ def capture(stream)
91
+ begin
92
+ stream = stream.to_s
93
+ eval "$#{stream} = StringIO.new"
94
+ yield
95
+ result = eval("$#{stream}").string
96
+ ensure
97
+ eval("$#{stream} = #{stream.upcase}")
98
+ end
99
+
100
+ result
101
+ end
102
+ alias :silence :capture
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,20 @@
1
+ # Reloads classes
2
+ def reload!
3
+ Tennpipes.reload!
4
+ end
5
+
6
+ # Show applications
7
+ def applications
8
+ puts "==== List of Mounted Applications ====\n\n"
9
+ Tennpipes.mounted_apps.each do |app|
10
+ puts " * %-10s mapped to %s" % [app.name, app.uri_root]
11
+ end
12
+ puts
13
+ Tennpipes.mounted_apps.map { |app| "#{app.name} => #{app.uri_root}" }
14
+ end
15
+
16
+ # Load apps
17
+ Tennpipes.mounted_apps.each do |app|
18
+ puts "=> Loading Application #{app.app_class}"
19
+ app.app_obj.setup_application!
20
+ end
@@ -0,0 +1,103 @@
1
+ require 'thor'
2
+
3
+ module Tennpipes
4
+ module Cli
5
+ class Launcher < Thor
6
+ include Thor::Actions
7
+
8
+ class_option :chdir, :type => :string, :aliases => "-c", :desc => "Change to dir before starting."
9
+ class_option :environment, :type => :string, :aliases => "-e", :desc => "Tennpipes Environment."
10
+ class_option :help, :type => :boolean, :desc => "Show help usage"
11
+
12
+ desc "start", "Starts the Tennpipes application (alternatively use 's')."
13
+ map "s" => :start
14
+ method_option :server, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)"
15
+ method_option :host, :type => :string, :aliases => "-h", :desc => "Bind to HOST address (default: 127.0.0.1)"
16
+ method_option :port, :type => :numeric, :aliases => "-p", :desc => "Use PORT (default: 3000)"
17
+ method_option :daemonize, :type => :boolean, :aliases => "-d", :desc => "Run daemonized in the background."
18
+ method_option :pid, :type => :string, :aliases => "-i", :desc => "File to store pid."
19
+ method_option :debug, :type => :boolean, :desc => "Set debugging flags."
20
+ method_option :options, :type => :array, :aliases => "-O", :desc => "--options NAME=VALUE NAME2=VALUE2'. pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} --server_options"
21
+ method_option :server_options, :type => :boolean, :desc => "Tells the current server handler's options that can be used with --options"
22
+ def start(*args)
23
+ prepare :start
24
+ require File.expand_path("../adapter", __FILE__)
25
+ require File.expand_path('config/boot.rb')
26
+
27
+ if options[:server_options]
28
+ puts server_options(options)
29
+ else
30
+ Tennpipes::Cli::Adapter.start(args.last ? options.merge(:config => args.last).freeze : options)
31
+ end
32
+ end
33
+
34
+ desc "stop", "Stops the Tennpipes application (alternatively use 'st')."
35
+ map "st" => :stop
36
+ method_option :pid, :type => :string, :aliases => "-p", :desc => "File to store pid", :default => 'tmp/pids/server.pid'
37
+ def stop
38
+ prepare :stop
39
+ require File.expand_path("../adapter", __FILE__)
40
+ Tennpipes::Cli::Adapter.stop(options)
41
+ end
42
+
43
+ private
44
+
45
+ # https://github.com/rack/rack/blob/master/lib/rack/server.rb\#L100
46
+ def server_options(options)
47
+ begin
48
+ info = []
49
+ server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
50
+ if server && server.respond_to?(:valid_options)
51
+ info << ""
52
+ info << "Server-specific options for #{server.name}:"
53
+
54
+ has_options = false
55
+ server.valid_options.each do |name, description|
56
+ next if name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # ignore handler's host and port options, we do our own.
57
+ info << " -O %-21s %s" % [name, description]
58
+ has_options = true
59
+ end
60
+ return "" if !has_options
61
+ end
62
+ info.join("\n")
63
+ rescue NameError
64
+ return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
65
+ end
66
+ end
67
+
68
+ protected
69
+
70
+ def prepare(task)
71
+ if options.help?
72
+ help(task.to_s)
73
+ exit
74
+ end
75
+ if options.environment
76
+ ENV["RACK_ENV"] = options.environment.to_s
77
+ else
78
+ ENV["RACK_ENV"] ||= 'development'
79
+ end
80
+ chdir(options.chdir)
81
+ unless File.exist?('config/boot.rb')
82
+ puts "=> Could not find boot file in: #{options.chdir}/config/boot.rb !!!"
83
+ abort
84
+ end
85
+ end
86
+
87
+ def chdir(dir)
88
+ return unless dir
89
+ begin
90
+ Dir.chdir(dir.to_s)
91
+ rescue Errno::ENOENT
92
+ puts "=> Specified Tennpipes root '#{dir}' does not appear to exist!"
93
+ rescue Errno::EACCES
94
+ puts "=> Specified Tennpipes root '#{dir}' cannot be accessed by the current user!"
95
+ end
96
+ end
97
+
98
+ def self.exit_on_failure?
99
+ true
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path('../../tasks', __FILE__)
2
+ require 'rake'
3
+ require 'rake/dsl_definition'
4
+ require 'thor'
5
+ require 'securerandom' unless defined?(SecureRandom)
6
+ begin
7
+ require 'tennpipes-init'
8
+ rescue LoadError
9
+ end
10
+
11
+ module TennpipesTasks
12
+ def self.init(init=false)
13
+ $LOAD_PATH.unshift(File.expand_path("lib"))
14
+ Tennpipes::Tasks.files.flatten.uniq.each { |rakefile| Rake.application.add_import(rakefile) rescue puts "<= Failed load #{ext}" }
15
+ load(File.expand_path('../rake_tasks.rb', __FILE__))
16
+ Rake.application.load_imports
17
+ end
18
+
19
+ def self.use(task)
20
+ tasks << task
21
+ end
22
+
23
+ def self.tasks
24
+ @tasks ||= []
25
+ end
26
+
27
+ def self.load?(task, constant_present)
28
+ if constant_present && !TennpipesTasks.tasks.include?(task)
29
+ warn <<-WARNING
30
+ Loading #{task} tasks automatically.
31
+ This functionality will be disabled in future versions. Please put
32
+
33
+ TennpipesTasks.use(#{task.inspect})
34
+ TennpipesTasks.init
35
+
36
+ and remove
37
+
38
+ require File.expand_path('../config/boot.rb', __FILE__)
39
+
40
+ in you Rakefile instead.
41
+ WARNING
42
+ end
43
+
44
+ constant_present || TennpipesTasks.tasks.include?(task)
45
+ end
46
+ end
47
+
48
+ def shell
49
+ @_shell ||= Thor::Base.shell.new
50
+ end
@@ -0,0 +1,72 @@
1
+ Dir["{lib/tasks/**,tasks/**,test,spec}/*.rake"].each do |file|
2
+ begin
3
+ load(file)
4
+ rescue LoadError => e
5
+ warn "#{file}: #{e.message}"
6
+ end
7
+ end
8
+
9
+ # Loads the Tennpipes applications mounted within the project.
10
+ # Setting up the required environment for Tennpipes.
11
+ task :environment do
12
+ require File.expand_path('config/boot.rb', Rake.application.original_dir)
13
+
14
+ Tennpipes.mounted_apps.each do |app|
15
+ app.app_obj.setup_application!
16
+ end
17
+ end
18
+
19
+ task :skeleton do
20
+ TENNPIPES_ROOT ||= Rake.application.original_dir
21
+ require 'tennpipes-base'
22
+ Tennpipes.send(:dependency_paths).reject!{ |path| path.include?('/models/') }
23
+ require File.expand_path('config/boot.rb', Rake.application.original_dir)
24
+ end
25
+
26
+ desc "Generate a secret key"
27
+ task :secret do
28
+ shell.say SecureRandom.hex(32)
29
+ end
30
+
31
+ def list_app_routes(app, args)
32
+ app_routes = app.named_routes
33
+ app_routes.reject! { |r| r.identifier.to_s !~ /#{args.query}/ } if args.query.present?
34
+ app_routes.map! { |r| [r.verb, r.name, r.path] }
35
+ return if app_routes.empty?
36
+ shell.say "\nApplication: #{app.app_class}", :yellow
37
+ app_routes.unshift(["REQUEST", "URL", "PATH"])
38
+ max_col_1 = app_routes.max { |a, b| a[0].size <=> b[0].size }[0].size
39
+ max_col_2 = app_routes.max { |a, b| a[1].size <=> b[1].size }[1].size
40
+ app_routes.each_with_index do |row, i|
41
+ message = [row[1].ljust(max_col_2+2), row[0].center(max_col_1+2), row[2]]
42
+ shell.say(" " + message.join(" "), i==0 ? :bold : nil)
43
+ end
44
+ end
45
+
46
+ def env_migration_version
47
+ version = ENV["MIGRATION_VERSION"]
48
+ if version.nil? && ENV["VERSION"]
49
+ deprecated = true
50
+ warn "Environment variable VERSION is deprecated, use MIGRATION_VERSION"
51
+ version = ENV["VERSION"]
52
+ end
53
+ version ? Integer(version) : nil
54
+ rescue ArgumentError
55
+ warn "Environment variable #{deprecated ? '' : 'MIGRATION_'}VERSION=#{version} should be non-existant or Integer"
56
+ nil
57
+ end
58
+
59
+ desc "Displays a listing of the named routes within a project, optionally only those matched by [query]"
60
+ task :routes, [:query] => :environment do |t, args|
61
+ Tennpipes.mounted_apps.each do |app|
62
+ list_app_routes(app, args)
63
+ end
64
+ end
65
+
66
+ desc "Displays a listing of the named routes a given app [app]"
67
+ namespace :routes do
68
+ task :app, [:app] => :environment do |t, args|
69
+ app = Tennpipes.mounted_apps.find { |app| app.app_class == args.app }
70
+ list_app_routes(app, args) if app
71
+ end
72
+ end