Merge in recent changes from v3-stable
This commit is contained in:
commit
4b53549ae4
|
@ -23,3 +23,8 @@ matrix:
|
|||
- rvm: jruby
|
||||
- rvm: jruby-19mode
|
||||
- rvm: rbx-2
|
||||
env: TEST=true
|
||||
before_install: git submodule update --init --recursive
|
||||
script: bundle exec rake test
|
||||
notifications:
|
||||
slack: middleman:JW9OvXmn1m3XrSERe8866nBR
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -16,9 +16,21 @@ master
|
|||
* Remove deprecated `request` instance
|
||||
* Remove old module-style extension support
|
||||
* Placed all `config.rb` evaluation inside the `ConfigContext` class
|
||||
* Update Padrino to 0.12.0. Introduces BREAKING CHANGE for Haml. Helpers which take blocks used to require `-` instead of `=` to work correctly. Now, all helpers which output content should use `=`. See: http://www.padrinorb.com/blog/upgrading-padrino-from-0-11-x-to-0-12-0-guide
|
||||
|
||||
3.3.0-3.3.2
|
||||
===
|
||||
|
||||
* Update Padrino to 0.12.1. Introduces BREAKING CHANGE for Haml. Helpers which take blocks used to require `-` instead of `=` to work correctly. Now, all helpers which output content should use `=`. See: http://www.padrinorb.com/blog/upgrading-padrino-from-0-11-x-to-0-12-0-guide
|
||||
* Update Haml to 4.x
|
||||
* Disable Webrick reverse DNS lookup, vastly improving performance when accessing from a VM.
|
||||
* Ignore `node_modules` in FileWatcher
|
||||
* Add `tzinfo-data` for Windows users.
|
||||
* Prefer loading layouts from `layouts_dir`
|
||||
* Add `before_build` hook.
|
||||
* Depend on Erubis and remove support for specifying another ERb engine.
|
||||
* Removed the ability to set the `sass_cache_path`.
|
||||
* Improved /__middleman/ meta pages. For example, sitemap view now calls out ignored resources, prints data/options better, and shows which special locals are available on a page.
|
||||
* Bump Uglifier to 2.5.x
|
||||
|
||||
3.2.2
|
||||
===
|
||||
|
|
|
@ -29,7 +29,6 @@ module Middleman
|
|||
|
||||
desc 'version', 'Show version'
|
||||
def version
|
||||
require 'middleman-core/version'
|
||||
say "Middleman #{Middleman::VERSION}"
|
||||
end
|
||||
|
||||
|
@ -86,6 +85,9 @@ module Middleman
|
|||
end
|
||||
end
|
||||
|
||||
# Require the Middleman version
|
||||
require 'middleman-core/version'
|
||||
|
||||
# Include the core CLI items
|
||||
require 'middleman-cli/init'
|
||||
require 'middleman-cli/extension'
|
||||
|
|
|
@ -185,9 +185,7 @@ module Middleman::Cli
|
|||
|
||||
@app.sitemap.resources.select do |resource|
|
||||
resource.ext == '.css'
|
||||
end.each do |resource|
|
||||
@rack.get(URI.escape(resource.destination_path))
|
||||
end
|
||||
end.each(&method(:build_resource))
|
||||
|
||||
logger.debug '== Checking for Compass sprites'
|
||||
|
||||
|
@ -210,8 +208,15 @@ module Middleman::Cli
|
|||
end
|
||||
|
||||
# Loop over all the paths and build them.
|
||||
resources.each do |resource|
|
||||
next if @config[:glob] && !File.fnmatch(@config[:glob], resource.destination_path)
|
||||
resources.reject do |resource|
|
||||
resource.ext == '.css'
|
||||
end.each(&method(:build_resource))
|
||||
|
||||
::Middleman::Profiling.report('build')
|
||||
end
|
||||
|
||||
def build_resource(resource)
|
||||
return if @config[:glob] && !File.fnmatch(@config[:glob], resource.destination_path)
|
||||
|
||||
output_path = render_to_file(resource)
|
||||
|
||||
|
@ -226,9 +231,6 @@ module Middleman::Cli
|
|||
end
|
||||
end
|
||||
|
||||
::Middleman::Profiling.report('build')
|
||||
end
|
||||
|
||||
# Render a resource to a file.
|
||||
#
|
||||
# @param [Middleman::Sitemap::Resource] resource
|
||||
|
|
|
@ -11,7 +11,7 @@ Feature: select_tag helper
|
|||
When I go to "/select_tag.html"
|
||||
Then I should see:
|
||||
"""
|
||||
<select name="colors"><option value="">Choose a color</option>
|
||||
<select name="colors" include_blank="Choose a color"><option value="">Choose a color</option>
|
||||
<option value="red">red</option>
|
||||
<option value="blue">blue</option>
|
||||
<option value="blorange">blorange</option>
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
if !defined?(::Padrino::Helpers)
|
||||
require 'vendored-middleman-deps/padrino-core-0.12.0/lib/padrino-core/support_lite'
|
||||
require 'vendored-middleman-deps/padrino-helpers-0.12.0/lib/padrino-helpers'
|
||||
require 'padrino-helpers'
|
||||
|
||||
# Don't fail on invalid locale, that's not what our current
|
||||
# users expect.
|
||||
::I18n.enforce_available_locales = false
|
||||
end
|
||||
# Don't fail on invalid locale, that's not what our current
|
||||
# users expect.
|
||||
::I18n.enforce_available_locales = false
|
||||
|
||||
class Padrino::Helpers::OutputHelpers::ErbHandler
|
||||
# Force Erb capture not to use safebuffer
|
||||
|
@ -65,16 +62,13 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
|
|||
end
|
||||
|
||||
def capture_html(*args, &block)
|
||||
handler = auto_find_proper_handler(&block)
|
||||
captured_block, captured_html = nil, ''
|
||||
|
||||
if handler && handler.engine_matches?(block)
|
||||
captured_html, captured_block = handler.capture_from_template(*args, &block)
|
||||
result = if handler = auto_find_proper_handler(&block)
|
||||
handler.capture_from_template(*args, &block)
|
||||
else
|
||||
block.call(*args)
|
||||
end
|
||||
|
||||
# invoking the block directly if there was no template
|
||||
captured_html = block_given? && ( captured_block || block.call(*args) ) if captured_html.blank?
|
||||
captured_html
|
||||
ActiveSupport::SafeBuffer.new.safe_concat(result)
|
||||
end
|
||||
|
||||
def auto_find_proper_handler(&block)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
.value {
|
||||
color: #002B36;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.description {
|
||||
|
@ -34,3 +35,15 @@
|
|||
.extensions .settings {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.inactive:after {
|
||||
content: "Inactive";
|
||||
font-weight: bold;
|
||||
color: #999999;
|
||||
margin-left: 10px;
|
||||
font-size: .7em;
|
||||
}
|
|
@ -168,6 +168,7 @@ body {
|
|||
padding-right: 1em;
|
||||
position: relative;
|
||||
margin-top: 2em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
.container:after {
|
||||
clear: both;
|
||||
|
@ -355,14 +356,29 @@ pre .tex .formula {
|
|||
#main {
|
||||
display: inline;
|
||||
float: left;
|
||||
font-size: 120%;
|
||||
font-size: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 1.20482%;
|
||||
width: 100%;
|
||||
}
|
||||
#main h1 {
|
||||
font-size: 2em;
|
||||
font-size: 3em;
|
||||
font-weight: bold;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
#main h2 {
|
||||
font-size: 1.5em;
|
||||
font-size: 2em;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-list a {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
}
|
|
@ -27,6 +27,7 @@ summary > i {
|
|||
|
||||
.resource-details th, .resource-details td {
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.resource-details th {
|
||||
|
@ -40,6 +41,22 @@ summary > i {
|
|||
font-family: "Arvo","andale mono","lucida console",monospace;
|
||||
}
|
||||
|
||||
.ignored > summary {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.ignored i {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.ignored > summary:after {
|
||||
content: "Ignored";
|
||||
font-weight: bold;
|
||||
color: #999999;
|
||||
margin-left: 10px;
|
||||
font-size: .7em;
|
||||
}
|
||||
|
||||
details > summary:before {
|
||||
content: "" !important;
|
||||
display: inline-block;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'pp'
|
||||
|
||||
module Middleman
|
||||
module MetaPages
|
||||
# View class for a config entry
|
||||
|
@ -13,22 +15,18 @@ module Middleman
|
|||
content = ''
|
||||
key_classes = ['key']
|
||||
key_classes << 'modified' if @setting.value_set?
|
||||
content << content_tag(:span, @setting.key.inspect, :class => key_classes.join(' '))
|
||||
content << content_tag(:span, @setting.key.pretty_inspect.strip, :class => key_classes.join(' '))
|
||||
content << ' = '
|
||||
content << content_tag(:span, @setting.value.inspect, :class => 'value')
|
||||
if @setting.default
|
||||
content << content_tag(:span, @setting.value.pretty_inspect.strip, :class => 'value')
|
||||
if @setting.default && @setting.value_set? && @setting.default != @setting.value
|
||||
content << content_tag(:span, :class => 'default') do
|
||||
if @setting.value_set?
|
||||
"Default: #{@setting.default.inspect}"
|
||||
else
|
||||
'(Default)'
|
||||
end
|
||||
"(Default: #{@setting.default.inspect})"
|
||||
end
|
||||
end
|
||||
|
||||
if @setting.description
|
||||
content << content_tag(:p, :class => 'description') do
|
||||
CGI::escapeHTML(@setting.description)
|
||||
@setting.description
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
if !defined?(::Padrino::Helpers)
|
||||
require 'vendored-middleman-deps/padrino-core-0.12.0/lib/padrino-core/support_lite'
|
||||
require 'vendored-middleman-deps/padrino-helpers-0.12.0/lib/padrino-helpers'
|
||||
end
|
||||
require 'padrino-helpers'
|
||||
|
||||
module Middleman
|
||||
module MetaPages
|
||||
|
@ -15,7 +12,9 @@ module Middleman
|
|||
end
|
||||
|
||||
def render
|
||||
content_tag :div, :class => 'resource-details' do
|
||||
classes = 'resource-details'
|
||||
classes << ' ignored' if @resource.ignored?
|
||||
content_tag :div, :class => classes do
|
||||
content_tag :table do
|
||||
content = ''
|
||||
resource_properties.each do |label, value|
|
||||
|
@ -33,24 +32,34 @@ module Middleman
|
|||
|
||||
# A hash of label to value for all the properties we want to display
|
||||
def resource_properties
|
||||
props = {
|
||||
'Path' => @resource.path,
|
||||
'Build Path' => @resource.destination_path,
|
||||
'URL' => content_tag(:a, @resource.url, :href => @resource.url),
|
||||
'Source File' => @resource.source_file,
|
||||
}
|
||||
props = {}
|
||||
props['Path'] = @resource.path
|
||||
|
||||
build_path = @resource.destination_path
|
||||
build_path = 'Not built' if ignored?
|
||||
props['Build Path'] = build_path if @resource.path != build_path
|
||||
props['URL'] = content_tag(:a, @resource.url, :href => @resource.url) unless ignored?
|
||||
props['Source File'] = @resource.source_file.sub(/^#{Regexp.escape(ENV['MM_ROOT'] + '/')}/, '')
|
||||
|
||||
data = @resource.data
|
||||
props['Data'] = data unless data.empty?
|
||||
props['Data'] = data.inspect unless data.empty?
|
||||
|
||||
options = @resource.metadata[:options]
|
||||
props['Options'] = options unless options.empty?
|
||||
meta = @resource.metadata
|
||||
options = meta[:options]
|
||||
props['Options'] = options.inspect unless options.empty?
|
||||
|
||||
locals = meta[:locals].keys
|
||||
props['Locals'] = locals.join(', ') unless locals.empty?
|
||||
|
||||
props
|
||||
end
|
||||
|
||||
def ignored?
|
||||
@resource.ignored?
|
||||
end
|
||||
|
||||
def css_classes
|
||||
['resource']
|
||||
['resource'].concat(ignored? ? ['ignored'] : [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,7 +45,11 @@ module Middleman
|
|||
end
|
||||
|
||||
def css_classes
|
||||
['tree']
|
||||
['tree'].concat(ignored? ? ['ignored'] : [])
|
||||
end
|
||||
|
||||
def ignored?
|
||||
@children.values.all?(&:ignored?)
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<a href="/__middleman/">« back</a>
|
||||
<h1>Middleman Configuration</h1>
|
||||
|
||||
<p>This page shows the current configuration of your Middleman application.</p>
|
||||
<p>This page shows the current configuration of your Middleman application. <a href="http://middlemanapp.com/advanced/configuration/">Read more about configuring Middleman.</a></p>
|
||||
|
||||
<p>
|
||||
<a href="#core">Core configuration</a>
|
||||
|
@ -48,7 +48,7 @@
|
|||
<% end %>
|
||||
|
||||
<% registered_extensions.keys.each do |ext_name| %>
|
||||
<li><span class="extension"><%= ext_name.inspect %></span> (Inactive)</li>
|
||||
<li><span class="extension inactive"><%= ext_name.inspect %></span></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</article>
|
||||
|
|
|
@ -8,14 +8,24 @@
|
|||
|
||||
<body>
|
||||
<div class="container">
|
||||
<article id="main">
|
||||
<h1>Middleman Information</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="/__middleman/sitemap/">Sitemap</a></li>
|
||||
<li><a href="/__middleman/config/">Configuration</a></li>
|
||||
<li><a href="http://middlemanapp.com">Middleman Guides</a></li>
|
||||
<ul class="nav-list">
|
||||
<li>
|
||||
<a href="/__middleman/sitemap/">Sitemap</a>
|
||||
<p>The structure of your site as understood by Middleman.</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/__middleman/config/">Configuration</a>
|
||||
<p>All available configuration options and their current values.</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://middlemanapp.com">Middleman Guides</a>
|
||||
<p>Documentation about Middleman's features.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<h1>Middleman Sitemap</h1>
|
||||
|
||||
<p>This page shows all of the pages in
|
||||
the <a href="http://middlemanapp.com/advanced/sitemap/">sitemap</a>,
|
||||
<a href="http://middlemanapp.com/advanced/sitemap/">the sitemap</a>,
|
||||
Middleman's view of your site.</p>
|
||||
|
||||
<%= sitemap_tree.render %>
|
||||
|
@ -28,4 +28,3 @@
|
|||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ module Middleman
|
|||
# @return [void]
|
||||
def start(opts={})
|
||||
@options = opts
|
||||
@host = @options[:host] || Socket.gethostname
|
||||
@host = @options[:host] || Socket.ip_address_list.find(&:ipv4_private?).ip_address
|
||||
@port = @options[:port] || DEFAULT_PORT
|
||||
|
||||
mount_instance(new_app)
|
||||
|
@ -168,7 +168,8 @@ module Middleman
|
|||
http_opts = {
|
||||
:BindAddress => host,
|
||||
:Port => port,
|
||||
:AccessLog => []
|
||||
:AccessLog => [],
|
||||
:DoNotReverseLookup => true
|
||||
}
|
||||
|
||||
if is_logging
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'sass'
|
||||
require 'compass/import-once'
|
||||
|
||||
module Middleman
|
||||
module Renderers
|
||||
|
@ -21,6 +22,8 @@ module Middleman
|
|||
# Tell Tilt to use it as well (for inline scss blocks)
|
||||
::Tilt.register 'scss', ScssPlusCSSFilenameTemplate
|
||||
::Tilt.prefer(ScssPlusCSSFilenameTemplate)
|
||||
|
||||
::Compass::ImportOnce.activate!
|
||||
end
|
||||
|
||||
alias :included :registered
|
||||
|
|
|
@ -101,7 +101,7 @@ module Middleman
|
|||
|
||||
relative_source = Pathname(source_file).relative_path_from(Pathname(app.root))
|
||||
|
||||
instrument 'render.resource', :path => relative_source do
|
||||
instrument 'render.resource', :path => relative_source, :destination_path => destination_path do
|
||||
md = metadata.dup
|
||||
opts = md[:options].deep_merge(opts)
|
||||
locs = md[:locals].deep_merge(locs)
|
||||
|
|
|
@ -3,10 +3,11 @@ MIDDLEMAN_BIN_PATH = File.join(MIDDLEMAN_ROOT_PATH, 'bin')
|
|||
ENV['PATH'] = "#{MIDDLEMAN_BIN_PATH}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
||||
|
||||
require 'aruba/cucumber'
|
||||
require 'aruba/jruby'
|
||||
require 'middleman-core/step_definitions/middleman_steps'
|
||||
require 'middleman-core/step_definitions/builder_steps'
|
||||
require 'middleman-core/step_definitions/server_steps'
|
||||
|
||||
Before do
|
||||
@aruba_timeout_seconds = 30
|
||||
@aruba_timeout_seconds = RUBY_PLATFORM == 'java' ? 120 : 60
|
||||
end
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
lib/**/*.rb
|
||||
bin/*
|
||||
-
|
||||
README.rdoc
|
||||
LICENSE.txt
|
|
@ -1,22 +0,0 @@
|
|||
## MAC OS
|
||||
.DS_Store
|
||||
|
||||
## TEXTMATE
|
||||
*.tmproj
|
||||
tmtags
|
||||
|
||||
## EMACS
|
||||
*~
|
||||
\#*
|
||||
.\#*
|
||||
|
||||
## VIM
|
||||
*.swp
|
||||
|
||||
## PROJECT::GENERAL
|
||||
coverage
|
||||
rdoc
|
||||
pkg
|
||||
|
||||
## PROJECT::SPECIFIC
|
||||
test/tmp/*
|
|
@ -1 +0,0 @@
|
|||
--title 'Padrino Core Documentation' --protected
|
|
@ -1,20 +0,0 @@
|
|||
Copyright (c) 2011 Padrino
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,294 +0,0 @@
|
|||
= Padrino (padrino-core)
|
||||
|
||||
Padrino is the godfather of Sinatra.
|
||||
|
||||
== Preface
|
||||
|
||||
Padrino is a ruby framework built upon the excellent {Sinatra Microframework}[http://www.sinatrarb.com].
|
||||
Sinatra is a DSL for creating simple web applications in Ruby with speed and minimal effort.
|
||||
This framework tries hard to make it as fun and easy as possible to code much more advanced web applications by
|
||||
building upon the Sinatra philosophies and foundation.
|
||||
|
||||
== Introduction
|
||||
|
||||
Many people love Sinatra's simplicity and lightweight but often quickly come to miss a great deal
|
||||
of functionality provided by other web frameworks such as Rails when building non-trivial applications.
|
||||
|
||||
Our goal with this framework is to match the essence of Sinatra and at the same time create a standard library
|
||||
of tools, helpers and components that will make Sinatra suitable for more complex applications.
|
||||
|
||||
Here is a brief overview of functionality provided by the Padrino framework:
|
||||
|
||||
Agnostic:: Full support for many popular testing, templating, mocking, and data storage choices.
|
||||
Generators:: Create Padrino applications, models, controllers i.e: padrino-gen project.
|
||||
Mountable:: Unlike other ruby frameworks, principally designed for mounting multiple apps.
|
||||
Routing:: Full url named routes, named params, before/after filter support.
|
||||
Tag Helpers:: View helpers such as: tag, content_tag, input_tag.
|
||||
Asset Helpers:: View helpers such as: link_to, image_tag, javascript_include_tag.
|
||||
Form Helpers:: Builder support such as: form_tag, form_for, field_set_tag, text_field.
|
||||
Text Helpers:: Useful formatting like: time_ago_in_words, js_escape_html, sanitize_html.
|
||||
Mailer:: Fast and simple delivery support for sending emails (akin to ActionMailer).
|
||||
Admin:: Builtin Admin interface (like Django)
|
||||
Logging:: Provide a unified logger that can interact with your ORM or any library.
|
||||
Reloading:: Automatically reloads server code during development.
|
||||
Localization:: Full support of I18n language localization and can auto-set user's locale.
|
||||
|
||||
Keep in mind, the user will be able to pull in these components
|
||||
{seperately into existing Sinatra applications}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra]
|
||||
or use them altogether for a comprehensive upgrade to Sinatra (a full-stack Padrino application).
|
||||
|
||||
== Installation
|
||||
|
||||
To install the padrino framework, simply grab the latest version from gemcutter:
|
||||
|
||||
$ sudo gem install padrino
|
||||
|
||||
This will install the necessary padrino gems to get you started.
|
||||
Now you are ready to use this gem to enhance your sinatra projects or to create new Padrino applications.
|
||||
|
||||
For a more detailed look at Padrino installation,
|
||||
check out the {Installation Guide}[http://www.padrinorb.com/guides/installation].
|
||||
|
||||
== Usage
|
||||
|
||||
Padrino is a framework which builds on the existing functionality and Sinatra and provides a variety of
|
||||
additional tools and helpers to build upon that foundation. This README and Padrino documentation in general will focus
|
||||
on the enhancements to the core Sinatra functionality. To use Padrino, one should be familiar with the basic
|
||||
usage of Sinatra itself.
|
||||
|
||||
Please check out the
|
||||
{Understanding Sinatra}[http://www.padrinorb.com/guides/underlying-sinatra-overview] guide
|
||||
to learn more about these fundamentals.
|
||||
|
||||
For information on how to use a specific gem in isolation within an existing Sinatra project, checkout the guide for
|
||||
{Using Padrino in Sinatra}[http://www.padrinorb.com/guides/standalone-usage-in-sinatra].
|
||||
|
||||
== Getting Started
|
||||
|
||||
Once a developer understands Sinatra, Padrino is quite easy to get comfortable with since Padrino is simply a superset
|
||||
of existing Sinatra Functionality! Best way to get started with building Padrino applications is to read following resources:
|
||||
|
||||
* {Blog Tutorial}[http://www.padrinorb.com/guides/blog-tutorial] - Step-by-step guide to building a blog application with Padrino.
|
||||
* {Quick Overview}[http://www.padrinorb.com/guides/basic-projects] - Outlines basic generation commands.
|
||||
* {Padrino Examples}[http://www.padrinorb.com/guides/examples] - List of known Padrino applications which can serve as examples.
|
||||
|
||||
== Enhanced Base Application (padrino-core)
|
||||
|
||||
Sinatra has support for classes which can be extended to create an application: <tt>Sinatra::Base</tt> and <tt>Sinatra::Application</tt>
|
||||
These classes can be extended in order to create a Sinatra web application. These classes provide support for all the basic
|
||||
functionality afforded by Sinatra.
|
||||
|
||||
Padrino has support for an enhanced base application class <tt>Padrino::Application</tt>. <tt>Padrino::Application</tt>
|
||||
expands the capabilities of Sinatra::Application and automatically provides the resulting application access to all of
|
||||
the padrino framework's functionalities.
|
||||
|
||||
=== Simple Application Definition
|
||||
|
||||
Let us first take a look at the simplest possible Padrino application:
|
||||
|
||||
# app.rb
|
||||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
require 'padrino'
|
||||
Padrino.load!
|
||||
|
||||
class SimpleApp < Padrino::Application
|
||||
get '/' do
|
||||
'Hello world'
|
||||
end
|
||||
|
||||
# and for read better we can divide with controllers
|
||||
controller '/admin' do
|
||||
get '/foo' do
|
||||
'Url is /admin/foo'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
=== Enhanced Route Definitions and Controllers
|
||||
|
||||
For a complete overview of the Padrino routing and controller system,
|
||||
check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
|
||||
|
||||
Suppose we wanted to add additional routes to our Padrino application, and we want to organize the routes
|
||||
within a more structured layout. Simply add a <tt>controllers</tt> or <tt>app/controllers</tt> folder and create a file as such:
|
||||
|
||||
# Simple Example
|
||||
SimpleApp.controllers do
|
||||
get "/test" do
|
||||
"Text to return"
|
||||
end
|
||||
end
|
||||
|
||||
You can also do more complex route alias definitions:
|
||||
|
||||
# app/controllers/example.rb
|
||||
SimpleApp.controllers :posts do
|
||||
get :index do
|
||||
...
|
||||
end
|
||||
|
||||
get :show, :with => :id do
|
||||
# url generated is '/posts/show/:id'
|
||||
# access params[:id]
|
||||
end
|
||||
end
|
||||
|
||||
as well as mapping the route aliases to an explicit url:
|
||||
|
||||
# app/controllers/example.rb
|
||||
SimpleApp.controllers do
|
||||
get :index, :map => '/index' do
|
||||
...
|
||||
end
|
||||
|
||||
get :account, :map => '/the/accounts/:name/and/:id' do
|
||||
# access params[:name] and params[:index]
|
||||
end
|
||||
end
|
||||
|
||||
and even configure the +provides+ for each route:
|
||||
|
||||
# app/controllers/example.rb
|
||||
SimpleApp.controllers :admin do
|
||||
get :show, :with => :id, :provides => :js do
|
||||
"Url is /admin/show/#{params[:id]}.#{params[:format]}"
|
||||
end
|
||||
|
||||
get :other, :with => [:id, :name], :provides => [:html, :json] do
|
||||
case content_type
|
||||
when :js then ... end
|
||||
when :json then ... end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
or auto lookup for current locale or content_type
|
||||
|
||||
# app/controllers/example.rb
|
||||
SimpleApp.controllers :admin do
|
||||
get :show, :with => :id, :provides => [:html, :js] do
|
||||
render "admin/show"
|
||||
end
|
||||
end
|
||||
|
||||
When you visit :+show+ and your I18n.locale == :ru Padrino try to look for "admin/show.ru.js.*" if nothing match that path
|
||||
they try "admin/show.ru.*" then "admin/show.js.*" if none match return "admin/show.erb" (or other engine i.e. haml)
|
||||
|
||||
For a complete overview of the routing and controller system, check out the
|
||||
{Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
|
||||
|
||||
=== Rendering
|
||||
|
||||
Unlike Sinatra, Padrino supports automatic template lookups such as:
|
||||
|
||||
# searches for 'account/index.{erb,haml,...}
|
||||
render 'account/index'
|
||||
|
||||
This render does not require any template engine to be specified and will choose the first one that is discovered.
|
||||
The existing render function works as well if an engine type should be specified:
|
||||
|
||||
# example.haml
|
||||
render :haml, 'account/index'
|
||||
|
||||
For a complete overview of the Padrino rendering system, check out the
|
||||
{Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
|
||||
|
||||
=== Layout
|
||||
|
||||
With Padrino you can (like rails do) use for your custom layout, disable it
|
||||
|
||||
class SimpleApp < Padrino::Application
|
||||
|
||||
# Disable layouts
|
||||
disable layout
|
||||
|
||||
# Use the layout located in views/layouts/custom.haml
|
||||
layout :custom
|
||||
|
||||
For a complete overview of the layout functionality,
|
||||
check out the {Routing and Controller guide}[http://www.padrinorb.com/guides/controllers].
|
||||
|
||||
=== Mounting Applications
|
||||
|
||||
Padrino applications are all automatically mountable into other Padrino projects. This means that a given Padrino
|
||||
project directory can easily mount multiple applications. This allows for better organization of complex applications,
|
||||
re-usable applications that can be applied (i.e admin, auth, blog) and even more flexibility.
|
||||
|
||||
You can think of mountable applications as a 'full-featured' merb slice or rails engine. Instead of a separate construct,
|
||||
any application can simply be packaged and mounted into another project.
|
||||
|
||||
Padrino stores application mounting information by default within <tt>config/apps.rb</tt>. This file is intended
|
||||
to keep all information regarding what applications are mounted to which uri's.
|
||||
|
||||
For a complete look at mounting applications within a Padrino project,
|
||||
check out the guide on {Mounting Applications}[http://www.padrinorb.com/guides/mounting-applications].
|
||||
|
||||
=== Auto Load Paths
|
||||
|
||||
Padrino also intelligently supports requiring useful files within your application automatically and provides
|
||||
functionality for easily splitting up your application into separate files. Padrino automatically requires <tt>config/database.rb</tt>
|
||||
as a convention for establishing database connection. Also, any files within the <tt>lib</tt> folder will be required
|
||||
automatically by Padrino.
|
||||
|
||||
For a complete overview of auto-loaded paths within Padrino,
|
||||
check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
|
||||
|
||||
=== Application Logging
|
||||
|
||||
Padrino also supports robust logging capabilities. By default, logging information will
|
||||
go to the STDOUT in development (for use in a console) and in an environment-specific log file <tt>log/development.log</tt>
|
||||
in test and production environments.
|
||||
|
||||
To use the logger within a Padrino application, simply refer to the <tt>logger</tt> method accessible
|
||||
within your app and any controller or views:
|
||||
|
||||
# controllers/example.rb
|
||||
SimpleApp.controllers do
|
||||
get("/test") { logger.info "This is a test" }
|
||||
end
|
||||
|
||||
For a complete overview of Padrino logger functionality, check out the
|
||||
{Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
|
||||
|
||||
=== Development Reloader
|
||||
|
||||
Padrino applications also have the enabled ability to automatically reload all changing application files without
|
||||
the need to restart the server. Through the use of a customized Rack middleware, all files on the 'load path'
|
||||
are monitored and reloaded whenever changes are applied.
|
||||
|
||||
This makes rapid development much easier and provides a better alternative to 'shotgun' or 'rerun'
|
||||
which requires the application server to be restarted which makes requests take much longer to complete.
|
||||
|
||||
For a complete overview of code reloading in development,
|
||||
check out the {Padrino Development Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
|
||||
|
||||
=== Terminal Commands
|
||||
|
||||
Padrino also comes equipped with multiple useful terminal commands which can be activated to perform
|
||||
common tasks such as starting / stopping the application, executing the unit tests or activating an irb session.
|
||||
|
||||
The following commands are available:
|
||||
|
||||
# starts the app server (non-daemonized)
|
||||
$ padrino start
|
||||
# starts the app server (daemonized) with given port, environment and adapter
|
||||
$ padrino start -d -p 3000 -e development -a thin
|
||||
|
||||
# Stops a daemonized app server
|
||||
$ padrino stop
|
||||
|
||||
# Bootup the Padrino console (irb)
|
||||
$ padrino console
|
||||
|
||||
# Run/List tasks
|
||||
$ padrino rake
|
||||
|
||||
You can also create custom rake tasks as well. Using these commands can simplify common tasks
|
||||
making development that much smoother.
|
||||
|
||||
For a complete overview of Padrino terminal commands, check out the
|
||||
{Padrino Commands Guide}[http://www.padrinorb.com/guides/development-and-terminal-commands].
|
||||
|
||||
== Copyright
|
||||
|
||||
Copyright (c) 2011-2013 Padrino. See LICENSE for details.
|
|
@ -1,5 +0,0 @@
|
|||
# coding:utf-8
|
||||
RAKE_ROOT = __FILE__
|
||||
|
||||
require 'rubygems'
|
||||
require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper')
|
|
@ -1,9 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
require 'rubygems' unless defined?(Gem)
|
||||
require 'bundler/setup' if %w(Gemfile .components).all? { |f| File.exist?(f) }
|
||||
|
||||
padrino_core_path = File.expand_path('../../lib', __FILE__)
|
||||
$:.unshift(padrino_core_path) if File.directory?(padrino_core_path) && !$:.include?(padrino_core_path)
|
||||
|
||||
require 'padrino-core/cli/base'
|
||||
Padrino::Cli::Base.start(ARGV)
|
|
@ -1,196 +0,0 @@
|
|||
require 'sinatra/base'
|
||||
require 'padrino-core/version'
|
||||
require 'padrino-core/support_lite'
|
||||
require 'padrino-core/application'
|
||||
|
||||
require 'padrino-core/caller'
|
||||
require 'padrino-core/command'
|
||||
require 'padrino-core/loader'
|
||||
require 'padrino-core/logger'
|
||||
require 'padrino-core/mounter'
|
||||
require 'padrino-core/reloader'
|
||||
require 'padrino-core/router'
|
||||
require 'padrino-core/server'
|
||||
require 'padrino-core/tasks'
|
||||
require 'padrino-core/module'
|
||||
|
||||
if ENV["PADRINO_ENV"]
|
||||
warn 'Environment variable PADRINO_ENV is deprecated. Please, use RACK_ENV.'
|
||||
ENV["RACK_ENV"] ||= ENV["PADRINO_ENV"]
|
||||
end
|
||||
RACK_ENV = ENV["RACK_ENV"] ||= "development" unless defined?(RACK_ENV)
|
||||
PADRINO_ROOT = ENV["PADRINO_ROOT"] ||= File.dirname(Padrino.first_caller) unless defined?(PADRINO_ROOT)
|
||||
|
||||
module Padrino
|
||||
class ApplicationLoadError < RuntimeError # @private
|
||||
end
|
||||
|
||||
extend Loader
|
||||
|
||||
class << self
|
||||
##
|
||||
# Helper method for file references.
|
||||
#
|
||||
# @param [Array<String>] args
|
||||
# The directories to join to {PADRINO_ROOT}.
|
||||
#
|
||||
# @return [String]
|
||||
# The absolute path.
|
||||
#
|
||||
# @example
|
||||
# # Referencing a file in config called settings.yml
|
||||
# Padrino.root("config", "settings.yml")
|
||||
# # returns PADRINO_ROOT + "/config/setting.yml"
|
||||
#
|
||||
def root(*args)
|
||||
File.expand_path(File.join(PADRINO_ROOT, *args))
|
||||
end
|
||||
|
||||
##
|
||||
# Helper method that return {RACK_ENV}.
|
||||
#
|
||||
# @return [Symbol]
|
||||
# The Padrino Environment.
|
||||
#
|
||||
def env
|
||||
@_env ||= RACK_ENV.to_s.downcase.to_sym
|
||||
end
|
||||
|
||||
##
|
||||
# The resulting rack builder mapping each 'mounted' application.
|
||||
#
|
||||
# @return [Padrino::Router]
|
||||
# The router for the application.
|
||||
#
|
||||
# @raise [ApplicationLoadError]
|
||||
# No applications were mounted.
|
||||
#
|
||||
def application
|
||||
raise ApplicationLoadError, "At least one app must be mounted!" unless Padrino.mounted_apps.present?
|
||||
router = Padrino::Router.new
|
||||
Padrino.mounted_apps.each { |app| app.map_onto(router) }
|
||||
middleware.present? ? add_middleware(router) : router
|
||||
end
|
||||
|
||||
##
|
||||
# Configure Global Project Settings for mounted apps. These can be overloaded
|
||||
# in each individual app's own personal configuration. This can be used like:
|
||||
#
|
||||
# @yield []
|
||||
# The given block will be called to configure each application.
|
||||
#
|
||||
# @example
|
||||
# Padrino.configure_apps do
|
||||
# enable :sessions
|
||||
# disable :raise_errors
|
||||
# end
|
||||
#
|
||||
def configure_apps(&block)
|
||||
return unless block_given?
|
||||
global_configurations << block
|
||||
end
|
||||
|
||||
##
|
||||
# Stores global configuration blocks.
|
||||
#
|
||||
def global_configurations
|
||||
@_global_configurations ||= []
|
||||
end
|
||||
|
||||
##
|
||||
# Set +Encoding.default_internal+ and +Encoding.default_external+
|
||||
# to +Encoding::UFT_8+.
|
||||
#
|
||||
# Please note that in +1.9.2+ with some template engines like +haml+
|
||||
# you should turn off Encoding.default_internal to prevent problems.
|
||||
#
|
||||
# @see https://github.com/rtomayko/tilt/issues/75
|
||||
#
|
||||
# @return [NilClass]
|
||||
#
|
||||
def set_encoding
|
||||
Encoding.default_external = Encoding::UTF_8
|
||||
Encoding.default_internal = Encoding::UTF_8
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Creates Rack stack with the router added to the middleware chain.
|
||||
#
|
||||
def add_middleware(router)
|
||||
builder = Rack::Builder.new
|
||||
middleware.each{ |mw,args,block| builder.use(mw, *args, &block) }
|
||||
builder.run(router)
|
||||
builder.to_app
|
||||
end
|
||||
|
||||
##
|
||||
# A Rack::Builder object that allows to add middlewares in front of all
|
||||
# Padrino applications.
|
||||
#
|
||||
# @return [Array<Array<Class, Array, Proc>>]
|
||||
# The middleware classes.
|
||||
#
|
||||
def middleware
|
||||
@middleware ||= []
|
||||
end
|
||||
|
||||
##
|
||||
# Clears all previously configured middlewares.
|
||||
#
|
||||
# @return [Array]
|
||||
# An empty array
|
||||
#
|
||||
def clear_middleware!
|
||||
@middleware = []
|
||||
end
|
||||
|
||||
##
|
||||
# Convenience method for adding a Middleware to the whole padrino app.
|
||||
#
|
||||
# @param [Class] m
|
||||
# The middleware class.
|
||||
#
|
||||
# @param [Array] args
|
||||
# The arguments for the middleware.
|
||||
#
|
||||
# @yield []
|
||||
# The given block will be passed to the initialized middleware.
|
||||
#
|
||||
def use(mw, *args, &block)
|
||||
middleware << [mw, args, block]
|
||||
end
|
||||
|
||||
##
|
||||
# Registers a gem with padrino. This relieves the caller from setting up
|
||||
# loadpaths by itself and enables Padrino to look up apps in gem folder.
|
||||
#
|
||||
# The name given has to be the proper gem name as given in the gemspec.
|
||||
#
|
||||
# @param [String] name
|
||||
# The name of the gem being registered.
|
||||
#
|
||||
# @param [Module] main_module
|
||||
# The main module of the gem.
|
||||
#
|
||||
# @returns The root path of the loaded gem
|
||||
def gem(name, main_module)
|
||||
_, spec = Gem.loaded_specs.find{|spec_pair| spec_pair[0] == name }
|
||||
gems << spec
|
||||
modules << main_module
|
||||
spec.full_gem_path
|
||||
end
|
||||
|
||||
##
|
||||
# @returns [Gem::Specification]
|
||||
def gems
|
||||
@gems ||= []
|
||||
end
|
||||
|
||||
##
|
||||
# @returns [<Padrino::Module>]
|
||||
def modules
|
||||
@modules ||= []
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,388 +0,0 @@
|
|||
require 'padrino-core/application/flash'
|
||||
require 'padrino-core/application/rendering'
|
||||
require 'padrino-core/application/routing'
|
||||
require 'padrino-core/application/show_exceptions'
|
||||
require 'padrino-core/application/authenticity_token'
|
||||
|
||||
module Padrino
|
||||
##
|
||||
# Subclasses of this become independent Padrino applications
|
||||
# (stemming from Sinatra::Application).
|
||||
# These subclassed applications can be easily mounted into other
|
||||
# Padrino applications as well.
|
||||
#
|
||||
class Application < Sinatra::Base
|
||||
# Support for advanced routing, controllers, url_for
|
||||
register Padrino::Routing
|
||||
|
||||
##
|
||||
# Returns the logger for this application.
|
||||
#
|
||||
# @return [Padrino::Logger] Logger associated with this app.
|
||||
#
|
||||
def logger
|
||||
Padrino.logger
|
||||
end
|
||||
|
||||
# TODO: Remove this hack after getting rid of thread-unsafe http_router:
|
||||
alias_method :original_call, :call
|
||||
def call(*args)
|
||||
settings.init_mutex.synchronize do
|
||||
instance_eval{ undef :call }
|
||||
class_eval{ alias_method :call, :original_call }
|
||||
instance_eval{ undef :original_call }
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def inherited(base)
|
||||
begun_at = Time.now
|
||||
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
||||
base.default_configuration!
|
||||
logger.devel :setup, begun_at, base
|
||||
super(base)
|
||||
end
|
||||
|
||||
##
|
||||
# Reloads the application files from all defined load paths.
|
||||
#
|
||||
# This method is used from our Padrino Reloader during development mode
|
||||
# in order to reload the source files.
|
||||
#
|
||||
# @return [TrueClass]
|
||||
#
|
||||
# @example
|
||||
# MyApp.reload!
|
||||
#
|
||||
def reload!
|
||||
logger.devel "Reloading application #{settings}"
|
||||
reset!
|
||||
reset_router!
|
||||
Padrino.require_dependencies(settings.app_file, :force => true)
|
||||
require_dependencies
|
||||
default_filters!
|
||||
default_routes!
|
||||
default_errors!
|
||||
I18n.reload! if defined?(I18n)
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Resets application routes to only routes not defined by the user.
|
||||
#
|
||||
# @return [TrueClass]
|
||||
#
|
||||
# @example
|
||||
# MyApp.reset_routes!
|
||||
#
|
||||
def reset_routes!
|
||||
reset_router!
|
||||
default_routes!
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the routes of our app.
|
||||
#
|
||||
# @example
|
||||
# MyApp.routes
|
||||
#
|
||||
def routes
|
||||
router.routes
|
||||
end
|
||||
|
||||
##
|
||||
# Returns an absolute path of view in application views folder.
|
||||
#
|
||||
# @example
|
||||
# Admin.view_path 'users/index' #=> "/home/user/test/admin/views/users/index"
|
||||
#
|
||||
def view_path(view)
|
||||
File.expand_path(view, views)
|
||||
end
|
||||
|
||||
##
|
||||
# Returns an absolute path of application layout.
|
||||
#
|
||||
# @example
|
||||
# Admin.layout_path :application #=> "/home/user/test/admin/views/layouts/application"
|
||||
#
|
||||
def layout_path(layout)
|
||||
view_path("layouts/#{layout}")
|
||||
end
|
||||
|
||||
##
|
||||
# Setup the application by registering initializers, load paths and logger.
|
||||
# Invoked automatically when an application is first instantiated.
|
||||
#
|
||||
# @return [TrueClass]
|
||||
#
|
||||
def setup_application!
|
||||
return if @_configured
|
||||
settings.require_dependencies
|
||||
settings.default_filters!
|
||||
settings.default_routes!
|
||||
settings.default_errors!
|
||||
if defined?(I18n)
|
||||
Reloader.special_files += settings.locale_path
|
||||
I18n.load_path << settings.locale_path
|
||||
I18n.reload!
|
||||
end
|
||||
@_configured = true
|
||||
end
|
||||
|
||||
##
|
||||
# Run the Padrino app as a self-hosted server using
|
||||
# Thin, Mongrel or WEBrick (in that order).
|
||||
#
|
||||
# @see Padrino::Server#start
|
||||
#
|
||||
def run!(options={})
|
||||
return unless Padrino.load!
|
||||
Padrino.mount(settings.to_s).to('/')
|
||||
Padrino.run!(options)
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Array]
|
||||
# directory that need to be added to +$LOAD_PATHS+ from this application
|
||||
#
|
||||
def load_paths
|
||||
@_load_paths ||= [
|
||||
'models',
|
||||
'lib',
|
||||
'mailers',
|
||||
'controllers',
|
||||
'helpers',
|
||||
].map { |path| File.join(settings.root, path) }
|
||||
end
|
||||
|
||||
##
|
||||
# Returns default list of path globs to load as dependencies.
|
||||
# Appends custom dependency patterns to the be loaded for your Application.
|
||||
#
|
||||
# @return [Array]
|
||||
# list of path globs to load as dependencies
|
||||
#
|
||||
# @example
|
||||
# MyApp.dependencies << "#{Padrino.root}/uploaders/**/*.rb"
|
||||
# MyApp.dependencies << Padrino.root('other_app', 'controllers.rb')
|
||||
#
|
||||
def dependencies
|
||||
[
|
||||
'urls.rb',
|
||||
'config/urls.rb',
|
||||
'mailers/*.rb',
|
||||
'mailers.rb',
|
||||
'controllers/**/*.rb',
|
||||
'controllers.rb',
|
||||
'helpers/**/*.rb',
|
||||
'helpers.rb',
|
||||
].map { |file| Dir[File.join(settings.root, file)] }.flatten
|
||||
end
|
||||
|
||||
##
|
||||
# An array of file to load before your app.rb, basically are files
|
||||
# which our app depends on.
|
||||
#
|
||||
# By default we look for files:
|
||||
#
|
||||
# # List of default files that we are looking for:
|
||||
# yourapp/models.rb
|
||||
# yourapp/models/**/*.rb
|
||||
# yourapp/lib.rb
|
||||
# yourapp/lib/**/*.rb
|
||||
#
|
||||
# @example Adding a custom prerequisite
|
||||
# MyApp.prerequisites << Padrino.root('my_app', 'custom_model.rb')
|
||||
#
|
||||
def prerequisites
|
||||
@_prerequisites ||= []
|
||||
end
|
||||
|
||||
def default(option, *args, &block)
|
||||
set(option, *args, &block) unless respond_to?(option)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
##
|
||||
# Defines default settings for Padrino application.
|
||||
#
|
||||
def default_configuration!
|
||||
set :app_file, File.expand_path(caller_files.first || $0)
|
||||
set :app_name, settings.to_s.underscore.to_sym
|
||||
|
||||
set :environment, Padrino.env
|
||||
set :reload, Proc.new { development? }
|
||||
set :logging, Proc.new { development? }
|
||||
|
||||
set :method_override, true
|
||||
set :default_builder, 'StandardFormBuilder'
|
||||
|
||||
# TODO: Remove this hack after getting rid of thread-unsafe http_router:
|
||||
set :init_mutex, Mutex.new
|
||||
|
||||
# TODO: Remove this line after sinatra version up.
|
||||
set :add_charset, %w[javascript xml xhtml+xml].map {|t| "application/#{t}" }
|
||||
|
||||
default_paths!
|
||||
default_security!
|
||||
global_configuration!
|
||||
setup_prerequisites!
|
||||
end
|
||||
|
||||
def setup_prerequisites!
|
||||
prerequisites.concat(default_prerequisites).uniq!
|
||||
Padrino.require_dependencies(prerequisites)
|
||||
end
|
||||
|
||||
def default_paths!
|
||||
set :locale_path, Proc.new { Dir.glob File.join(root, 'locale/**/*.{rb,yml}') }
|
||||
set :views, Proc.new { File.join(root, 'views') }
|
||||
|
||||
set :uri_root, '/'
|
||||
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
||||
set :images_path, Proc.new { File.join(public_folder, 'images') }
|
||||
end
|
||||
|
||||
def default_security!
|
||||
set :protection, :except => :path_traversal
|
||||
set :authentication, false
|
||||
set :sessions, false
|
||||
set :protect_from_csrf, false
|
||||
set :allow_disabled_csrf, false
|
||||
end
|
||||
|
||||
##
|
||||
# Applies global padrino configuration blocks to current application.
|
||||
#
|
||||
def global_configuration!
|
||||
Padrino.global_configurations.each do |configuration|
|
||||
class_eval(&configuration)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# We need to add almost __sinatra__ images.
|
||||
#
|
||||
def default_routes!
|
||||
configure :development do
|
||||
get '*__sinatra__/:image.png' do
|
||||
content_type :png
|
||||
filename = File.dirname(__FILE__) + "/images/#{params[:image]}.png"
|
||||
send_file filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This filter it's used for know the format of the request, and
|
||||
# automatically set the content type.
|
||||
#
|
||||
def default_filters!
|
||||
before do
|
||||
response['Content-Type'] = 'text/html;charset=utf-8' unless @_content_type
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# This log errors for production environments.
|
||||
#
|
||||
def default_errors!
|
||||
configure :production do
|
||||
error ::Exception do
|
||||
boom = env['sinatra.error']
|
||||
logger.error ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ")
|
||||
response.status = 500
|
||||
content_type 'text/html'
|
||||
'<h1>Internal Server Error</h1>'
|
||||
end unless errors.has_key?(::Exception)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Requires all files within the application load paths.
|
||||
#
|
||||
def require_dependencies
|
||||
Padrino.set_load_paths(*load_paths)
|
||||
Padrino.require_dependencies(dependencies, :force => true)
|
||||
end
|
||||
|
||||
##
|
||||
# Returns globs of default paths of application prerequisites.
|
||||
#
|
||||
def default_prerequisites
|
||||
[
|
||||
'/models.rb',
|
||||
'/models/**/*.rb',
|
||||
'/lib.rb',
|
||||
'/lib/**/*.rb',
|
||||
].map{ |glob| File.join(settings.root, glob) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Overrides the default middleware for Sinatra based on Padrino conventions.
|
||||
# Also initializes the application after setting up the middleware.
|
||||
def setup_default_middleware(builder)
|
||||
setup_sessions builder
|
||||
builder.use Padrino::ShowExceptions if show_exceptions?
|
||||
builder.use Padrino::Logger::Rack, uri_root if Padrino.logger && logging?
|
||||
builder.use Padrino::Reloader::Rack if reload?
|
||||
builder.use Rack::MethodOverride if method_override?
|
||||
builder.use Rack::Head
|
||||
register Padrino::Flash
|
||||
setup_protection builder
|
||||
setup_csrf_protection builder
|
||||
setup_application!
|
||||
end
|
||||
|
||||
# sets up csrf protection for the app:
|
||||
def setup_csrf_protection(builder)
|
||||
check_csrf_protection_dependency
|
||||
|
||||
if protect_from_csrf?
|
||||
options = options_for_csrf_protection_setup
|
||||
options.merge!(protect_from_csrf) if protect_from_csrf.kind_of?(Hash)
|
||||
builder.use(options[:except] ? Padrino::AuthenticityToken : Rack::Protection::AuthenticityToken, options)
|
||||
end
|
||||
end
|
||||
|
||||
# returns the options used in the builder for csrf protection setup
|
||||
def options_for_csrf_protection_setup
|
||||
options = { :logger => logger }
|
||||
|
||||
if allow_disabled_csrf?
|
||||
options.merge!({
|
||||
:reaction => :report,
|
||||
:report_key => 'protection.csrf.failed'
|
||||
})
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
# throw an exception if the protect_from_csrf is active but sessions not.
|
||||
def check_csrf_protection_dependency
|
||||
if (protect_from_csrf? && !sessions?) && !defined?(Padrino::IGNORE_CSRF_SETUP_WARNING)
|
||||
warn(<<-ERROR)
|
||||
`protect_from_csrf` is activated, but `sessions` seem to be off. To enable csrf
|
||||
protection, use:
|
||||
|
||||
enable :sessions
|
||||
|
||||
or deactivate protect_from_csrf:
|
||||
|
||||
disable :protect_from_csrf
|
||||
|
||||
If you use a different session store, ignore this warning using:
|
||||
|
||||
# in boot.rb:
|
||||
Padrino::IGNORE_CSRF_SETUP_WARNING = true
|
||||
ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
module Padrino
|
||||
class AuthenticityToken < Rack::Protection::AuthenticityToken
|
||||
def initialize(app, options = {})
|
||||
@app = app
|
||||
@except = options[:except]
|
||||
@except = Array(@except) unless @except.is_a?(Proc)
|
||||
super
|
||||
end
|
||||
|
||||
def call(env)
|
||||
if except?(env)
|
||||
@app.call(env)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def except?(env)
|
||||
return false unless @except
|
||||
path_info = env['PATH_INFO']
|
||||
@except.is_a?(Proc) ? @except.call(env) : @except.any?{|path|
|
||||
path.is_a?(Regexp) ? path.match(path_info) : path == path_info }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,229 +0,0 @@
|
|||
module Padrino
|
||||
module Flash
|
||||
|
||||
class << self
|
||||
def registered(app)
|
||||
app.helpers Helpers
|
||||
app.after do
|
||||
session[:_flash] = @_flash.next if @_flash
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Storage
|
||||
include Enumerable
|
||||
|
||||
# @private
|
||||
def initialize(session=nil)
|
||||
@_now = session || {}
|
||||
@_next = {}
|
||||
end
|
||||
|
||||
def now
|
||||
@_now
|
||||
end
|
||||
|
||||
def next
|
||||
@_next
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def [](type)
|
||||
@_now[type]
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def []=(type, message)
|
||||
@_next[type] = message
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def delete(type)
|
||||
@_now.delete(type)
|
||||
self
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def keys
|
||||
@_now.keys
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def key?(type)
|
||||
@_now.key?(type)
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def each(&block)
|
||||
@_now.each(&block)
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def replace(hash)
|
||||
@_now.replace(hash)
|
||||
self
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def update(hash)
|
||||
@_now.update(hash)
|
||||
self
|
||||
end
|
||||
alias_method :merge!, :update
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def sweep
|
||||
@_now.replace(@_next)
|
||||
@_next = {}
|
||||
self
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def keep(key = nil)
|
||||
if key
|
||||
@_next[key] = @_now[key]
|
||||
else
|
||||
@_next.merge!(@_now)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def discard(key = nil)
|
||||
if key
|
||||
@_next.delete(key)
|
||||
else
|
||||
@_next = {}
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def clear
|
||||
@_now.clear
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def empty?
|
||||
@_now.empty?
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def to_hash
|
||||
@_now.dup
|
||||
end
|
||||
|
||||
def length
|
||||
@_now.length
|
||||
end
|
||||
alias_method :size, :length
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def to_s
|
||||
@_now.to_s
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def error=(message)
|
||||
self[:error] = message
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def error
|
||||
self[:error]
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def notice=(message)
|
||||
self[:notice] = message
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def notice
|
||||
self[:notice]
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def success=(message)
|
||||
self[:success] = message
|
||||
end
|
||||
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def success
|
||||
self[:success]
|
||||
end
|
||||
end # Storage
|
||||
|
||||
module Helpers
|
||||
###
|
||||
# Overloads the existing redirect helper in-order to provide support for
|
||||
# flash messages.
|
||||
#
|
||||
# @overload redirect(url)
|
||||
# @param [String] url
|
||||
#
|
||||
# @overload redirect(url, status_code)
|
||||
# @param [String] url
|
||||
# @param [Fixnum] status_code
|
||||
#
|
||||
# @overload redirect(url, status_code, flash_messages)
|
||||
# @param [String] url
|
||||
# @param [Fixnum] status_code
|
||||
# @param [Hash] flash_messages
|
||||
#
|
||||
# @overload redirect(url, flash_messages)
|
||||
# @param [String] url
|
||||
# @param [Hash] flash_messages
|
||||
#
|
||||
# @example
|
||||
# redirect(dashboard, success: :user_created)
|
||||
# redirect(new_location, 301, notice: 'This page has moved. Please update your bookmarks!!')
|
||||
#
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def redirect(url, *args)
|
||||
flashes = args.extract_options!
|
||||
|
||||
flashes.each do |type, message|
|
||||
message = I18n.translate(message) if message.is_a?(Symbol) && defined?(I18n)
|
||||
flash[type] = message
|
||||
end
|
||||
|
||||
super(url, args)
|
||||
end
|
||||
alias_method :redirect_to, :redirect
|
||||
|
||||
###
|
||||
# Returns the flash storage object.
|
||||
#
|
||||
# @return [Storage]
|
||||
#
|
||||
# @since 0.10.8
|
||||
# @api public
|
||||
def flash
|
||||
@_flash ||= Storage.new(env['rack.session'] ? session[:_flash] : {})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,325 +0,0 @@
|
|||
require 'padrino-core/support_lite' unless defined?(SupportLite)
|
||||
|
||||
module Padrino
|
||||
##
|
||||
# Padrino enhances the Sinatra 'render' method to have support for
|
||||
# automatic template engine detection, enhanced layout functionality,
|
||||
# locale enabled rendering, among other features.
|
||||
#
|
||||
module Rendering
|
||||
##
|
||||
# A SafeTemplate assumes that its output is safe.
|
||||
#
|
||||
module SafeTemplate
|
||||
def render(*)
|
||||
super.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Exception responsible for when an expected template did not exist.
|
||||
#
|
||||
class TemplateNotFound < RuntimeError
|
||||
end
|
||||
|
||||
##
|
||||
# This is an array of file patterns to ignore. If your editor add a
|
||||
# suffix during editing to your files please add it like:
|
||||
#
|
||||
# @example
|
||||
# Padrino::Rendering::IGNORE_FILE_PATTERN << /~$/
|
||||
#
|
||||
IGNORE_FILE_PATTERN = [
|
||||
/~$/ # This is for Gedit
|
||||
] unless defined?(IGNORE_FILE_PATTERN)
|
||||
|
||||
##
|
||||
# Default options used in the resolve_template-method.
|
||||
#
|
||||
DEFAULT_RENDERING_OPTIONS = { :strict_format => false, :raise_exceptions => true } unless defined?(DEFAULT_RENDERING_OPTIONS)
|
||||
|
||||
class << self
|
||||
##
|
||||
# Default engine configurations for Padrino::Rendering.
|
||||
#
|
||||
# @return {Hash<Symbol,Hash>}
|
||||
# The configurations, keyed by engine.
|
||||
def engine_configurations
|
||||
@engine_configurations ||= {}
|
||||
end
|
||||
|
||||
def registered(app)
|
||||
included(app)
|
||||
engine_configurations.each do |engine, configs|
|
||||
app.set engine, configs
|
||||
end
|
||||
end
|
||||
|
||||
def included(base)
|
||||
base.send(:include, InstanceMethods)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Class methods responsible for rendering templates as part of a request.
|
||||
#
|
||||
module ClassMethods
|
||||
##
|
||||
# Use layout like rails does or if a block given then like sinatra.
|
||||
# If used without a block, sets the current layout for the route.
|
||||
#
|
||||
# By default, searches in your:
|
||||
#
|
||||
# +app+/+views+/+layouts+/+application+.(+haml+|+erb+|+xxx+)
|
||||
# +app+/+views+/+layout_name+.(+haml+|+erb+|+xxx+)
|
||||
#
|
||||
# If you define +layout+ :+custom+ then searches for your layouts in
|
||||
# +app+/+views+/+layouts+/+custom+.(+haml+|+erb+|+xxx+)
|
||||
# +app+/+views+/+custom+.(+haml+|+erb+|+xxx+)
|
||||
#
|
||||
# @param [Symbol] name (:layout)
|
||||
# The layout to use.
|
||||
#
|
||||
# @yield []
|
||||
#
|
||||
def layout(name=:layout, &block)
|
||||
return super(name, &block) if block_given?
|
||||
@layout = name
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the cached template file to render for a given url,
|
||||
# content_type and locale.
|
||||
#
|
||||
# @param [Array<template_path, content_type, locale>] render_options
|
||||
#
|
||||
def fetch_template_file(render_options)
|
||||
(@_cached_templates ||= {})[render_options]
|
||||
end
|
||||
|
||||
##
|
||||
# Caches the template file for the given rendering options.
|
||||
#
|
||||
# @param [String] template_file
|
||||
# The path of the template file.
|
||||
#
|
||||
# @param [Array<template_path, content_type, locale>] render_options
|
||||
#
|
||||
def cache_template_file!(template_file, render_options)
|
||||
(@_cached_templates ||= {})[render_options] = template_file || []
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the cached layout path.
|
||||
#
|
||||
# @param [Symbol, nil] given_layout
|
||||
# The requested layout.
|
||||
#
|
||||
def fetch_layout_path(given_layout=nil)
|
||||
layout_name = given_layout || @layout || :application
|
||||
@_cached_layout ||= {}
|
||||
cached_layout_path = @_cached_layout[layout_name]
|
||||
return cached_layout_path if cached_layout_path
|
||||
has_layout_at_root = Dir["#{views}/#{layout_name}.*"].any?
|
||||
layout_path = has_layout_at_root ? layout_name.to_sym : File.join('layouts', layout_name.to_s).to_sym
|
||||
@_cached_layout[layout_name] = layout_path unless reload_templates?
|
||||
layout_path
|
||||
end
|
||||
end
|
||||
|
||||
# Instance methods that allow enhanced rendering to function properly in Padrino.
|
||||
module InstanceMethods
|
||||
attr_reader :current_engine
|
||||
|
||||
##
|
||||
# Get/Set the content_type
|
||||
#
|
||||
# @param [String, nil] type
|
||||
# The Content-Type to use.
|
||||
#
|
||||
# @param [Symbol, nil] type.
|
||||
# Look and parse the given symbol to the matched Content-Type.
|
||||
#
|
||||
# @param [Hash] params
|
||||
# Additional params to append to the Content-Type.
|
||||
#
|
||||
# @example
|
||||
# case content_type
|
||||
# when :js then do_some
|
||||
# when :css then do_another
|
||||
# end
|
||||
#
|
||||
# content_type :js
|
||||
# # => set the response with 'application/javascript' Content-Type
|
||||
# content_type 'text/html'
|
||||
#
|
||||
# # => set directly the Content-Type to 'text/html'
|
||||
#
|
||||
def content_type(type=nil, params={})
|
||||
unless type.nil?
|
||||
super(type, params)
|
||||
@_content_type = type
|
||||
end
|
||||
@_content_type
|
||||
end
|
||||
|
||||
private
|
||||
##
|
||||
# Enhancing Sinatra render functionality for:
|
||||
#
|
||||
# * Using layout similar to rails
|
||||
# * Use render 'path/to/my/template' (without symbols)
|
||||
# * Use render 'path/to/my/template' (with engine lookup)
|
||||
# * Use render 'path/to/template.haml' (with explicit engine lookup)
|
||||
# * Use render 'path/to/template', :layout => false
|
||||
# * Use render 'path/to/template', :layout => false, :engine => 'haml'
|
||||
#
|
||||
def render(engine, data=nil, options={}, locals={}, &block)
|
||||
|
||||
# If engine is nil, ignore engine parameter and shift up all arguments
|
||||
# render nil, "index", { :layout => true }, { :localvar => "foo" }
|
||||
engine, data, options = data, options, locals if engine.nil? && data
|
||||
|
||||
# Data is a hash of options when no engine isn't explicit
|
||||
# render "index", { :layout => true }, { :localvar => "foo" }
|
||||
# Data is options, and options is locals in this case
|
||||
data, options, locals = nil, data, options if data.is_a?(Hash)
|
||||
|
||||
# If data is unassigned then this is a likely a template to be resolved
|
||||
# This means that no engine was explicitly defined
|
||||
data, engine = *resolve_template(engine, options.dup) if data.nil?
|
||||
|
||||
# Use @layout if it exists
|
||||
layout_was = options[:layout]
|
||||
options[:layout] = @layout if options[:layout].nil? || options[:layout] == true
|
||||
# Resolve layouts similar to in Rails
|
||||
if options[:layout].nil? && !settings.templates.has_key?(:layout)
|
||||
layout_path = settings.fetch_layout_path(options[:layout])
|
||||
is_included_extension = %w[.slim .erb .haml].include?(File.extname(layout_path.to_s))
|
||||
layout_path, layout_engine = *(is_included_extension ? resolve_template(layout_path) : resolved_layout)
|
||||
|
||||
# We need to force layout false so sinatra don't try to render it
|
||||
options[:layout] = layout_path || false
|
||||
options[:layout] = false unless is_included_extension ? layout_engine : layout_engine == engine
|
||||
options[:layout_engine] = layout_engine || engine if options[:layout]
|
||||
elsif options[:layout].present?
|
||||
options[:layout], options[:layout_engine] = *resolve_template(settings.fetch_layout_path(options[:layout]), options)
|
||||
end
|
||||
# Default to original layout value if none found.
|
||||
options[:layout] ||= layout_was
|
||||
|
||||
# Cleanup the template.
|
||||
@current_engine, engine_was = engine, @current_engine
|
||||
@_out_buf, _buf_was = ActiveSupport::SafeBuffer.new, @_out_buf
|
||||
|
||||
# Pass arguments to Sinatra render method.
|
||||
super(engine, data, options.dup, locals, &block)
|
||||
ensure
|
||||
@current_engine = engine_was
|
||||
@_out_buf = _buf_was
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the located layout tuple to be used for the rendered template
|
||||
# (if available).
|
||||
#
|
||||
# @example
|
||||
# resolve_layout
|
||||
# # => ["/layouts/custom", :erb]
|
||||
# # => [nil, nil]
|
||||
#
|
||||
def resolved_layout
|
||||
located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false, :strict_format => true)
|
||||
located_layout ? located_layout : [nil, nil]
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the template path and engine that match content_type (if present),
|
||||
# I18n.locale.
|
||||
#
|
||||
# @param [String] template_path
|
||||
# The path of the template.
|
||||
#
|
||||
# @param [Hash] options
|
||||
# Additional options.
|
||||
#
|
||||
# @option options [Boolean] :strict_format (false)
|
||||
# The resolved template must match the content_type of the request.
|
||||
#
|
||||
# @option options [Boolean] :raise_exceptions (false)
|
||||
# Raises a {TemplateNotFound} exception if the template cannot be located.
|
||||
#
|
||||
# @return [Array<Symbol, Symbol>]
|
||||
# The path and format of the template.
|
||||
#
|
||||
# @raise [TemplateNotFound]
|
||||
# The template could not be found.
|
||||
#
|
||||
# @example
|
||||
# get "/foo", :provides => [:html, :js] do; render 'path/to/foo'; end
|
||||
# # If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb]
|
||||
# # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
|
||||
#
|
||||
def resolve_template(template_path, options={})
|
||||
began_at = Time.now
|
||||
_content_type = content_type || :html
|
||||
# Fetch cached template for rendering options
|
||||
template_path = template_path.to_s[0] == ?/ ? template_path.to_s : "/#{template_path}"
|
||||
rendering_options = [template_path, _content_type, locale]
|
||||
cached_template = settings.fetch_template_file(rendering_options)
|
||||
if cached_template
|
||||
logger.debug :cached, began_at, cached_template[0] if settings.logging? && defined?(logger)
|
||||
return cached_template
|
||||
end
|
||||
|
||||
# Resolve view path and options.
|
||||
options = DEFAULT_RENDERING_OPTIONS.merge(options)
|
||||
view_path = options.delete(:views) || settings.views || "./views"
|
||||
target_extension = File.extname(template_path)[1..-1] || "none" # explicit template extension
|
||||
template_path = template_path.chomp(".#{target_extension}")
|
||||
template_glob =
|
||||
if respond_to?(:request) && request.controller.present?
|
||||
File.join("{,#{request.controller}}", template_path)
|
||||
else
|
||||
template_path
|
||||
end
|
||||
|
||||
# Generate potential template candidates
|
||||
templates = Dir[File.join(view_path, template_glob) + ".*"].map do |file|
|
||||
template_engine = File.extname(file)[1..-1].to_sym # Retrieves engine extension
|
||||
template_file = file.squeeze('/').sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
|
||||
[template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern }
|
||||
end
|
||||
|
||||
# Check if we have a simple content type
|
||||
simple_content_type = [:html, :plain].include?(_content_type)
|
||||
|
||||
# Resolve final template to render
|
||||
located_template =
|
||||
templates.find { |file, e| file.to_s == "#{template_path}.#{locale}.#{_content_type}" } ||
|
||||
templates.find { |file, e| file.to_s == "#{template_path}.#{locale}" && simple_content_type } ||
|
||||
templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } ||
|
||||
templates.find { |file, e| file.to_s == "#{template_path}.#{_content_type}" } ||
|
||||
templates.find { |file, e| file.to_s == "#{template_path}" && simple_content_type } ||
|
||||
(!options[:strict_format] && templates.first) # If not strict, fall back to the first located template.
|
||||
|
||||
raise TemplateNotFound, "Template '#{template_path}' not found in '#{view_path}'!" if !located_template && options[:raise_exceptions]
|
||||
settings.cache_template_file!(located_template, rendering_options) unless settings.reload_templates?
|
||||
logger.debug :template, began_at, located_template[0] if located_template && settings.logging? && defined?(logger)
|
||||
located_template
|
||||
end
|
||||
|
||||
##
|
||||
# Return the I18n.locale if I18n is defined.
|
||||
#
|
||||
def locale
|
||||
I18n.locale if defined?(I18n)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'padrino-core/application/rendering/extensions/haml'
|
||||
require 'padrino-core/application/rendering/extensions/erubis'
|
||||
require 'padrino-core/application/rendering/extensions/slim'
|
|
@ -1,68 +0,0 @@
|
|||
begin
|
||||
require 'erubis'
|
||||
|
||||
module Padrino
|
||||
module Erubis
|
||||
##
|
||||
# SafeBufferEnhancer is an Erubis Enhancer that compiles templates that
|
||||
# are fit for using ActiveSupport::SafeBuffer as a Buffer.
|
||||
#
|
||||
# @api private
|
||||
module SafeBufferEnhancer
|
||||
def add_expr_literal(src, code)
|
||||
src << " #{@bufvar}.concat((" << code << ').to_s);'
|
||||
end
|
||||
|
||||
def add_expr_escaped(src, code)
|
||||
src << " #{@bufvar}.safe_concat " << code << ';'
|
||||
end
|
||||
|
||||
def add_text(src, text)
|
||||
src << " #{@bufvar}.safe_concat '" << escape_text(text) << "';" unless text.empty?
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# SafeBufferTemplate is the classic Erubis template, augmented with
|
||||
# SafeBufferEnhancer.
|
||||
#
|
||||
# @api private
|
||||
class SafeBufferTemplate < ::Erubis::Eruby
|
||||
include SafeBufferEnhancer
|
||||
end
|
||||
|
||||
##
|
||||
# Modded ErubisTemplate that doesn't insist in an String as output
|
||||
# buffer.
|
||||
#
|
||||
# @api private
|
||||
class Template < Tilt::ErubisTemplate
|
||||
def render(*args)
|
||||
app = args.first
|
||||
app_class = app.class
|
||||
@is_padrino_app = app.kind_of?(Padrino::Application) ||
|
||||
(app_class.respond_to?(:erb) && app_class.erb[:engine_class] == Padrino::Erubis::SafeBufferTemplate)
|
||||
super
|
||||
end
|
||||
|
||||
##
|
||||
# In preamble we need a flag `__in_erb_template` and SafeBuffer for padrino apps.
|
||||
#
|
||||
def precompiled_preamble(locals)
|
||||
original = super
|
||||
return original unless @is_padrino_app
|
||||
"__in_erb_template = true\n" << original.rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Tilt.prefer(Padrino::Erubis::Template, :erb)
|
||||
|
||||
if defined? Padrino::Rendering
|
||||
Padrino::Rendering.engine_configurations[:erb] = {
|
||||
:engine_class => Padrino::Erubis::SafeBufferTemplate,
|
||||
}
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
begin
|
||||
require 'haml'
|
||||
require 'haml/helpers/xss_mods'
|
||||
require 'haml/helpers/action_view_extensions'
|
||||
|
||||
module Haml
|
||||
module Helpers
|
||||
include XssMods
|
||||
include ActionViewExtensions
|
||||
end
|
||||
|
||||
module Util
|
||||
def self.rails_xss_safe?
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if defined? Padrino::Rendering
|
||||
Padrino::Rendering.engine_configurations[:haml] = {
|
||||
:escape_html => true,
|
||||
}
|
||||
|
||||
class Tilt::HamlTemplate
|
||||
include Padrino::Rendering::SafeTemplate
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
begin
|
||||
require 'slim'
|
||||
|
||||
if defined? Padrino::Rendering
|
||||
Padrino::Rendering.engine_configurations[:slim] = {
|
||||
:generator => Temple::Generators::RailsOutputBuffer,
|
||||
:buffer => "@_out_buf",
|
||||
:use_html_safe => true,
|
||||
:disable_capture => true,
|
||||
}
|
||||
|
||||
class Slim::Template
|
||||
include Padrino::Rendering::SafeTemplate
|
||||
|
||||
def precompiled_preamble(locals)
|
||||
"__in_slim_template = true\n" << super
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
|||
module Padrino
|
||||
##
|
||||
# This module extend Sinatra::ShowExceptions adding Padrino as "Framework".
|
||||
#
|
||||
# @private
|
||||
class ShowExceptions < Sinatra::ShowExceptions
|
||||
private
|
||||
|
||||
def frame_class(frame)
|
||||
if frame.filename =~ /lib\/sinatra.*\.rb|lib\/padrino.*\.rb/
|
||||
"framework"
|
||||
elsif (defined?(Gem) && frame.filename.include?(Gem.dir)) ||
|
||||
frame.filename =~ /\/bin\/(\w+)$/ ||
|
||||
frame.filename =~ /Ruby\/Gems/
|
||||
"system"
|
||||
else
|
||||
"app"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,53 +0,0 @@
|
|||
module Padrino
|
||||
|
||||
# List of callers in a Padrino application that should be ignored as part of a stack trace.
|
||||
PADRINO_IGNORE_CALLERS = [
|
||||
%r{lib/padrino-.*$},
|
||||
%r{/padrino-.*/(lib|bin)},
|
||||
%r{/bin/padrino$},
|
||||
%r{/sinatra(/(base|main|show_?exceptions))?\.rb$},
|
||||
%r{lib/tilt.*\.rb$},
|
||||
%r{lib/rack.*\.rb$},
|
||||
%r{lib/mongrel.*\.rb$},
|
||||
%r{lib/shotgun.*\.rb$},
|
||||
%r{bin/shotgun$},
|
||||
%r{\(.*\)},
|
||||
%r{shoulda/context\.rb$},
|
||||
%r{mocha/integration},
|
||||
%r{test/unit},
|
||||
%r{rake_test_loader\.rb},
|
||||
%r{custom_require\.rb$},
|
||||
%r{active_support},
|
||||
%r{/thor}
|
||||
] unless defined?(PADRINO_IGNORE_CALLERS)
|
||||
|
||||
##
|
||||
# Add rubinius (and hopefully other VM implementations) ignore patterns ...
|
||||
#
|
||||
PADRINO_IGNORE_CALLERS.concat(RUBY_IGNORE_CALLERS) if defined?(RUBY_IGNORE_CALLERS)
|
||||
|
||||
private
|
||||
##
|
||||
# The filename for the file that is the direct caller (first caller).
|
||||
#
|
||||
# @return [String]
|
||||
# The file the caller method exists in.
|
||||
#
|
||||
def self.first_caller
|
||||
caller_files.first
|
||||
end
|
||||
|
||||
#
|
||||
# Like +Kernel#caller+ but excluding certain magic entries and without
|
||||
# line / method information; the resulting array contains filenames only.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
# The files of the calling methods.
|
||||
#
|
||||
def self.caller_files
|
||||
caller(1).
|
||||
map { |line| line.split(/:(?=\d|in )/)[0,2] }.
|
||||
reject { |file,line| PADRINO_IGNORE_CALLERS.any? { |pattern| file =~ pattern } }.
|
||||
map { |file,line| file }
|
||||
end
|
||||
end
|
|
@ -1,24 +0,0 @@
|
|||
module Padrino
|
||||
module Cli
|
||||
module Adapter
|
||||
class << self
|
||||
# Start for the given options a rackup handler
|
||||
def start(options)
|
||||
Padrino.run!(options.symbolize_keys)
|
||||
end
|
||||
|
||||
# Method that stop (if exist) a running Padrino.application
|
||||
def stop(options)
|
||||
options.symbolize_keys!
|
||||
if File.exist?(options[:pid])
|
||||
pid = File.read(options[:pid]).to_i
|
||||
print "=> Sending INT to process with pid #{pid} wait "
|
||||
Process.kill(2, pid) rescue nil
|
||||
else
|
||||
puts "=> #{options[:pid]} not found!"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,190 +0,0 @@
|
|||
require 'thor'
|
||||
|
||||
module Padrino
|
||||
module Cli
|
||||
|
||||
class Base < Thor
|
||||
include Thor::Actions
|
||||
|
||||
class_option :chdir, :type => :string, :aliases => "-c", :desc => "Change to dir before starting."
|
||||
class_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development, :desc => "Padrino Environment."
|
||||
class_option :help, :type => :boolean, :desc => "Show help usage"
|
||||
|
||||
desc "start", "Starts the Padrino application (alternatively use 's')."
|
||||
map "s" => :start
|
||||
method_option :server, :type => :string, :aliases => "-a", :desc => "Rack Handler (default: autodetect)"
|
||||
method_option :host, :type => :string, :aliases => "-h", :required => true, :default => '127.0.0.1', :desc => "Bind to HOST address."
|
||||
method_option :port, :type => :numeric, :aliases => "-p", :required => true, :default => 3000, :desc => "Use PORT."
|
||||
method_option :daemonize, :type => :boolean, :aliases => "-d", :desc => "Run daemonized in the background."
|
||||
method_option :pid, :type => :string, :aliases => "-i", :desc => "File to store pid."
|
||||
method_option :debug, :type => :boolean, :desc => "Set debugging flags."
|
||||
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"
|
||||
method_option :server_options, :type => :boolean, :desc => "Tells the current server handler's options that can be used with --options"
|
||||
|
||||
def start
|
||||
prepare :start
|
||||
require File.expand_path("../adapter", __FILE__)
|
||||
require File.expand_path('config/boot.rb')
|
||||
|
||||
if options[:server_options]
|
||||
puts server_options(options)
|
||||
else
|
||||
Padrino::Cli::Adapter.start(options)
|
||||
end
|
||||
end
|
||||
|
||||
desc "stop", "Stops the Padrino application (alternatively use 'st')."
|
||||
map "st" => :stop
|
||||
method_option :pid, :type => :string, :aliases => "-p", :desc => "File to store pid", :default => 'tmp/pids/server.pid'
|
||||
def stop
|
||||
prepare :stop
|
||||
require File.expand_path("../adapter", __FILE__)
|
||||
Padrino::Cli::Adapter.stop(options)
|
||||
end
|
||||
|
||||
desc "rake", "Execute rake tasks."
|
||||
method_option :environment, :type => :string, :aliases => "-e", :required => true, :default => :development
|
||||
method_option :list, :type => :string, :aliases => "-T", :desc => "Display the tasks (matching optional PATTERN) with descriptions, then exit."
|
||||
method_option :trace, :type => :boolean, :aliases => "-t", :desc => "Turn on invoke/execute tracing, enable full backtrace."
|
||||
def rake(*args)
|
||||
prepare :rake
|
||||
args << "-T" if options[:list]
|
||||
args << options[:list] unless options[:list].nil? || options[:list].to_s == "list"
|
||||
args << "--trace" if options[:trace]
|
||||
args << "--verbose" if options[:verbose]
|
||||
ARGV.clear
|
||||
ARGV.concat(args)
|
||||
puts "=> Executing Rake #{ARGV.join(' ')} ..."
|
||||
load File.expand_path('../rake.rb', __FILE__)
|
||||
Rake.application.init
|
||||
Rake.application.instance_variable_set(:@rakefile, __FILE__)
|
||||
load File.expand_path('Rakefile')
|
||||
Rake.application.top_level
|
||||
end
|
||||
|
||||
desc "console", "Boots up the Padrino application irb console (alternatively use 'c')."
|
||||
map "c" => :console
|
||||
def console(*args)
|
||||
prepare :console
|
||||
require File.expand_path("../../version", __FILE__)
|
||||
ARGV.clear
|
||||
require 'irb'
|
||||
require "irb/completion"
|
||||
require File.expand_path('config/boot.rb')
|
||||
puts "=> Loading #{Padrino.env} console (Padrino v.#{Padrino.version})"
|
||||
require File.expand_path('../console', __FILE__)
|
||||
IRB.start
|
||||
end
|
||||
|
||||
desc "generate", "Executes the Padrino generator with given options (alternatively use 'gen' or 'g')."
|
||||
map ["gen", "g"] => :generate
|
||||
def generate(*args)
|
||||
begin
|
||||
# We try to load the vendored padrino-gen if exist
|
||||
padrino_gen_path = File.expand_path('../../../../../padrino-gen/lib', __FILE__)
|
||||
$:.unshift(padrino_gen_path) if File.directory?(padrino_gen_path) && !$:.include?(padrino_gen_path)
|
||||
require 'padrino-core/command'
|
||||
require 'padrino-gen/command'
|
||||
ARGV.shift
|
||||
ARGV << 'help' if ARGV.empty?
|
||||
Padrino.bin_gen(*ARGV)
|
||||
rescue
|
||||
puts "<= You need padrino-gen! Run: gem install padrino-gen"
|
||||
end
|
||||
end
|
||||
|
||||
desc "version", "Show current Padrino version."
|
||||
map ["-v", "--version"] => :version
|
||||
def version
|
||||
require 'padrino-core/version'
|
||||
puts "Padrino v. #{Padrino.version}"
|
||||
end
|
||||
|
||||
desc "runner", "Run a piece of code in the Padrino application environment (alternatively use 'run' or 'r')."
|
||||
map ["run", "r"] => :runner
|
||||
def runner(*args)
|
||||
prepare :runner
|
||||
|
||||
code_or_file = args.shift
|
||||
abort "Please specify code or file" if code_or_file.nil?
|
||||
|
||||
require File.expand_path('config/boot.rb')
|
||||
|
||||
if File.exist?(code_or_file)
|
||||
eval(File.read(code_or_file), nil, code_or_file)
|
||||
else
|
||||
eval(code_or_file)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare(task)
|
||||
if options.help?
|
||||
help(task.to_s)
|
||||
raise SystemExit
|
||||
end
|
||||
ENV["RACK_ENV"] ||= options.environment.to_s
|
||||
chdir(options.chdir)
|
||||
unless File.exist?('config/boot.rb')
|
||||
puts "=> Could not find boot file in: #{options.chdir}/config/boot.rb !!!"
|
||||
raise SystemExit
|
||||
end
|
||||
end
|
||||
|
||||
# https://github.com/rack/rack/blob/master/lib/rack/server.rb\#L100
|
||||
def server_options(options)
|
||||
begin
|
||||
info = []
|
||||
server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
|
||||
if server && server.respond_to?(:valid_options)
|
||||
info << ""
|
||||
info << "Server-specific options for #{server.name}:"
|
||||
|
||||
has_options = false
|
||||
server.valid_options.each do |name, description|
|
||||
next if name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # ignore handler's host and port options, we do our own.
|
||||
info << " -O %-21s %s" % [name, description]
|
||||
has_options = true
|
||||
end
|
||||
return "" if !has_options
|
||||
end
|
||||
info.join("\n")
|
||||
rescue NameError
|
||||
return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.banner(task=nil, *args)
|
||||
"padrino #{task.name}"
|
||||
end
|
||||
|
||||
def chdir(dir)
|
||||
return unless dir
|
||||
begin
|
||||
Dir.chdir(dir.to_s)
|
||||
rescue Errno::ENOENT
|
||||
puts "=> Specified Padrino root '#{dir}' does not appear to exist!"
|
||||
rescue Errno::EACCES
|
||||
puts "=> Specified Padrino root '#{dir}' cannot be accessed by the current user!"
|
||||
end
|
||||
end
|
||||
|
||||
def capture(stream)
|
||||
begin
|
||||
stream = stream.to_s
|
||||
eval "$#{stream} = StringIO.new"
|
||||
yield
|
||||
result = eval("$#{stream}").string
|
||||
ensure
|
||||
eval("$#{stream} = #{stream.upcase}")
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
alias :silence :capture
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
# Reloads classes
|
||||
def reload!
|
||||
Padrino.reload!
|
||||
end
|
||||
|
||||
# Show applications
|
||||
def applications
|
||||
puts "==== List of Mounted Applications ====\n\n"
|
||||
Padrino.mounted_apps.each do |app|
|
||||
puts " * %-10s mapped to %s" % [app.name, app.uri_root]
|
||||
end
|
||||
puts
|
||||
Padrino.mounted_apps.map { |app| "#{app.name} => #{app.uri_root}" }
|
||||
end
|
||||
|
||||
# Load apps
|
||||
Padrino.mounted_apps.each do |app|
|
||||
puts "=> Loading Application #{app.app_class}"
|
||||
app.app_obj.setup_application!
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
require File.expand_path('../../tasks', __FILE__)
|
||||
require 'rake'
|
||||
require 'rake/dsl_definition'
|
||||
require 'thor'
|
||||
require 'securerandom' unless defined?(SecureRandom)
|
||||
require 'padrino-gen'
|
||||
|
||||
module PadrinoTasks
|
||||
def self.init(init=false)
|
||||
$LOAD_PATH.unshift(File.expand_path("lib"))
|
||||
Padrino::Tasks.files.flatten.uniq.each { |rakefile| Rake.application.add_import(rakefile) rescue puts "<= Failed load #{ext}" }
|
||||
load(File.expand_path('../rake_tasks.rb', __FILE__))
|
||||
Rake.application.load_imports
|
||||
end
|
||||
|
||||
def self.use(task)
|
||||
tasks << task
|
||||
end
|
||||
|
||||
def self.tasks
|
||||
@tasks ||= []
|
||||
end
|
||||
|
||||
def self.load?(task, constant_present)
|
||||
if constant_present && !PadrinoTasks.tasks.include?(task)
|
||||
warn <<-WARNING.undent
|
||||
Loading #{task} tasks automatically.
|
||||
This functionality will be disabled in future versions. Please put
|
||||
|
||||
PadrinoTasks.use(#{task.inspect})
|
||||
PadrinoTasks.init
|
||||
|
||||
and remove
|
||||
|
||||
require File.expand_path('../config/boot.rb', __FILE__)
|
||||
|
||||
in you Rakefile instead.
|
||||
WARNING
|
||||
end
|
||||
|
||||
constant_present || PadrinoTasks.tasks.include?(task)
|
||||
end
|
||||
end
|
||||
|
||||
def shell
|
||||
@_shell ||= Thor::Base.shell.new
|
||||
end
|
|
@ -1,62 +0,0 @@
|
|||
Dir["{lib/tasks/**,tasks/**,test,spec}/*.rake"].each do |file|
|
||||
begin
|
||||
load(file)
|
||||
rescue LoadError => e
|
||||
warn "#{file}: #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
# Loads the Padrino applications mounted within the project.
|
||||
# Setting up the required environment for Padrino.
|
||||
task :environment do
|
||||
require File.expand_path('config/boot.rb', Rake.application.original_dir)
|
||||
|
||||
Padrino.mounted_apps.each do |app|
|
||||
app.app_obj.setup_application!
|
||||
end
|
||||
end
|
||||
|
||||
# Loads skeleton Padrino environment, no models, no application settings.
|
||||
task :skeleton do
|
||||
module Padrino::Reloader
|
||||
def self.safe_load(file, options)
|
||||
super unless file.include?('/models/')
|
||||
end
|
||||
end
|
||||
require File.expand_path('config/boot.rb', Rake.application.original_dir)
|
||||
end
|
||||
|
||||
desc "Generate a secret key"
|
||||
task :secret do
|
||||
shell.say SecureRandom.hex(32)
|
||||
end
|
||||
|
||||
def list_app_routes(app, args)
|
||||
app_routes = app.named_routes
|
||||
app_routes.reject! { |r| r.identifier.to_s !~ /#{args.query}/ } if args.query.present?
|
||||
app_routes.map! { |r| [r.verb, r.name, r.path] }
|
||||
return if app_routes.empty?
|
||||
shell.say "\nApplication: #{app.app_class}", :yellow
|
||||
app_routes.unshift(["REQUEST", "URL", "PATH"])
|
||||
max_col_1 = app_routes.max { |a, b| a[0].size <=> b[0].size }[0].size
|
||||
max_col_2 = app_routes.max { |a, b| a[1].size <=> b[1].size }[1].size
|
||||
app_routes.each_with_index do |row, i|
|
||||
message = [row[1].ljust(max_col_2+2), row[0].center(max_col_1+2), row[2]]
|
||||
shell.say(" " + message.join(" "), i==0 ? :bold : nil)
|
||||
end
|
||||
end
|
||||
|
||||
desc "Displays a listing of the named routes within a project, optionally only those matched by [query]"
|
||||
task :routes, [:query] => :environment do |t, args|
|
||||
Padrino.mounted_apps.each do |app|
|
||||
list_app_routes(app, args)
|
||||
end
|
||||
end
|
||||
|
||||
desc "Displays a listing of the named routes a given app [app]"
|
||||
namespace :routes do
|
||||
task :app, [:app] => :environment do |t, args|
|
||||
app = Padrino.mounted_apps.find { |app| app.app_class == args.app }
|
||||
list_app_routes(app, args) if app
|
||||
end
|
||||
end
|
|
@ -1,38 +0,0 @@
|
|||
require 'rbconfig'
|
||||
|
||||
module Padrino
|
||||
##
|
||||
# This method return the correct location of padrino bin or
|
||||
# exec it using Kernel#system with the given args.
|
||||
#
|
||||
# @param [Array] args
|
||||
# command or commands to execute
|
||||
#
|
||||
# @return [Boolean]
|
||||
#
|
||||
# @example
|
||||
# Padrino.bin('start', '-e production')
|
||||
#
|
||||
def self.bin(*args)
|
||||
@_padrino_bin ||= [self.ruby_command, File.expand_path("../../../bin/padrino", __FILE__)]
|
||||
args.empty? ? @_padrino_bin : system(args.unshift(@_padrino_bin).join(" "))
|
||||
end
|
||||
|
||||
##
|
||||
# Return the path to the ruby interpreter taking into account multiple
|
||||
# installations and windows extensions.
|
||||
#
|
||||
# @return [String]
|
||||
# path to ruby bin executable
|
||||
#
|
||||
def self.ruby_command
|
||||
@ruby_command ||= begin
|
||||
ruby = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
||||
ruby << RbConfig::CONFIG['EXEEXT']
|
||||
|
||||
# escape string in case path to ruby executable contain spaces.
|
||||
ruby.sub!(/.*\s.*/m, '"\&"')
|
||||
ruby
|
||||
end
|
||||
end
|
||||
end
|
Binary file not shown.
Before Width: | Height: | Size: 23 KiB |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
|
@ -1,224 +0,0 @@
|
|||
module Padrino
|
||||
module Loader
|
||||
##
|
||||
# Hooks to be called before a load/reload.
|
||||
#
|
||||
# @yield []
|
||||
# The given block will be called before Padrino was loaded/reloaded.
|
||||
#
|
||||
# @return [Array<Proc>]
|
||||
# The load/reload before hooks.
|
||||
#
|
||||
# @example
|
||||
# before_load do
|
||||
# pre_initialize_something
|
||||
# end
|
||||
#
|
||||
def before_load(&block)
|
||||
@_before_load ||= []
|
||||
@_before_load << block if block_given?
|
||||
@_before_load
|
||||
end
|
||||
|
||||
##
|
||||
# Hooks to be called after a load/reload.
|
||||
#
|
||||
# @yield []
|
||||
# The given block will be called after Padrino was loaded/reloaded.
|
||||
#
|
||||
# @return [Array<Proc>]
|
||||
# The load/reload hooks.
|
||||
#
|
||||
# @example
|
||||
# after_load do
|
||||
# DataMapper.finalize
|
||||
# end
|
||||
#
|
||||
def after_load(&block)
|
||||
@_after_load ||= []
|
||||
@_after_load << block if block_given?
|
||||
@_after_load
|
||||
end
|
||||
|
||||
##
|
||||
# Requires necessary dependencies as well as application files from root
|
||||
# lib and models.
|
||||
#
|
||||
# @return [Boolean]
|
||||
# returns true if Padrino is not already bootstraped otherwise else.
|
||||
#
|
||||
def load!
|
||||
return false if loaded?
|
||||
began_at = Time.now
|
||||
@_called_from = first_caller
|
||||
set_encoding
|
||||
set_load_paths(*load_paths)
|
||||
Logger.setup!
|
||||
require_dependencies("#{root}/config/database.rb")
|
||||
Reloader.lock!
|
||||
before_load.each(&:call)
|
||||
require_dependencies(*dependency_paths)
|
||||
after_load.each(&:call)
|
||||
logger.devel "Loaded Padrino in #{Time.now - began_at} seconds"
|
||||
Thread.current[:padrino_loaded] = true
|
||||
end
|
||||
|
||||
##
|
||||
# Clear the padrino env.
|
||||
#
|
||||
# @return [NilClass]
|
||||
#
|
||||
def clear!
|
||||
clear_middleware!
|
||||
mounted_apps.clear
|
||||
@_load_paths = nil
|
||||
@_dependency_paths = nil
|
||||
@_global_configuration = nil
|
||||
before_load.clear
|
||||
after_load.clear
|
||||
Reloader.clear!
|
||||
Thread.current[:padrino_loaded] = nil
|
||||
end
|
||||
|
||||
##
|
||||
# Method for reloading required applications and their files.
|
||||
#
|
||||
def reload!
|
||||
return unless Reloader.changed?
|
||||
before_load.each(&:call)
|
||||
Reloader.reload!
|
||||
after_load.each(&:call)
|
||||
end
|
||||
|
||||
##
|
||||
# This adds the ability to instantiate {Padrino.load!} after
|
||||
# {Padrino::Application} definition.
|
||||
#
|
||||
def called_from
|
||||
@_called_from || first_caller
|
||||
end
|
||||
|
||||
##
|
||||
# Determines whether Padrino was loaded with {Padrino.load!}.
|
||||
#
|
||||
# @return [Boolean]
|
||||
# Specifies whether Padrino was loaded.
|
||||
#
|
||||
def loaded?
|
||||
Thread.current[:padrino_loaded]
|
||||
end
|
||||
|
||||
##
|
||||
# Attempts to require all dependency libs that we need.
|
||||
# If you use this method we can perform correctly a Padrino.reload!
|
||||
# Another good thing that this method are dependency check, for example:
|
||||
#
|
||||
# # models
|
||||
# # \-- a.rb => require something of b.rb
|
||||
# # \-- b.rb
|
||||
#
|
||||
# In the example above if we do:
|
||||
#
|
||||
# Dir["/models/*.rb"].each { |r| require r }
|
||||
#
|
||||
# We get an error, because we try to require first +a.rb+ that need
|
||||
# _something_ of +b.rb+.
|
||||
#
|
||||
# With this method we don't have this problem.
|
||||
#
|
||||
# @param [Array<String>] paths
|
||||
# The paths to require.
|
||||
#
|
||||
# @example For require all our app libs we need to do:
|
||||
# require_dependencies("#{Padrino.root}/lib/**/*.rb")
|
||||
#
|
||||
def require_dependencies(*paths)
|
||||
options = paths.extract_options!.merge( :cyclic => true )
|
||||
files = paths.flatten.map{|path| Dir[path].sort_by{|v| v.count('/') }}.flatten.uniq
|
||||
|
||||
while files.present?
|
||||
error, fatal, loaded = nil, nil, nil
|
||||
|
||||
files.dup.each do |file|
|
||||
begin
|
||||
Reloader.safe_load(file, options)
|
||||
files.delete(file)
|
||||
loaded = true
|
||||
rescue NameError, LoadError => e
|
||||
logger.devel "Cyclic dependency reload for #{e.class}: #{e.message}"
|
||||
error = e
|
||||
rescue Exception => e
|
||||
fatal = e
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if fatal || !loaded
|
||||
e = fatal || error
|
||||
logger.error "#{e.class}: #{e.message}; #{e.backtrace.first}"
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Concat to +$LOAD_PATH+ the given paths.
|
||||
#
|
||||
# @param [Array<String>] paths
|
||||
# The paths to concat.
|
||||
#
|
||||
def set_load_paths(*paths)
|
||||
load_paths.concat(paths).uniq!
|
||||
$LOAD_PATH.concat(paths).uniq!
|
||||
end
|
||||
|
||||
##
|
||||
# The used +$LOAD_PATHS+ from Padrino.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
# The load paths used by Padrino.
|
||||
#
|
||||
def load_paths
|
||||
@_load_paths ||= load_paths_was.dup
|
||||
end
|
||||
|
||||
##
|
||||
# Returns default list of path globs to load as dependencies.
|
||||
# Appends custom dependency patterns to the be loaded for Padrino.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
# The dependencey paths.
|
||||
#
|
||||
# @example
|
||||
# Padrino.dependency_paths << "#{Padrino.root}/uploaders/*.rb"
|
||||
#
|
||||
def dependency_paths
|
||||
@_dependency_paths ||= dependency_paths_was + module_paths
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def module_paths
|
||||
modules.map(&:dependency_paths).flatten
|
||||
end
|
||||
|
||||
def load_paths_was
|
||||
@_load_paths_was ||= [
|
||||
"#{root}/lib",
|
||||
"#{root}/models",
|
||||
"#{root}/shared",
|
||||
].freeze
|
||||
end
|
||||
|
||||
def dependency_paths_was
|
||||
@_dependency_paths_was ||= [
|
||||
"#{root}/config/database.rb",
|
||||
"#{root}/lib/**/*.rb",
|
||||
"#{root}/models/**/*.rb",
|
||||
"#{root}/shared/lib/**/*.rb",
|
||||
"#{root}/shared/models/**/*.rb",
|
||||
"#{root}/config/apps.rb"
|
||||
].freeze
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
cs:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d. %m. %Y"
|
||||
short: "%d %b"
|
||||
long: "%d. %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Neděle, Pondělí, Úterý, Středa, Čtvrtek, Pátek, Sobota]
|
||||
abbr_day_names: [Ne, Po, Út, St, Čt, Pá, So]
|
||||
month_names: [~, Leden, Únor, Březen, Duben, Květen, Červen, Červenec, Srpen, Září, Říjen, Listopad, Prosinec]
|
||||
abbr_month_names: [~, Led, Úno, Bře, Dub, Kvě, Čvn, Čvc, Srp, Zář, Říj, Lis, Pro]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a %d. %B %Y %H:%M %z"
|
||||
short: "%d. %m. %H:%M"
|
||||
long: "%A %d. %B %Y %H:%M"
|
||||
am: "dop"
|
||||
pm: "odp"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " a "
|
||||
last_word_connector: " a "
|
|
@ -1,33 +0,0 @@
|
|||
da:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%e. %b %Y"
|
||||
long: "%e. %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag]
|
||||
abbr_day_names: [sø, ma, ti, 'on', to, fr, lø]
|
||||
month_names: [~, januar, februar, marts, april, maj, juni, juli, august, september, oktober, november, december]
|
||||
abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, dec]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%e. %B %Y, %H:%M"
|
||||
short: "%e. %b %Y, %H:%M"
|
||||
long: "%A, %e. %B %Y, %H:%M"
|
||||
am: ""
|
||||
pm: ""
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " og "
|
||||
last_word_connector: " og "
|
|
@ -1,33 +0,0 @@
|
|||
de:
|
||||
date:
|
||||
formats:
|
||||
# Benutze die strftime Parameter für die Formatierung
|
||||
# Wenn keine Formate angegeben werden, wird "default" benutzt.
|
||||
# Du kannst auch weitere Formate hinzufügen, wenn Du möchtest.
|
||||
default: "&d.&m.%Y"
|
||||
short: "%d. %b"
|
||||
long: "%d. %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
|
||||
abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
|
||||
month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
|
||||
abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d. %b %Y %H:%M:%S %z"
|
||||
short: "%d. %b %H:%M"
|
||||
long: "%d. %B %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " und "
|
||||
last_word_connector: " und "
|
|
@ -1,33 +0,0 @@
|
|||
en:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y-%m-%d"
|
||||
short: "%b %d"
|
||||
long: "%B %d, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
|
||||
abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
|
||||
month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
|
||||
abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " and "
|
||||
last_word_connector: ", and "
|
|
@ -1,33 +0,0 @@
|
|||
es:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d-%m-%Y"
|
||||
short: "%b %d"
|
||||
long: "%B %d, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
|
||||
abbr_day_names: [Dom, Lun, Mar, Mie, Jue, Vie, Sab]
|
||||
month_names: [~, Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre]
|
||||
abbr_month_names: [~, Ene, Feb, Mar, Abr, May, Jun, Jul, Ago, Sep, Oct, Nov, Dic]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " y "
|
||||
last_word_connector: ", y "
|
|
@ -1,33 +0,0 @@
|
|||
fr:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d-%m-%Y"
|
||||
short: "%b %d"
|
||||
long: "%B %d, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Dimanche, Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi]
|
||||
abbr_day_names: [Dim, Lun, Mar, Mer, Jeu, Ven, Sam]
|
||||
month_names: [~, Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre]
|
||||
abbr_month_names: [~, Jan, Fev, Mar, Avr, Mai, Jun, Jul, Aou, Sep, Oct, Nov, Dec]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " et "
|
||||
last_word_connector: ", et "
|
|
@ -1,33 +0,0 @@
|
|||
hu:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y-%m-%d"
|
||||
short: "%b. %d."
|
||||
long: "%Y. %B %d."
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [vasárnap, hétfő, kedd, szerda, csütörtök, péntek, szombat]
|
||||
abbr_day_names: [vas, hét, kedd, sze, csüt, pén, szo]
|
||||
month_names: [~, január, február, március, április, május, június, július, augusztus, szeptember, oktober, november, december]
|
||||
abbr_month_names: [~, jan, febr, márc, ápr, máj, jún, júl, aug, szept, okt, nov, dec]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%Y. %B %d. %H:%M:%S %z, %A"
|
||||
short: "%B %d. %H:%M"
|
||||
long: "%Y. %B %d. %H:%M"
|
||||
am: "de"
|
||||
pm: "du"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " és "
|
||||
last_word_connector: " és "
|
|
@ -1,39 +0,0 @@
|
|||
it:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d-%m-%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Domenica, Lunedì, Martedì, Mercoledì, Giovedì, Venerdì, Sabato]
|
||||
abbr_day_names: [Dom, Lun, Mar, Mer, Gio, Ven, Sab]
|
||||
month_names: [~, Gennaio, Febbraio, Marzo, Aprile, Maggio, Giugno, Luglio, Agosto, Settembre, Ottobre, Novembre, Dicembre]
|
||||
abbr_month_names: [~, Gen, Feb, Mar, Apr, Mag, Giu, Lug, Ago, Set, Ott, Nov, Dic]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a %d %b %Y, %H:%M:%S %z"
|
||||
time: "%H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%d %B %Y %H:%M"
|
||||
only_second: "%S"
|
||||
|
||||
datetime:
|
||||
formats:
|
||||
default: "%d-%m-%YT%H:%M:%S%Z"
|
||||
|
||||
am: 'am'
|
||||
pm: 'pm'
|
||||
|
||||
support:
|
||||
array:
|
||||
sentence_connector: "e"
|
||||
skip_last_comma: false
|
|
@ -1,33 +0,0 @@
|
|||
ja:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y/%m/%d"
|
||||
short: "%m/%d"
|
||||
long: "%Y年%m月%d日"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [日曜日, 月曜日, 火曜日, 水曜日, 木曜日, 金曜日, 土曜日]
|
||||
abbr_day_names: [日, 月, 火, 水, 木, 金, 土]
|
||||
month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
|
||||
abbr_month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%Y/%m/%d %H:%M:%S"
|
||||
short: "%m/%d %H:%M"
|
||||
long: "%Y年%m月%d日 %H時%M分%S秒"
|
||||
am: "午前"
|
||||
pm: "午後"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " と "
|
||||
last_word_connector: ", と "
|
|
@ -1,33 +0,0 @@
|
|||
lv:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%e. %B"
|
||||
long: "%Y. gada %e. %B"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Svētdiena, Pirmdiena, Otrdiena, Trešdiena, Ceturtdiena, Piektdiena, Sestdiena]
|
||||
abbr_day_names: [Sv, P, O, T, C, P, S]
|
||||
month_names: [~, Janvāris, Februāris, Marts, Aprīlis, Maijs, Jūnijs, Jūlijs, Augusts, Septembris, Oktobris, Novembris, Decembris]
|
||||
abbr_month_names: [~, Janv, Febr, Marts, Apr, Maijs, Jūn, Jūl, Aug, Sept, Okt, Nov, Dec]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%Y. gada %e. %B, %H:%M"
|
||||
short: "%d.%m.%Y, %H:%M"
|
||||
long: "%Y. gada %e. %B, %H:%M:%S"
|
||||
am: "priekšpusdiena"
|
||||
pm: "pēcpusdiena"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " un "
|
||||
last_word_connector: ", un "
|
|
@ -1,33 +0,0 @@
|
|||
nl:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d-%m-%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag]
|
||||
abbr_day_names: [zo, ma, di, wo, do, vr, za]
|
||||
month_names: [~, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december]
|
||||
abbr_month_names: [~, jan, feb, maa, apr, mei, jun, jul, aug, sep, okt, nov, dec]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%d %B %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " en "
|
||||
last_word_connector: " en "
|
|
@ -1,33 +0,0 @@
|
|||
"no":
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%e. %b %Y"
|
||||
long: "%e. %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [søndag, mandag, tirsdag, onsdag, torsdag, fredag, lørdag]
|
||||
abbr_day_names: [sø, ma, ti, 'on', to, fr, lø]
|
||||
month_names: [~, januar, februar, mars, april, mai, juni, juli, august, september, oktober, november, desember]
|
||||
abbr_month_names: [~, jan, feb, mar, apr, maj, jun, jul, aug, sep, okt, nov, des]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%e. %B %Y, %H:%M"
|
||||
short: "%e. %b %Y, %H:%M"
|
||||
long: "%A, %e. %B %Y, %H:%M"
|
||||
am: ""
|
||||
pm: ""
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " og "
|
||||
last_word_connector: " og "
|
|
@ -1,33 +0,0 @@
|
|||
pl:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y-%m-%d"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Niedziela, Poniedziałek, Wtorek, Środa, Czwartek, Piątek, Sobota]
|
||||
abbr_day_names: [nie, pon, wto, śro, czw, pia, sob]
|
||||
month_names: [~, Styczeń, Luty, Marzec, Kwiecień, Maj, Czerwiec, Lipiec, Sierpień, Wrzesień, Październik, Listopad, Grudzień]
|
||||
abbr_month_names: [~, sty, lut, mar, kwi, maj, cze, lip, sie, wrz, paź, lis, gru]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y, %H:%M:%S %z"
|
||||
short: "%d %b, %H:%M"
|
||||
long: "%d %B %Y, %H:%M"
|
||||
am: "przed południem"
|
||||
pm: "po południu"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " i "
|
||||
last_word_connector: " i "
|
|
@ -1,39 +0,0 @@
|
|||
pt_br:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d-%m-%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Domingo, Segunda-feira, Terça-feira, Quarta-feira, Quinta-feira, Sexta-feira, Sábado]
|
||||
abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sab]
|
||||
month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
|
||||
abbr_month_names: [~, Jan, Fev, Mar, Abr, Maio, Jun, Jul, Ago, Set, Out, Nov, Dez]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a %d %b %Y, %H:%M:%S %z"
|
||||
time: "%H:%M"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%d %B %Y %H:%M"
|
||||
only_second: "%S"
|
||||
|
||||
datetime:
|
||||
formats:
|
||||
default: "%d-%m-%YT%H:%M:%S%Z"
|
||||
|
||||
am: 'am'
|
||||
pm: 'pm'
|
||||
|
||||
support:
|
||||
array:
|
||||
sentence_connector: "e"
|
||||
skip_last_comma: false
|
|
@ -1,33 +0,0 @@
|
|||
ro:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Duminică, Luni, Marți, Miercuri, Joi, Vineri, Sâmbătă]
|
||||
abbr_day_names: [Dum, Lun, Mar, Mie, Joi, Vin, Sâm]
|
||||
month_names: [~, Ianuarie, Februarie, Martie, Aprilie, Mai, Iunie, Iulie, August, Septembrie, Octombrie, Noiembrie, Decembrie]
|
||||
abbr_month_names: [~, Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%d, %B %Y %H:%M"
|
||||
am: "am"
|
||||
pm: "pm"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " și "
|
||||
last_word_connector: " și "
|
|
@ -1,34 +0,0 @@
|
|||
ru:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%d %b"
|
||||
long: "%e %B, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
|
||||
abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
|
||||
month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
|
||||
abbr_month_names: [~, Янв, Фев, Мар, Апр, Май, Июн, Июл, Авг, Сен, Окт, Ноя, Дек]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%e %B, %Y %H:%M"
|
||||
am: "д.п."
|
||||
pm: "п.п."
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " и "
|
||||
last_word_connector: " и "
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
sv:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y-%m-%d"
|
||||
short: "%b %d"
|
||||
long: "%B %d, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [söndag, måndag, tisdag, onsdag, torsdag, fredag, lördag]
|
||||
abbr_day_names: [sön, mån, tis, ons, tors, fre, lör]
|
||||
month_names: [~, januari, februari, mars, april, maj, juni, juli, augusti, september, oktober, november, december]
|
||||
abbr_month_names: [~, jan, feb, mar, apr, may, jun, jul, aug, sep, okt, nov, dec]
|
||||
order:
|
||||
- år
|
||||
- månad
|
||||
- dag
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%B %d, %Y %H:%M"
|
||||
am: "fm"
|
||||
pm: "em"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " och "
|
||||
last_word_connector: ", och "
|
|
@ -1,33 +0,0 @@
|
|||
tr:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d/%m/%Y"
|
||||
short: "%d %b"
|
||||
long: "%d %B %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Pazar, Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi]
|
||||
abbr_day_names: [Paz, Pts, Sal, Çar, Per, Cum, Cts]
|
||||
month_names: [~, Ocak, Şubat, Mart, Nisan, Mayıs, Haziran, Temmuz, Ağustos, Eylül, Ekim, Kasım, Aralık]
|
||||
abbr_month_names: [~, Oca, Şub, Mar, Nis, May, Haz, Tem, Ağu, Eyl, Eki, Kas, Ara]
|
||||
order:
|
||||
- day
|
||||
- month
|
||||
- year
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %b %b %Y %H:%M:%S %z"
|
||||
short: "%b %d %H:%M"
|
||||
long: "%d %B, %Y %H:%M"
|
||||
am: "öö"
|
||||
pm: "ös"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " ve "
|
||||
last_word_connector: " ve "
|
|
@ -1,33 +0,0 @@
|
|||
uk:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%d.%m.%Y"
|
||||
short: "%d %b"
|
||||
long: "%e %B, %Y"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [Неділя, Понеділок, Вівторок, Середа, Четвер, Пятница, Субота]
|
||||
abbr_day_names: [Нд, Пн, Вт, Ср, Чт, Пт, Сб]
|
||||
month_names: [~, Січено, Лютий, Березень, Квітень, Травень, Червень, Липень, Серпень, Вересень, Жовтень, Листопад, Грудень]
|
||||
abbr_month_names: [~, Січ, Лют, Бер, Кві, Тра, Чер, Лип, Сер, Вер, Жов, Лис, Гру]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%a, %d %b %Y %H:%M:%S %z"
|
||||
short: "%d %b %H:%M"
|
||||
long: "%e %B, %Y %H:%M"
|
||||
am: "д.п."
|
||||
pm: "п.п"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " і "
|
||||
last_word_connector: ", і "
|
|
@ -1,33 +0,0 @@
|
|||
zh_cn:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y年%m月%d日"
|
||||
short: "%b月%d日"
|
||||
long: "%Y年%B月%d日"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
|
||||
abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
|
||||
month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
|
||||
abbr_month_names: [~, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%Y年%b月%d日 %H:%M:%S %z"
|
||||
short: "%b月%d日 %H:%M"
|
||||
long: "%Y年%B%d日 %H时%M分"
|
||||
am: "上午"
|
||||
pm: "下午"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ","
|
||||
two_words_connector: "和"
|
||||
last_word_connector: ",还有"
|
|
@ -1,33 +0,0 @@
|
|||
zh_tw:
|
||||
date:
|
||||
formats:
|
||||
# Use the strftime parameters for formats.
|
||||
# When no format has been given, it uses default.
|
||||
# You can provide other formats here if you like!
|
||||
default: "%Y-%m-%d"
|
||||
short: "%b%d日"
|
||||
long: "%Y年%b%d日"
|
||||
only_day: "%e"
|
||||
|
||||
day_names: [星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六]
|
||||
abbr_day_names: [日, 一, 二, 三, 四, 五, 六]
|
||||
month_names: [~, 一月, 二月, 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月]
|
||||
abbr_month_names: [~, 1月, 2月, 3月, 4月, 5月, 6月, 7月, 8月, 9月, 10月, 11月, 12月]
|
||||
order:
|
||||
- year
|
||||
- month
|
||||
- day
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%Y年%b%d日 %A %H:%M:%S %Z"
|
||||
short: "%b%d日 %H:%M"
|
||||
long: "%Y年%b%d日 %H:%M"
|
||||
am: "上午"
|
||||
pm: "下午"
|
||||
|
||||
support:
|
||||
array:
|
||||
words_connector: ", "
|
||||
two_words_connector: " 和 "
|
||||
last_word_connector: ", 和 "
|
|
@ -1,438 +0,0 @@
|
|||
# Defines the log level for a Padrino project.
|
||||
PADRINO_LOG_LEVEL = ENV['PADRINO_LOG_LEVEL'] unless defined?(PADRINO_LOG_LEVEL)
|
||||
|
||||
# Defines the logger used for a Padrino project.
|
||||
PADRINO_LOGGER = ENV['PADRINO_LOGGER'] unless defined?(PADRINO_LOGGER)
|
||||
|
||||
module Padrino
|
||||
##
|
||||
# @return [Padrino::Logger]
|
||||
#
|
||||
# @example
|
||||
# logger.debug "foo"
|
||||
# logger.warn "bar"
|
||||
#
|
||||
def self.logger
|
||||
Padrino::Logger.logger
|
||||
end
|
||||
|
||||
##
|
||||
# Set the padrino logger.
|
||||
#
|
||||
# @param [Object] value
|
||||
# an object that respond to <<, write, puts, debug, warn etc..
|
||||
#
|
||||
# @return [Object]
|
||||
# The given value.
|
||||
#
|
||||
# @example using ruby default logger
|
||||
# require 'logger'
|
||||
# Padrino.logger = Logger.new(STDOUT)
|
||||
#
|
||||
# @example using ActiveSupport
|
||||
# require 'active_support/buffered_logger'
|
||||
# Padrino.logger = Buffered.new(STDOUT)
|
||||
#
|
||||
def self.logger=(value)
|
||||
Padrino::Logger.logger = value
|
||||
end
|
||||
|
||||
##
|
||||
# Padrinos internal logger, using all of Padrino log extensions.
|
||||
#
|
||||
class Logger
|
||||
##
|
||||
# Ruby (standard) logger levels:
|
||||
#
|
||||
# :fatal:: An not handleable error that results in a program crash
|
||||
# :error:: A handleable error condition
|
||||
# :warn:: A warning
|
||||
# :info:: generic (useful) information about system operation
|
||||
# :debug:: low-level information for developers
|
||||
# :devel:: Development-related information that is unnecessary in debug mode
|
||||
#
|
||||
Levels = {
|
||||
:fatal => 4,
|
||||
:error => 3,
|
||||
:warn => 2,
|
||||
:info => 1,
|
||||
:debug => 0,
|
||||
:devel => -1,
|
||||
} unless defined?(Levels)
|
||||
|
||||
module Extensions
|
||||
##
|
||||
# Generate the logging methods for {Padrino.logger} for each log level.
|
||||
#
|
||||
Padrino::Logger::Levels.each_pair do |name, number|
|
||||
define_method(name) do |*args|
|
||||
return if number < level
|
||||
if args.size > 1
|
||||
bench(args[0], args[1], args[2], name)
|
||||
else
|
||||
push(args * '', name)
|
||||
end
|
||||
end
|
||||
|
||||
define_method(:"#{name}?") do
|
||||
number >= level
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Append a to development logger a given action with time.
|
||||
#
|
||||
# @param [string] action
|
||||
# The action.
|
||||
#
|
||||
# @param [float] time
|
||||
# Time duration for the given action.
|
||||
#
|
||||
# @param [message] string
|
||||
# The message that you want to log.
|
||||
#
|
||||
# @example
|
||||
# logger.bench 'GET', started_at, '/blog/categories'
|
||||
# # => DEBUG - GET (0.0056s) - /blog/categories
|
||||
#
|
||||
def bench(action, began_at, message, level=:debug, color=:yellow)
|
||||
@_pad ||= 8
|
||||
@_pad = action.to_s.size if action.to_s.size > @_pad
|
||||
duration = Time.now - began_at
|
||||
color = :red if duration > 1
|
||||
action = colorize(action.to_s.upcase.rjust(@_pad), color)
|
||||
duration = colorize('%0.4fs' % duration, :bold, color)
|
||||
push "#{action} (#{duration}) #{message}", level
|
||||
end
|
||||
|
||||
##
|
||||
# Appends a message to the log. The methods yield to an optional block and
|
||||
# the output of this block will be appended to the message.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message that you want write to your stream.
|
||||
#
|
||||
# @param [String] level
|
||||
# The level one of :debug, :warn etc. ...
|
||||
#
|
||||
#
|
||||
def push(message = nil, level = nil)
|
||||
add(Padrino::Logger::Levels[level], format(message, level))
|
||||
end
|
||||
|
||||
##
|
||||
# Formats the log message. This method is a noop and should be implemented by other
|
||||
# logger components such as {Padrino::Logger}.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message to format.
|
||||
#
|
||||
# @param [String,Symbol] level
|
||||
# The log level, one of :debug, :warn ...
|
||||
def format(message, level)
|
||||
message
|
||||
end
|
||||
|
||||
##
|
||||
# The debug level, with some style added. May be reimplemented.
|
||||
#
|
||||
# @example
|
||||
# stylized_level(:debug) => DEBUG
|
||||
#
|
||||
# @param [String,Symbol] level
|
||||
# The log level.
|
||||
#
|
||||
def stylized_level(level)
|
||||
level.to_s.upcase.rjust(7)
|
||||
end
|
||||
|
||||
##
|
||||
# Colorizes a string for colored console output. This is a noop and can be reimplemented
|
||||
# to colorize the string as needed.
|
||||
#
|
||||
# @see
|
||||
# ColorizedLogger
|
||||
#
|
||||
# @param [string]
|
||||
# The string to be colorized.
|
||||
#
|
||||
# @param [Array<Symbol>]
|
||||
# The colors to use. Should be applied in the order given.
|
||||
def colorize(string, *colors)
|
||||
string
|
||||
end
|
||||
|
||||
##
|
||||
# Turns a logger with LoggingExtensions into a logger with colorized output.
|
||||
#
|
||||
# @example
|
||||
# Padrino.logger = Logger.new($stdout)
|
||||
# Padrino.logger.colorize!
|
||||
# Padrino.logger.debug("Fancy Padrino debug string")
|
||||
def colorize!
|
||||
self.extend(Colorize)
|
||||
end
|
||||
end
|
||||
|
||||
module Colorize
|
||||
# Colors for levels
|
||||
ColoredLevels = {
|
||||
:fatal => [:bold, :red],
|
||||
:error => [:red],
|
||||
:warn => [:yellow],
|
||||
:info => [:green],
|
||||
:debug => [:cyan],
|
||||
:devel => [:magenta]
|
||||
} unless defined?(ColoredLevels)
|
||||
|
||||
##
|
||||
# Colorize our level.
|
||||
#
|
||||
# @param [String, Symbol] level
|
||||
#
|
||||
# @see Padrino::Logging::ColorizedLogger::ColoredLevels
|
||||
#
|
||||
def colorize(string, *colors)
|
||||
colors.each do |c|
|
||||
string = string.colorize(c)
|
||||
end
|
||||
string
|
||||
end
|
||||
|
||||
def stylized_level(level)
|
||||
style = ColoredLevels[level].map { |c| "\e[%dm" % String::Colorizer.colors[c] } * ''
|
||||
[style, super, "\e[0m"] * ''
|
||||
end
|
||||
end
|
||||
|
||||
include Extensions
|
||||
|
||||
attr_accessor :auto_flush, :level, :log_static
|
||||
attr_reader :buffer, :colorize_logging, :init_args, :log
|
||||
|
||||
##
|
||||
# Configuration for a given environment, possible options are:
|
||||
#
|
||||
# :log_level:: Once of [:fatal, :error, :warn, :info, :debug]
|
||||
# :stream:: Once of [:to_file, :null, :stdout, :stderr] our your custom stream
|
||||
# :log_level::
|
||||
# The log level from, e.g. :fatal or :info. Defaults to :warn in the
|
||||
# production environment and :debug otherwise.
|
||||
# :auto_flush::
|
||||
# Whether the log should automatically flush after new messages are
|
||||
# added. Defaults to true.
|
||||
# :format_datetime:: Format of datetime. Defaults to: "%d/%b/%Y %H:%M:%S"
|
||||
# :format_message:: Format of message. Defaults to: ""%s - - [%s] \"%s\"""
|
||||
# :log_static:: Whether or not to show log messages for static files. Defaults to: false
|
||||
# :colorize_logging:: Whether or not to colorize log messages. Defaults to: true
|
||||
#
|
||||
# @example
|
||||
# Padrino::Logger::Config[:development] = { :log_level => :debug, :stream => :to_file }
|
||||
# # or you can edit our defaults
|
||||
# Padrino::Logger::Config[:development][:log_level] = :error
|
||||
# # or you can use your stream
|
||||
# Padrino::Logger::Config[:development][:stream] = StringIO.new
|
||||
#
|
||||
# Defaults are:
|
||||
#
|
||||
# :production => { :log_level => :warn, :stream => :to_file }
|
||||
# :development => { :log_level => :debug, :stream => :stdout }
|
||||
# :test => { :log_level => :fatal, :stream => :null }
|
||||
#
|
||||
# In some cases, configuring the loggers before loading the framework is necessary.
|
||||
# You can do so by setting PADRINO_LOGGER:
|
||||
#
|
||||
# PADRINO_LOGGER = { :staging => { :log_level => :debug, :stream => :to_file }}
|
||||
#
|
||||
Config = {
|
||||
:production => { :log_level => :warn, :stream => :to_file },
|
||||
:development => { :log_level => :debug, :stream => :stdout, :format_datetime => '' },
|
||||
:test => { :log_level => :debug, :stream => :null }
|
||||
}
|
||||
Config.merge!(PADRINO_LOGGER) if PADRINO_LOGGER
|
||||
|
||||
@@mutex = Mutex.new
|
||||
def self.logger
|
||||
@_logger || setup!
|
||||
end
|
||||
|
||||
def self.logger=(logger)
|
||||
logger.extend(Padrino::Logger::Extensions)
|
||||
|
||||
@_logger = logger
|
||||
end
|
||||
|
||||
##
|
||||
# Setup a new logger.
|
||||
#
|
||||
# @return [Padrino::Logger]
|
||||
# A {Padrino::Logger} instance
|
||||
#
|
||||
def self.setup!
|
||||
self.logger = begin
|
||||
config_level = (PADRINO_LOG_LEVEL || Padrino.env || :test).to_sym # need this for PADRINO_LOG_LEVEL
|
||||
config = Config[config_level]
|
||||
|
||||
unless config
|
||||
warn("No logging configuration for :#{config_level} found, falling back to :production")
|
||||
config = Config[:production]
|
||||
end
|
||||
|
||||
stream = case config[:stream]
|
||||
when :to_file
|
||||
FileUtils.mkdir_p(Padrino.root('log')) unless File.exist?(Padrino.root('log'))
|
||||
File.new(Padrino.root('log', "#{Padrino.env}.log"), 'a+')
|
||||
when :null then StringIO.new
|
||||
when :stdout then $stdout
|
||||
when :stderr then $stderr
|
||||
else config[:stream] # return itself, probabilly is a custom stream.
|
||||
end
|
||||
|
||||
Padrino::Logger.new(config.merge(:stream => stream))
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# To initialize the logger you create a new object, proxies to set_log.
|
||||
#
|
||||
# @param [Hash] options
|
||||
#
|
||||
# @option options [Symbol] :stream ($stdout)
|
||||
# Either an IO object or a name of a logfile. Defaults to $stdout
|
||||
#
|
||||
# @option options [Symbol] :log_level (:production in the production environment and :debug otherwise)
|
||||
# The log level from, e.g. :fatal or :info.
|
||||
#
|
||||
# @option options [Symbol] :auto_flush (true)
|
||||
# Whether the log should automatically flush after new messages are
|
||||
# added. Defaults to true.
|
||||
#
|
||||
# @option options [Symbol] :format_datetime (" [%d/%b/%Y %H:%M:%S] ")
|
||||
# Format of datetime.
|
||||
#
|
||||
# @option options [Symbol] :format_message ("%s -%s%s")
|
||||
# Format of message.
|
||||
#
|
||||
# @option options [Symbol] :log_static (false)
|
||||
# Whether or not to show log messages for static files.
|
||||
#
|
||||
# @option options [Symbol] :colorize_logging (true)
|
||||
# Whether or not to colorize log messages. Defaults to: true.
|
||||
#
|
||||
def initialize(options={})
|
||||
@buffer = []
|
||||
@auto_flush = options.has_key?(:auto_flush) ? options[:auto_flush] : true
|
||||
@level = options[:log_level] ? Padrino::Logger::Levels[options[:log_level]] : Padrino::Logger::Levels[:debug]
|
||||
@log = options[:stream] || $stdout
|
||||
@log.sync = true
|
||||
@format_datetime = options[:format_datetime] || "%d/%b/%Y %H:%M:%S"
|
||||
@format_message = options[:format_message] || "%s - %s %s"
|
||||
@log_static = options.has_key?(:log_static) ? options[:log_static] : false
|
||||
@colorize_logging = options.has_key?(:colorize_logging) ? options[:colorize_logging] : true
|
||||
colorize! if @colorize_logging
|
||||
end
|
||||
|
||||
##
|
||||
# Flush the entire buffer to the log object.
|
||||
#
|
||||
def flush
|
||||
return unless @buffer.size > 0
|
||||
@@mutex.synchronize do
|
||||
@log.write(@buffer.join(''))
|
||||
@buffer.clear
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Close and remove the current log object.
|
||||
#
|
||||
# @return [NilClass]
|
||||
#
|
||||
def close
|
||||
flush
|
||||
@log.close if @log.respond_to?(:close) && !@log.tty?
|
||||
@log = nil
|
||||
end
|
||||
|
||||
##
|
||||
# Adds a message to the log - for compatibility with other loggers.
|
||||
#
|
||||
def add(level, message = nil)
|
||||
write(message)
|
||||
end
|
||||
|
||||
##
|
||||
# Directly append message to the log.
|
||||
#
|
||||
# @param [String] message
|
||||
# The message
|
||||
#
|
||||
def <<(message = nil)
|
||||
message << "\n" unless message[-1] == ?\n
|
||||
@@mutex.synchronize {
|
||||
@buffer << message
|
||||
}
|
||||
flush if @auto_flush
|
||||
message
|
||||
end
|
||||
alias :write :<<
|
||||
|
||||
def format(message, level)
|
||||
@format_message % [stylized_level(level), colorize(Time.now.strftime(@format_datetime), :yellow), message.to_s.strip]
|
||||
end
|
||||
|
||||
##
|
||||
# Padrino::Logger::Rack forwards every request to an +app+ given, and
|
||||
# logs a line in the Apache common log format to the +logger+, or
|
||||
# rack.errors by default.
|
||||
#
|
||||
class Rack
|
||||
def initialize(app, uri_root)
|
||||
@app = app
|
||||
@uri_root = uri_root.sub(/\/$/,"")
|
||||
end
|
||||
|
||||
def call(env)
|
||||
env['rack.logger'] = Padrino.logger
|
||||
began_at = Time.now
|
||||
status, header, body = @app.call(env)
|
||||
log(env, status, header, began_at) if logger.debug?
|
||||
[status, header, body]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def log(env, status, header, began_at)
|
||||
return if env['sinatra.static_file'] && (!logger.respond_to?(:log_static) || !logger.log_static)
|
||||
logger.bench(
|
||||
env["REQUEST_METHOD"],
|
||||
began_at,
|
||||
[
|
||||
@uri_root.to_s,
|
||||
env["PATH_INFO"],
|
||||
env["QUERY_STRING"].empty? ? "" : "?" + env["QUERY_STRING"],
|
||||
' - ',
|
||||
logger.colorize(status.to_s[0..3], :bold),
|
||||
' ',
|
||||
code_to_name(status)
|
||||
] * '',
|
||||
:debug,
|
||||
:magenta
|
||||
)
|
||||
end
|
||||
|
||||
def code_to_name(status)
|
||||
::Rack::Utils::HTTP_STATUS_CODES[status.to_i] || ''
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Kernel
|
||||
##
|
||||
# Define a logger available every where in our app
|
||||
#
|
||||
def logger
|
||||
Padrino.logger
|
||||
end
|
||||
end
|
|
@ -1,58 +0,0 @@
|
|||
module Padrino
|
||||
module Module
|
||||
attr_accessor :root
|
||||
|
||||
##
|
||||
# Register this module as being loaded from a gem. This automatically
|
||||
# sets the root and therefore the dependency paths correctly.
|
||||
#
|
||||
# @param [String] name
|
||||
# The name of the gem. Has to be the name as stated in the gemspec.
|
||||
#
|
||||
# @returns the gems root.
|
||||
def gem!(name)
|
||||
self.root = Padrino.gem(name, self)
|
||||
end
|
||||
|
||||
##
|
||||
# Helper method for file references within a Padrino module.
|
||||
#
|
||||
# @param [Array<String>] args
|
||||
# The directories to join to {Module.root}.
|
||||
#
|
||||
# @return [String]
|
||||
# The absolute path.
|
||||
#
|
||||
# @example
|
||||
# module MyModule
|
||||
# extend Padrino::Module
|
||||
# gem! 'my_gem'
|
||||
# end
|
||||
# Module.root!
|
||||
def root(*args)
|
||||
File.expand_path(File.join(@root, *args))
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the list of path globs to load as dependencies.
|
||||
# Appends custom dependency patterns to the be loaded for Padrino.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
# The dependency paths.
|
||||
#
|
||||
# @example
|
||||
# module MyModule
|
||||
# extend Padrino::Module
|
||||
# gem! 'my_gem'
|
||||
# end
|
||||
#
|
||||
# Module.dependency_paths << "#{MyModule.root}/uploaders/*.rb"
|
||||
#
|
||||
def dependency_paths
|
||||
[
|
||||
"#{root}/lib/**/*.rb", "#{root}/shared/lib/**/*.rb",
|
||||
"#{root}/models/**/*.rb", "#{root}/shared/models/**/*.rb"
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,239 +0,0 @@
|
|||
module Padrino
|
||||
##
|
||||
# Represents a particular mounted Padrino application.
|
||||
# Stores the name of the application (app folder name) and url mount path.
|
||||
#
|
||||
# @example
|
||||
# Mounter.new("blog_app", :app_class => "Blog").to("/blog")
|
||||
# Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
|
||||
#
|
||||
class Mounter
|
||||
DEFAULT_CASCADE = [404, 405]
|
||||
class MounterException < RuntimeError
|
||||
end
|
||||
|
||||
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host, :cascade
|
||||
|
||||
##
|
||||
# @param [String, Padrino::Application] name
|
||||
# The app name or the {Padrino::Application} class.
|
||||
#
|
||||
# @param [Hash] options
|
||||
# @option options [Symbol] :app_class (Detected from name)
|
||||
# @option options [Symbol] :app_file (Automatically detected)
|
||||
# @option options [Symbol] :app_obj (Detected)
|
||||
# @option options [Symbol] :app_root (Directory of :app_file)
|
||||
# @option options [Symbol] :gem The gem to load the app from (Detected from name)
|
||||
#
|
||||
def initialize(name, options={})
|
||||
@name = name.to_s
|
||||
@app_class = options[:app_class] || @name.camelize
|
||||
@gem = options[:gem] || @app_class.split("::").first.underscore
|
||||
@app_file = options[:app_file] || locate_app_file
|
||||
@app_obj = options[:app_obj] || app_constant || locate_app_object
|
||||
ensure_app_file! || ensure_app_object!
|
||||
@app_root = options[:app_root] || (@app_obj.respond_to?(:root) && @app_obj.root || File.dirname(@app_file))
|
||||
@uri_root = "/"
|
||||
@cascade = options[:cascade] ? true == options[:cascade] ? DEFAULT_CASCADE.dup : Array(options[:cascade]) : []
|
||||
Padrino::Reloader.exclude_constants << @app_class
|
||||
end
|
||||
|
||||
##
|
||||
# Registers the mounted application onto Padrino.
|
||||
#
|
||||
# @param [String] mount_url
|
||||
# Path where we mount the app.
|
||||
#
|
||||
# @example
|
||||
# Mounter.new("blog_app").to("/blog")
|
||||
#
|
||||
def to(mount_url)
|
||||
@uri_root = mount_url
|
||||
Padrino.insert_mounted_app(self)
|
||||
self
|
||||
end
|
||||
|
||||
##
|
||||
# Registers the mounted application onto Padrino for the given host.
|
||||
#
|
||||
# @param [String] mount_host
|
||||
# Host name.
|
||||
#
|
||||
# @example
|
||||
# Mounter.new("blog_app").to("/blog").host("blog.padrino.org")
|
||||
# Mounter.new("blog_app").host("blog.padrino.org")
|
||||
# Mounter.new("catch_all").host(/.*\.padrino.org/)
|
||||
#
|
||||
def host(mount_host)
|
||||
@app_host = mount_host
|
||||
Padrino.insert_mounted_app(self)
|
||||
self
|
||||
end
|
||||
|
||||
##
|
||||
# Maps Padrino application onto a Padrino::Router.
|
||||
# For use in constructing a Rack application.
|
||||
#
|
||||
# @param [Padrino::Router]
|
||||
#
|
||||
# @return [Padrino::Router]
|
||||
#
|
||||
# @example
|
||||
# @app.map_onto(router)
|
||||
#
|
||||
def map_onto(router)
|
||||
app_data, app_obj = self, @app_obj
|
||||
app_obj.set :uri_root, app_data.uri_root
|
||||
app_obj.set :app_name, app_data.app_obj.app_name.to_s
|
||||
app_obj.set :app_file, app_data.app_file unless ::File.exist?(app_obj.app_file)
|
||||
app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
|
||||
app_obj.set :public_folder, Padrino.root('public', app_data.uri_root) unless File.exist?(app_obj.public_folder)
|
||||
app_obj.set :static, File.exist?(app_obj.public_folder) if app_obj.nil?
|
||||
app_obj.set :cascade, app_data.cascade
|
||||
app_obj.setup_application! # Initializes the app here with above settings.
|
||||
router.map(:to => app_obj, :path => app_data.uri_root, :host => app_data.app_host)
|
||||
end
|
||||
|
||||
###
|
||||
# Returns the route objects for the mounted application.
|
||||
#
|
||||
def routes
|
||||
app_obj.routes
|
||||
end
|
||||
|
||||
###
|
||||
# Returns the basic route information for each named route.
|
||||
#
|
||||
# @return [Array]
|
||||
# Array of routes.
|
||||
#
|
||||
def named_routes
|
||||
app_obj.routes.map { |route|
|
||||
route_name = route.name.to_s
|
||||
route_name.sub!(/^#{route.controller} /, "") if route.controller
|
||||
name_array = "(#{route.controller ? %Q[:#{route.controller}] + ", " : ""}:#{route_name})"
|
||||
request_method = route.request_methods.first
|
||||
next if route.name.blank? || request_method == 'HEAD'
|
||||
original_path = route.original_path.is_a?(Regexp) ? route.original_path.inspect : route.original_path
|
||||
full_path = File.join(uri_root, original_path)
|
||||
OpenStruct.new(:verb => request_method, :identifier => route.name, :name => name_array, :path => full_path)
|
||||
}.compact
|
||||
end
|
||||
|
||||
##
|
||||
# Makes two Mounters equal if they have the same name and uri_root.
|
||||
#
|
||||
# @param [Padrino::Mounter] other
|
||||
#
|
||||
def ==(other)
|
||||
other.is_a?(Mounter) && self.app_class == other.app_class && self.uri_root == other.uri_root
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Padrino::Application]
|
||||
# the class object for the app if defined, nil otherwise.
|
||||
#
|
||||
def app_constant
|
||||
klass = Object
|
||||
for piece in app_class.split("::")
|
||||
piece = piece.to_sym
|
||||
if klass.const_defined?(piece)
|
||||
klass = klass.const_get(piece)
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
klass
|
||||
end
|
||||
|
||||
protected
|
||||
##
|
||||
# Locates and requires the file to load the app constant.
|
||||
#
|
||||
def locate_app_object
|
||||
@_app_object ||= begin
|
||||
ensure_app_file!
|
||||
Padrino.require_dependencies(app_file)
|
||||
app_constant
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the determined location of the mounted application main file.
|
||||
#
|
||||
def locate_app_file
|
||||
candidates = []
|
||||
candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s)
|
||||
candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
||||
candidates << Padrino.mounted_root(name.downcase, "app.rb")
|
||||
simple_name = name.split("::").last.downcase
|
||||
mod_name = name.split("::")[0..-2].join("::")
|
||||
Padrino.modules.each do |mod|
|
||||
if mod.name == mod_name
|
||||
candidates << mod.root(simple_name, "app.rb")
|
||||
end
|
||||
end
|
||||
candidates << Padrino.root("app", "app.rb")
|
||||
candidates.find { |candidate| File.exist?(candidate) }
|
||||
end
|
||||
|
||||
###
|
||||
# Raises an exception unless app_file is located properly.
|
||||
#
|
||||
def ensure_app_file!
|
||||
message = "Unable to locate source file for app '#{app_class}', try with :app_file => '/path/app.rb'"
|
||||
raise MounterException, message unless @app_file
|
||||
end
|
||||
|
||||
###
|
||||
# Raises an exception unless app_obj is defined properly.
|
||||
#
|
||||
def ensure_app_object!
|
||||
message = "Unable to locate app for '#{app_class}', try with :app_class => 'MyAppClass'"
|
||||
raise MounterException, message unless @app_obj
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
attr_writer :mounted_root # Set root directory where padrino searches mounted apps
|
||||
|
||||
##
|
||||
# @param [Array] args
|
||||
#
|
||||
# @return [String]
|
||||
# the root to the mounted apps base directory.
|
||||
#
|
||||
def mounted_root(*args)
|
||||
Padrino.root(@mounted_root ||= "", *args)
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Array]
|
||||
# the mounted padrino applications (MountedApp objects)
|
||||
#
|
||||
def mounted_apps
|
||||
@mounted_apps ||= []
|
||||
end
|
||||
|
||||
##
|
||||
# Inserts a Mounter object into the mounted applications (avoids duplicates).
|
||||
#
|
||||
# @param [Padrino::Mounter] mounter
|
||||
#
|
||||
def insert_mounted_app(mounter)
|
||||
Padrino.mounted_apps.push(mounter) unless Padrino.mounted_apps.include?(mounter)
|
||||
end
|
||||
|
||||
##
|
||||
# Mounts a new sub-application onto Padrino project.
|
||||
#
|
||||
# @see Padrino::Mounter#new
|
||||
#
|
||||
# @example
|
||||
# Padrino.mount("blog_app").to("/blog")
|
||||
#
|
||||
def mount(name, options={})
|
||||
Mounter.new(name, options)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,250 +0,0 @@
|
|||
require 'pathname'
|
||||
require 'padrino-core/reloader/rack'
|
||||
require 'padrino-core/reloader/storage'
|
||||
|
||||
module Padrino
|
||||
##
|
||||
# High performance source code reloader middleware
|
||||
#
|
||||
module Reloader
|
||||
##
|
||||
# This reloader is suited for use in a many environments because each file
|
||||
# will only be checked once and only one system call to stat(2) is made.
|
||||
#
|
||||
# Please note that this will not reload files in the background, and does so
|
||||
# only when explicitly invoked.
|
||||
#
|
||||
extend self
|
||||
|
||||
# The modification times for every file in a project.
|
||||
MTIMES = {}
|
||||
|
||||
##
|
||||
# Specified folders can be excluded from the code reload detection process.
|
||||
# Default excluded directories at Padrino.root are: test, spec, features, tmp, config, db and public
|
||||
#
|
||||
def exclude
|
||||
@_exclude ||= Set.new %w(test spec tmp features config public db).map{ |path| Padrino.root(path) }
|
||||
end
|
||||
|
||||
##
|
||||
# Specified constants can be excluded from the code unloading process.
|
||||
#
|
||||
def exclude_constants
|
||||
@_exclude_constants ||= Set.new
|
||||
end
|
||||
|
||||
##
|
||||
# Specified constants can be configured to be reloaded on every request.
|
||||
# Default included constants are: [none]
|
||||
#
|
||||
def include_constants
|
||||
@_include_constants ||= Set.new
|
||||
end
|
||||
|
||||
##
|
||||
# Reload apps and files with changes detected.
|
||||
#
|
||||
def reload!
|
||||
rotation do |file|
|
||||
next unless file_changed?(file)
|
||||
reload_special(file) || reload_regular(file)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Remove files and classes loaded with stat
|
||||
#
|
||||
def clear!
|
||||
MTIMES.clear
|
||||
Storage.clear!
|
||||
end
|
||||
|
||||
##
|
||||
# Returns true if any file changes are detected.
|
||||
#
|
||||
def changed?
|
||||
rotation do |file|
|
||||
break true if file_changed?(file)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# We lock dependencies sets to prevent reloading of protected constants
|
||||
#
|
||||
def lock!
|
||||
klasses = ObjectSpace.classes do |klass|
|
||||
klass._orig_klass_name.split('::').first
|
||||
end
|
||||
klasses |= Padrino.mounted_apps.map(&:app_class)
|
||||
exclude_constants.merge(klasses)
|
||||
end
|
||||
|
||||
##
|
||||
# A safe Kernel::require which issues the necessary hooks depending on results
|
||||
#
|
||||
def safe_load(file, options={})
|
||||
began_at = Time.now
|
||||
file = figure_path(file)
|
||||
return unless options[:force] || file_changed?(file)
|
||||
|
||||
Storage.prepare(file) # might call #safe_load recursively
|
||||
logger.devel(file_new?(file) ? :loading : :reload, began_at, file)
|
||||
begin
|
||||
with_silence{ require(file) }
|
||||
Storage.commit(file)
|
||||
update_modification_time(file)
|
||||
rescue Exception => e
|
||||
unless options[:cyclic]
|
||||
logger.error "#{e.class}: #{e.message}; #{e.backtrace.first}"
|
||||
logger.error "Failed to load #{file}; removing partially defined constants"
|
||||
end
|
||||
Storage.rollback(file)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Removes the specified class and constant.
|
||||
#
|
||||
def remove_constant(const)
|
||||
return if constant_excluded?(const)
|
||||
base, _, object = const.to_s.rpartition('::')
|
||||
base = base.empty? ? Object : base.constantize
|
||||
base.send :remove_const, object
|
||||
logger.devel "Removed constant #{const} from #{base}"
|
||||
rescue NameError
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the list of special tracked files for Reloader.
|
||||
#
|
||||
def special_files
|
||||
@special_files ||= Set.new
|
||||
end
|
||||
|
||||
##
|
||||
# Sets the list of special tracked files for Reloader.
|
||||
#
|
||||
def special_files=(files)
|
||||
@special_files = Set.new(files)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# Returns absolute path of the file.
|
||||
#
|
||||
def figure_path(file)
|
||||
return file if Pathname.new(file).absolute?
|
||||
$LOAD_PATH.each do |path|
|
||||
found = File.join(path, file)
|
||||
return File.expand_path(found) if File.file?(found)
|
||||
end
|
||||
file
|
||||
end
|
||||
|
||||
##
|
||||
# Reloads the file if it's special. For now it's only I18n locale files.
|
||||
#
|
||||
def reload_special(file)
|
||||
return unless special_files.any?{ |f| File.identical?(f, file) }
|
||||
if defined?(I18n)
|
||||
began_at = Time.now
|
||||
I18n.reload!
|
||||
update_modification_time(file)
|
||||
logger.devel :reload, began_at, file
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Reloads ruby file and applications dependent on it.
|
||||
#
|
||||
def reload_regular(file)
|
||||
apps = mounted_apps_of(file)
|
||||
if apps.present?
|
||||
apps.each { |app| app.app_obj.reload! }
|
||||
update_modification_time(file)
|
||||
else
|
||||
safe_load(file)
|
||||
reloadable_apps.each do |app|
|
||||
app.app_obj.reload! if app.app_obj.dependencies.include?(file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
# Macro for mtime update.
|
||||
#
|
||||
def update_modification_time(file)
|
||||
MTIMES[file] = File.mtime(file)
|
||||
end
|
||||
|
||||
###
|
||||
# Returns true if the file is new or it's modification time changed.
|
||||
#
|
||||
def file_changed?(file)
|
||||
file_new?(file) || File.mtime(file) > MTIMES[file]
|
||||
end
|
||||
|
||||
###
|
||||
# Returns true if the file is new.
|
||||
#
|
||||
def file_new?(file)
|
||||
MTIMES[file].nil?
|
||||
end
|
||||
|
||||
##
|
||||
# Return the mounted_apps providing the app location.
|
||||
# Can be an array because in one app.rb we can define multiple Padrino::Application.
|
||||
#
|
||||
def mounted_apps_of(file)
|
||||
Padrino.mounted_apps.select { |app| File.identical?(file, app.app_file) }
|
||||
end
|
||||
|
||||
##
|
||||
# Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths
|
||||
# and monitors them for any changes.
|
||||
#
|
||||
def rotation
|
||||
files_for_rotation.each do |file|
|
||||
file = File.expand_path(file)
|
||||
next if Reloader.exclude.any? { |base| file.start_with?(base) } || !File.file?(file)
|
||||
yield file
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
##
|
||||
# Creates an array of paths for use in #rotation.
|
||||
#
|
||||
def files_for_rotation
|
||||
files = Set.new
|
||||
Padrino.load_paths.each{ |path| files += Dir.glob("#{path}/**/*.rb") }
|
||||
reloadable_apps.each do |app|
|
||||
files << app.app_file
|
||||
files += app.app_obj.dependencies
|
||||
end
|
||||
files + special_files
|
||||
end
|
||||
|
||||
def constant_excluded?(const)
|
||||
(exclude_constants - include_constants).any?{ |c| const._orig_klass_name.start_with?(c) }
|
||||
end
|
||||
|
||||
def reloadable_apps
|
||||
Padrino.mounted_apps.select{ |app| app.app_obj.respond_to?(:reload) && app.app_obj.reload? }
|
||||
end
|
||||
|
||||
##
|
||||
# Disables output, yields block, switches output back.
|
||||
#
|
||||
def with_silence
|
||||
verbosity_level, $-v = $-v, nil
|
||||
yield
|
||||
ensure
|
||||
$-v = verbosity_level
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
module Padrino
|
||||
module Reloader
|
||||
##
|
||||
# This class acts as a Rack middleware to be added to the application stack.
|
||||
# This middleware performs a check and reload for source files at the start
|
||||
# of each request, but also respects a specified cool down time
|
||||
# during which no further action will be taken.
|
||||
#
|
||||
class Rack
|
||||
def initialize(app, cooldown=1)
|
||||
@app = app
|
||||
@cooldown = cooldown
|
||||
@last = (Time.now - cooldown)
|
||||
end
|
||||
|
||||
# Invoked in order to perform the reload as part of the request stack.
|
||||
def call(env)
|
||||
if @cooldown && Time.now > @last + @cooldown
|
||||
Thread.list.size > 1 ? Thread.exclusive { Padrino.reload! } : Padrino.reload!
|
||||
@last = Time.now
|
||||
end
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,55 +0,0 @@
|
|||
module Padrino
|
||||
module Reloader
|
||||
module Storage
|
||||
extend self
|
||||
|
||||
def clear!
|
||||
files.each_key do |file|
|
||||
remove(file)
|
||||
$LOADED_FEATURES.delete(file)
|
||||
end
|
||||
@files = {}
|
||||
end
|
||||
|
||||
def remove(name)
|
||||
file = files[name] || return
|
||||
file[:constants].each{ |constant| Reloader.remove_constant(constant) }
|
||||
file[:features].each{ |feature| $LOADED_FEATURES.delete(feature) }
|
||||
files.delete(name)
|
||||
end
|
||||
|
||||
def prepare(name)
|
||||
file = remove(name)
|
||||
@old_entries ||= {}
|
||||
@old_entries[name] = {
|
||||
:constants => ObjectSpace.classes,
|
||||
:features => old_features = Set.new($LOADED_FEATURES.dup)
|
||||
}
|
||||
features = file && file[:features] || []
|
||||
features.each{ |feature| Reloader.safe_load(feature, :force => true) }
|
||||
$LOADED_FEATURES.delete(name) if old_features.include?(name)
|
||||
end
|
||||
|
||||
def commit(name)
|
||||
entry = {
|
||||
:constants => ObjectSpace.new_classes(@old_entries[name][:constants]),
|
||||
:features => Set.new($LOADED_FEATURES) - @old_entries[name][:features] - [name]
|
||||
}
|
||||
files[name] = entry
|
||||
@old_entries.delete(name)
|
||||
end
|
||||
|
||||
def rollback(name)
|
||||
new_constants = ObjectSpace.new_classes(@old_entries[name][:constants])
|
||||
new_constants.each{ |klass| Reloader.remove_constant(klass) }
|
||||
@old_entries.delete(name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def files
|
||||
@files ||= {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,94 +0,0 @@
|
|||
module Padrino
|
||||
##
|
||||
# This class is an extended version of Rack::URLMap.
|
||||
#
|
||||
# Padrino::Router like Rack::URLMap dispatches in such a way that the
|
||||
# longest paths are tried first, since they are most specific.
|
||||
#
|
||||
# Features:
|
||||
#
|
||||
# * Map a path to the specified App
|
||||
# * Ignore server names (this solve issues with vhost and domain aliases)
|
||||
# * Use hosts instead of server name for mappings (this help us with our vhost and domain aliases)
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# routes = Padrino::Router.new do
|
||||
# map(:path => "/", :to => PadrinoWeb, :host => "padrino.local")
|
||||
# map(:path => "/", :to => Admin, :host => "admin.padrino.local")
|
||||
# end
|
||||
# run routes
|
||||
#
|
||||
# routes = Padrino::Router.new do
|
||||
# map(:path => "/", :to => PadrinoWeb, :host => /*.padrino.local/)
|
||||
# end
|
||||
# run routes
|
||||
#
|
||||
# @api semipublic
|
||||
class Router
|
||||
def initialize(*mapping, &block)
|
||||
@mapping = []
|
||||
mapping.each { |m| map(m) }
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
|
||||
##
|
||||
# Map a route path and host to a specified application.
|
||||
#
|
||||
# @param [Hash] options
|
||||
# The options to map.
|
||||
# @option options [Sinatra::Application] :to
|
||||
# The class of the application to mount.
|
||||
# @option options [String] :path ("/")
|
||||
# The path to map the specified application.
|
||||
# @option options [String] :host
|
||||
# The host to map the specified application.
|
||||
#
|
||||
# @example
|
||||
# map(:path => "/", :to => PadrinoWeb, :host => "padrino.local")
|
||||
#
|
||||
# @return [Array] The sorted route mappings.
|
||||
# @api semipublic
|
||||
def map(options={})
|
||||
path = options[:path] || "/"
|
||||
host = options[:host]
|
||||
app = options[:to]
|
||||
|
||||
raise ArgumentError, "paths need to start with /" if path[0] != ?/
|
||||
raise ArgumentError, "app is required" if app.nil?
|
||||
|
||||
path = path.chomp('/')
|
||||
match = Regexp.new("^#{Regexp.quote(path).gsub('/', '/+')}(.*)", nil, 'n')
|
||||
host = Regexp.new("^#{Regexp.quote(host)}$", true, 'n') unless host.nil? || host.is_a?(Regexp)
|
||||
|
||||
@mapping << [host, path, match, app]
|
||||
end
|
||||
|
||||
# The call handler setup to route a request given the mappings specified.
|
||||
def call(env)
|
||||
began_at = Time.now
|
||||
path_info = env["PATH_INFO"].to_s
|
||||
script_name = env['SCRIPT_NAME']
|
||||
http_host = env['HTTP_HOST']
|
||||
last_result = nil
|
||||
|
||||
@mapping.each do |host, path, match, app|
|
||||
next unless host.nil? || http_host =~ host
|
||||
next unless path_info =~ match && rest = $1
|
||||
next unless rest.empty? || rest[0] == ?/
|
||||
|
||||
rest = "/" if rest.empty?
|
||||
|
||||
last_result = app.call(env.merge('SCRIPT_NAME' => script_name + path, 'PATH_INFO' => rest))
|
||||
|
||||
cascade_setting = app.respond_to?(:cascade) ? app.cascade : true
|
||||
cascade_statuses = cascade_setting.respond_to?(:include?) ? cascade_setting : Mounter::DEFAULT_CASCADE
|
||||
break unless cascade_setting && cascade_statuses.include?(last_result[0])
|
||||
end
|
||||
last_result || begin
|
||||
Padrino::Logger::Rack.new(nil,'/').send(:log, env, 404, {}, began_at) if logger.debug?
|
||||
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path_info}"]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,82 +0,0 @@
|
|||
module Padrino
|
||||
##
|
||||
# Runs the Padrino apps as a self-hosted server using:
|
||||
# thin, mongrel, or WEBrick in that order.
|
||||
#
|
||||
# @example
|
||||
# Padrino.run! # with these defaults => host: "127.0.0.1", port: "3000", adapter: the first found
|
||||
# Padrino.run!("0.0.0.0", "4000", "mongrel") # use => host: "0.0.0.0", port: "4000", adapter: "mongrel"
|
||||
#
|
||||
def self.run!(options={})
|
||||
Padrino.load!
|
||||
Server.start(Padrino.application, options)
|
||||
end
|
||||
|
||||
##
|
||||
# This module builds a Padrino server to run the project based on available handlers.
|
||||
#
|
||||
class Server < Rack::Server
|
||||
# Server Handlers
|
||||
Handlers = [:thin, :puma, :mongrel, :trinidad, :webrick]
|
||||
|
||||
# Starts the application on the available server with specified options.
|
||||
def self.start(app, opts={})
|
||||
options = {}.merge(opts) # We use a standard hash instead of Middleman::Util::HashWithIndifferentAccess
|
||||
options.symbolize_keys!
|
||||
options[:Host] = options.delete(:host) || '127.0.0.1'
|
||||
options[:Port] = options.delete(:port) || 3000
|
||||
options[:AccessLog] = []
|
||||
if options[:daemonize]
|
||||
options[:pid] = File.expand_path(options[:pid].blank? ? 'tmp/pids/server.pid' : opts[:pid])
|
||||
FileUtils.mkdir_p(File.dirname(options[:pid]))
|
||||
end
|
||||
options[:server] = detect_rack_handler if options[:server].blank?
|
||||
if options[:options].is_a?(Array)
|
||||
parsed_server_options = options.delete(:options).map { |opt| opt.split('=', 2) }.flatten
|
||||
server_options = Hash[*parsed_server_options].symbolize_keys!
|
||||
options.merge!(server_options)
|
||||
end
|
||||
new(options, app).start
|
||||
end
|
||||
|
||||
def initialize(options, app)
|
||||
@options, @app = options, app
|
||||
end
|
||||
|
||||
# Starts the application on the available server with specified options.
|
||||
def start
|
||||
puts "=> Padrino/#{Padrino.version} has taken the stage #{Padrino.env} at http://#{options[:Host]}:#{options[:Port]}"
|
||||
[:INT, :TERM].each { |sig| trap(sig) { exit } }
|
||||
super
|
||||
ensure
|
||||
puts "<= Padrino leaves the gun, takes the cannoli" unless options[:daemonize]
|
||||
end
|
||||
|
||||
# The application the server will run.
|
||||
def app
|
||||
@app
|
||||
end
|
||||
alias :wrapped_app :app
|
||||
|
||||
def options
|
||||
@options
|
||||
end
|
||||
|
||||
private
|
||||
# Detects the supported handler to use.
|
||||
#
|
||||
# @example
|
||||
# detect_rack_handler => <ThinHandler>
|
||||
#
|
||||
def self.detect_rack_handler
|
||||
Handlers.each do |handler|
|
||||
begin
|
||||
return handler if Rack::Handler.get(handler.to_s.downcase)
|
||||
rescue LoadError
|
||||
rescue NameError
|
||||
end
|
||||
end
|
||||
fail "Server handler (#{Handlers.join(', ')}) not found."
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,259 +0,0 @@
|
|||
##
|
||||
# This file loads certain extensions required by Padrino from ActiveSupport.
|
||||
#
|
||||
require 'active_support/core_ext/module/aliasing' # alias_method_chain
|
||||
require 'active_support/core_ext/hash/reverse_merge' # reverse_merge
|
||||
require 'active_support/core_ext/hash/keys' # symbolize_keys
|
||||
require 'active_support/core_ext/hash/indifferent_access' # params[:foo]
|
||||
require 'active_support/core_ext/hash/slice' # slice
|
||||
require 'active_support/core_ext/object/blank' # present?
|
||||
require 'active_support/core_ext/array/extract_options' # extract_options
|
||||
require 'active_support/inflector/methods' # constantize
|
||||
require 'active_support/inflector/inflections' # pluralize
|
||||
require 'active_support/core_ext/string/output_safety' # SafeBuffer and html_safe
|
||||
require 'active_support/inflections' # load default inflections
|
||||
require 'yaml' unless defined?(YAML) # load yaml for i18n
|
||||
require 'win32console' if RUBY_PLATFORM =~ /(win|m)32/ # ruby color support for win
|
||||
|
||||
##
|
||||
# This is an adapted version of active_support/core_ext/string/inflections.rb
|
||||
# to prevent loading several dependencies including I18n gem.
|
||||
#
|
||||
# Issue: https://github.com/rails/rails/issues/1526
|
||||
#
|
||||
class String
|
||||
##
|
||||
# Returns the plural form of the word in the string.
|
||||
#
|
||||
# "post".pluralize # => "posts"
|
||||
# "octopus".pluralize # => "octopi"
|
||||
# "sheep".pluralize # => "sheep"
|
||||
# "words".pluralize # => "words"
|
||||
# "the blue mailman".pluralize # => "the blue mailmen"
|
||||
# "CamelOctopus".pluralize # => "CamelOctopi"
|
||||
#
|
||||
def pluralize
|
||||
ActiveSupport::Inflector.pluralize(self)
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the singular form of the word in the string.
|
||||
#
|
||||
# "posts".singularize # => "post"
|
||||
# "octopi".singularize # => "octopus"
|
||||
# "sheep".singularize # => "sheep"
|
||||
# "words".singularize # => "word"
|
||||
# "the blue mailmen".singularize # => "the blue mailman"
|
||||
# "CamelOctopi".singularize # => "CamelOctopus"
|
||||
#
|
||||
def singularize
|
||||
ActiveSupport::Inflector.singularize(self)
|
||||
end
|
||||
|
||||
##
|
||||
# +constantize+ tries to find a declared constant with the name specified
|
||||
# in the string. It raises a NameError when the name is not in CamelCase
|
||||
# or is not initialized.
|
||||
#
|
||||
# "Module".constantize # => Module
|
||||
# "Class".constantize # => Class
|
||||
#
|
||||
def constantize
|
||||
ActiveSupport::Inflector.constantize(self)
|
||||
end
|
||||
|
||||
##
|
||||
# The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
|
||||
#
|
||||
# +underscore+ will also change '::' to '/' to convert namespaces to paths.
|
||||
#
|
||||
# "ActiveRecord".underscore # => "active_record"
|
||||
# "ActiveRecord::Errors".underscore # => active_record/errors
|
||||
#
|
||||
def underscore
|
||||
ActiveSupport::Inflector.underscore(self)
|
||||
end
|
||||
|
||||
##
|
||||
# By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
|
||||
# is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
|
||||
#
|
||||
# +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
|
||||
#
|
||||
# "active_record".camelize # => "ActiveRecord"
|
||||
# "active_record".camelize(:lower) # => "activeRecord"
|
||||
# "active_record/errors".camelize # => "ActiveRecord::Errors"
|
||||
# "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
|
||||
#
|
||||
def camelize(first_letter = :upper)
|
||||
case first_letter
|
||||
when :upper then ActiveSupport::Inflector.camelize(self, true)
|
||||
when :lower then ActiveSupport::Inflector.camelize(self, false)
|
||||
end
|
||||
end
|
||||
alias_method :camelcase, :camelize
|
||||
|
||||
##
|
||||
# Create a class name from a plural table name like Rails does for table names to models.
|
||||
# Note that this returns a string and not a class. (To convert to an actual class
|
||||
# follow +classify+ with +constantize+.)
|
||||
#
|
||||
# "egg_and_hams".classify # => "EggAndHam"
|
||||
# "posts".classify # => "Post"
|
||||
#
|
||||
# Singular names are not handled correctly.
|
||||
#
|
||||
# "business".classify # => "Busines"
|
||||
#
|
||||
def classify
|
||||
ActiveSupport::Inflector.classify(self)
|
||||
end
|
||||
end
|
||||
|
||||
module ObjectSpace
|
||||
class << self
|
||||
##
|
||||
# Returns all the classes in the object space.
|
||||
# Optionally, a block can be passed, for example the following code
|
||||
# would return the classes that start with the character "A":
|
||||
#
|
||||
# ObjectSpace.classes do |klass|
|
||||
# if klass.to_s[0] == "A"
|
||||
# klass
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def classes(&block)
|
||||
rs = Set.new
|
||||
|
||||
ObjectSpace.each_object(Class).each do |klass|
|
||||
if block
|
||||
if r = block.call(klass)
|
||||
# add the returned value if the block returns something
|
||||
rs << r
|
||||
end
|
||||
else
|
||||
rs << klass
|
||||
end
|
||||
end
|
||||
|
||||
rs
|
||||
end
|
||||
|
||||
##
|
||||
# Returns a list of existing classes that are not included in "snapshot"
|
||||
# This method is useful to get the list of new classes that were loaded
|
||||
# after an event like requiring a file.
|
||||
# Usage:
|
||||
#
|
||||
# snapshot = ObjectSpace.classes
|
||||
# # require a file
|
||||
# ObjectSpace.new_classes(snapshot)
|
||||
#
|
||||
def new_classes(snapshot)
|
||||
self.classes do |klass|
|
||||
if !snapshot.include?(klass)
|
||||
klass
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# FileSet helper method for iterating and interacting with files inside a directory
|
||||
#
|
||||
module FileSet
|
||||
extend self
|
||||
##
|
||||
# Iterates over every file in the glob pattern and yields to a block
|
||||
# Returns the list of files matching the glob pattern
|
||||
# FileSet.glob('padrino-core/application/*.rb', __FILE__) { |file| load file }
|
||||
#
|
||||
def glob(glob_pattern, file_path=nil, &block)
|
||||
glob_pattern = File.join(File.dirname(file_path), glob_pattern) if file_path
|
||||
file_list = Dir.glob(glob_pattern).sort
|
||||
file_list.each { |file| block.call(file) }
|
||||
file_list
|
||||
end
|
||||
|
||||
##
|
||||
# Requires each file matched in the glob pattern into the application
|
||||
# FileSet.glob_require('padrino-core/application/*.rb', __FILE__)
|
||||
#
|
||||
def glob_require(glob_pattern, file_path=nil)
|
||||
glob(glob_pattern, file_path) { |f| require f }
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Removes indentation
|
||||
# Add colors
|
||||
#
|
||||
# @example
|
||||
# help <<-EOS.undent
|
||||
# Here my help usage
|
||||
# sample_code
|
||||
#
|
||||
# Fix
|
||||
# EOS
|
||||
# puts help.red.bold
|
||||
#
|
||||
class String
|
||||
# colorize(:red)
|
||||
def colorize(color)
|
||||
Colorizer.send(color, self)
|
||||
end
|
||||
|
||||
# Used to colorize strings for the shell
|
||||
class Colorizer
|
||||
# Returns colors integer mapping
|
||||
def self.colors
|
||||
@_colors ||= {
|
||||
:clear => 0,
|
||||
:bold => 1,
|
||||
:black => 30,
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:yellow => 33,
|
||||
:blue => 34,
|
||||
:magenta => 35,
|
||||
:cyan => 36,
|
||||
:white => 37
|
||||
}
|
||||
end
|
||||
|
||||
# Defines class level color methods
|
||||
# i.e Colorizer.red("hello")
|
||||
class << self
|
||||
Colorizer.colors.each do |color, value|
|
||||
define_method(color) do |target|
|
||||
"\e[#{value}m" << target << "\e[0m"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Strip unnecessary indentation of the front of a string
|
||||
def undent
|
||||
gsub(/^.{#{slice(/^ +/).size}}/, '')
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Make sure we can always use the class name
|
||||
# In reloader for accessing class_name Foo._orig_klass_name
|
||||
#
|
||||
class Module
|
||||
alias :_orig_klass_name :to_s
|
||||
end
|
||||
|
||||
##
|
||||
# Loads our locale configuration files
|
||||
#
|
||||
I18n.load_path += Dir["#{File.dirname(__FILE__)}/locale/*.yml"] if defined?(I18n)
|
||||
|
||||
##
|
||||
# Used to determine if this file has already been required
|
||||
#
|
||||
module SupportLite; end
|
|
@ -1,21 +0,0 @@
|
|||
module Padrino
|
||||
##
|
||||
# This module it's used for bootstrap with padrino rake
|
||||
# third party tasks, in your gem/plugin/extension you
|
||||
# need only do this:
|
||||
#
|
||||
# @example
|
||||
# Padrino::Tasks.files << yourtask.rb
|
||||
# Padrino::Tasks.files.concat(Dir["/path/to/all/my/tasks/*.rb"])
|
||||
# Padrino::Tasks.files.unshift("yourtask.rb")
|
||||
#
|
||||
module Tasks
|
||||
|
||||
##
|
||||
# Returns a list of files to handle with padrino rake
|
||||
#
|
||||
def self.files
|
||||
@files ||= []
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +0,0 @@
|
|||
#
|
||||
# Manages current Padrino version for use in gem generation.
|
||||
#
|
||||
# We put this in a separate file so you can get padrino version
|
||||
# without include full padrino core.
|
||||
#
|
||||
module Padrino
|
||||
# The version constant for the current version of Padrino.
|
||||
VERSION = '0.12.0' unless defined?(Padrino::VERSION)
|
||||
|
||||
#
|
||||
# The current Padrino version.
|
||||
#
|
||||
# @return [String]
|
||||
# The version number.
|
||||
#
|
||||
def self.version
|
||||
VERSION
|
||||
end
|
||||
end # Padrino
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env gem build
|
||||
# encoding: utf-8
|
||||
|
||||
require File.expand_path("../lib/padrino-core/version.rb", __FILE__)
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "padrino-core"
|
||||
s.rubyforge_project = "padrino-core"
|
||||
s.authors = ["Padrino Team", "Nathan Esquenazi", "Davide D'Agostino", "Arthur Chiu"]
|
||||
s.email = "padrinorb@gmail.com"
|
||||
s.summary = "The required Padrino core gem"
|
||||
s.homepage = "http://www.padrinorb.com"
|
||||
s.description = "The Padrino core gem required for use of this framework"
|
||||
s.required_rubygems_version = ">= 1.3.6"
|
||||
s.version = Padrino.version
|
||||
s.date = Time.now.strftime("%Y-%m-%d")
|
||||
s.license = "MIT"
|
||||
|
||||
s.extra_rdoc_files = Dir["*.rdoc"]
|
||||
s.files = `git ls-files`.split("\n")
|
||||
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
||||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
||||
s.require_paths = ["lib"]
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
|
||||
# TODO remove after a couple versions
|
||||
# s.post_install_message = "\e[32m" + ("*" * 20)
|
||||
# s.post_install_message << "\n UPGRADE NOTES\n\n\e[31m When upgrading, please 'enable :sessions' for each application"
|
||||
# s.post_install_message << " as shown here:\e[0m http://bit.ly/kODKMx\n"
|
||||
# s.post_install_message << "\e[31m When upgrading, please 'register Padrino::Rendering' for each application"
|
||||
# s.post_install_message << " as shown here:\e[0m https://gist.github.com/1d36a35794dbbd664ea4"
|
||||
# s.post_install_message << "\n\e[32m" + ("*" * 20) + "\n\e[0m"
|
||||
|
||||
s.add_dependency("tilt", "~> 1.4.1")
|
||||
if ENV["SINATRA_EDGE"]
|
||||
s.add_dependency("sinatra")
|
||||
else
|
||||
s.add_dependency("sinatra", "~> 1.4.2")
|
||||
end
|
||||
s.add_dependency("http_router", "~> 0.11.0")
|
||||
s.add_dependency("thor", "~> 0.17.0")
|
||||
s.add_dependency("activesupport", ">= 3.1")
|
||||
s.add_dependency("rack-protection", ">= 1.5.0")
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
# Specify your gem's dependencies in app_gem.gemspec
|
||||
gemspec
|
|
@ -1,3 +0,0 @@
|
|||
class AppGem::App < Padrino::Application
|
||||
set :version, AppGem::VERSION
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require File.expand_path('../lib/app_gem/version', __FILE__)
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.authors = ["Florian Gilcher"]
|
||||
gem.email = ["florian.gilcher@asquera.de"]
|
||||
gem.description = %q{TODO: Write a gem description}
|
||||
gem.summary = %q{TODO: Write a gem summary}
|
||||
gem.homepage = ""
|
||||
|
||||
gem.files = `git ls-files`.split($\)
|
||||
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
||||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||
gem.name = "app_gem"
|
||||
gem.require_paths = ["app", "lib"]
|
||||
gem.version = AppGem::VERSION
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'padrino'
|
||||
|
||||
module AppGem
|
||||
extend Padrino::Module
|
||||
|
||||
gem! 'app_gem'
|
||||
end
|
|
@ -1,3 +0,0 @@
|
|||
module AppGem
|
||||
VERSION = "0.0.1"
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
:test: bacon
|
||||
:mock: mocha
|
||||
:orm: datamapper
|
||||
:renderer: erb
|
||||
:script: jquery
|
|
@ -1,7 +0,0 @@
|
|||
.DS_Store
|
||||
log/**/*
|
||||
tmp/**/*
|
||||
vendor/gems/gems
|
||||
vendor/gems/specifications
|
||||
vendor/gems/doc
|
||||
vendor/gems/environment.rb
|
|
@ -1,32 +0,0 @@
|
|||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
|
||||
module LibDemo
|
||||
def self.give_me_a_random
|
||||
@rand ||= rand(100)
|
||||
end
|
||||
end
|
||||
|
||||
class Complex1Demo < Padrino::Application
|
||||
set :reload, true
|
||||
get("/old"){ "Old Sinatra Way" }
|
||||
end
|
||||
|
||||
class Complex2Demo < Padrino::Application
|
||||
set :reload, true
|
||||
get("/old"){ "Old Sinatra Way" }
|
||||
|
||||
controllers :var do
|
||||
get(:destroy){ params.inspect }
|
||||
end
|
||||
|
||||
get("/"){ "The magick number is: 12!" } # Change only the number!!!
|
||||
end
|
||||
|
||||
Complex1Demo.controllers do
|
||||
get("/"){ "Given random #{LibDemo.give_me_a_random}" }
|
||||
end
|
||||
|
||||
Complex2Demo.controllers do
|
||||
end
|
||||
|
||||
Padrino.load!
|
|
@ -1,8 +0,0 @@
|
|||
require 'resolv'
|
||||
|
||||
SystemDemo.helpers do
|
||||
def resolv
|
||||
Resolv.name
|
||||
end
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
class Kiq < ::Sinatra::Base
|
||||
set :root, '/weird'
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
class MyKlass < OpenStruct
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
class MyKlass
|
||||
class MySubKlass
|
||||
end
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
class Child < Parent
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
class Parent
|
||||
def family
|
||||
'Danes'
|
||||
end
|
||||
end
|
|
@ -1,13 +0,0 @@
|
|||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
|
||||
class RenderDemo < Padrino::Application
|
||||
set :reload, true
|
||||
end
|
||||
|
||||
RenderDemo.controllers :blog do
|
||||
get '/' do
|
||||
render 'post'
|
||||
end
|
||||
end
|
||||
|
||||
Padrino.load!
|
|
@ -1,33 +0,0 @@
|
|||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
# Remove this comment if you want do some like this: ruby RACK_ENV=test app.rb
|
||||
#
|
||||
# require 'rubygems'
|
||||
# require 'padrino-core'
|
||||
#
|
||||
|
||||
class SimpleDemo < Padrino::Application
|
||||
set :reload, true
|
||||
before { true }
|
||||
after { true }
|
||||
error(404) { "404" }
|
||||
end
|
||||
|
||||
SimpleDemo.controllers do
|
||||
get "/" do
|
||||
'The magick number is: 2767356926488785838763860464013972991031534522105386787489885890443740254365!' # Change only the number!!!
|
||||
end
|
||||
|
||||
get "/rand" do
|
||||
rand(2 ** 256).to_s
|
||||
end
|
||||
end
|
||||
|
||||
## If you want use this as a standalone app uncomment:
|
||||
#
|
||||
# Padrino.mount("SimpleDemo").to("/")
|
||||
# Padrino.run! unless Padrino.loaded? # If you enable reloader prevent to re-run the app
|
||||
#
|
||||
# Then run it from your console: ruby -I"lib" test/fixtures/apps/simple.rb
|
||||
#
|
||||
|
||||
Padrino.load!
|
|
@ -1,10 +0,0 @@
|
|||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
|
||||
class StaticDemo < Padrino::Application
|
||||
disable :reload
|
||||
def self.reload!
|
||||
fail 'reload! called'
|
||||
end
|
||||
end
|
||||
|
||||
Padrino.load!
|
|
@ -1,13 +0,0 @@
|
|||
PADRINO_ROOT = File.dirname(__FILE__) unless defined? PADRINO_ROOT
|
||||
|
||||
class SystemDemo < Padrino::Application
|
||||
set :reload, true
|
||||
end
|
||||
|
||||
SystemDemo.controllers do
|
||||
get '/' do
|
||||
resolv
|
||||
end
|
||||
end
|
||||
|
||||
Padrino.load!
|
|
@ -1 +0,0 @@
|
|||
okay
|
|
@ -1,9 +0,0 @@
|
|||
# This file will be safe loaded three times.
|
||||
# The first one fail because B and C constant are not defined
|
||||
# The second one file because B requires C constant so will not be loaded
|
||||
# The third one B and C are defined
|
||||
|
||||
# But here we need some of b.rb
|
||||
A_result = [B, C]
|
||||
|
||||
A = "A"
|
|
@ -1,4 +0,0 @@
|
|||
# But here we need some of c.rb and a.rb
|
||||
B_result = C
|
||||
|
||||
B = "B"
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue