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