Patch for using Sinatra with default views via Rack

8 views
Skip to first unread message

Igal Koshevoy

unread,
Nov 4, 2008, 6:06:05 AM11/4/08
to sinatrarb
Sinatra fails to find its views when run via Rack unless you
explicitly specify the views path. The problem is that Sinatra is
using $0 to determine the path to the Sinatra application, but when
run via Rack, $0 is the web server (e.g., thin, passenger, etc), which
causes Sinatra to incorrectly guess the base path to the "views"
directory.

The attached patch against Sinatra 0.3.2 adds a "get_app_file" method
that tries a number of approaches to guess the Sinatra application's
path. If someone can figure out how to determine the path without
guessing, that'd be prefered.

-igal

PS: I would have submitted this as a github pull request, except that
the source for the current release isn't on github.
PPS: I would have created a Lighthouse ticket, but the "Create ticket"
button doesn't do anything when I click it with either Firefox or
Opera.

diff --git a/sinatra.rb b/sinatra.rb
--- a/lib/sinatra.rb
+++ b/lib/sinatra.rb
@@ -913,6 +913,25 @@ module Sinatra
load_default_configuration!
end

+ # Return absolute path of Sinatra application.
+ def self.get_app_file
+ path = \
+ begin
+ # Try the first caller that invoked the
Sinatra.application.
+ require 'thread'
+ Thread.current[:app_file] ||= self.caller_filenames[0]
+ rescue LoadError
+ # Try the most recent "config.ru" in stack, else fallback
to $0.
+ self.caller_filenames.find{|path| path.match(/\bconfig.ru
\b/)} || $0
+ end
+ return File.expand_path(path)
+ end
+
+ # Return the filenames in the caller's stack frames.
+ def self.caller_filenames
+ return caller[1..-1].map{|path| path.split(':')[0]}.reverse
+ end
+
# Hash of default application configuration options. When a new
# Application is created, the #options object takes its initial
values
# from here.
@@ -923,7 +942,8 @@ module Sinatra
# file, before any DSL related functions are invoked.
def self.default_options
return @default_options unless @default_options.nil?
- root = File.expand_path(File.dirname($0))
+ app_file = self.get_app_file
+ root = File.dirname(app_file)
@default_options = {
:run => true,
:port => 4567,
@@ -934,7 +954,7 @@ module Sinatra
:public => root + '/public',
:sessions => false,
:logging => true,
- :app_file => $0,
+ :app_file => app_file,
:raise_errors => false
}
load_default_options_from_command_line!
@@ -947,7 +967,7 @@ module Sinatra
# NOTE: Ignores --name so unit/spec tests can run individually
def self.load_default_options_from_command_line! #:nodoc:
# fixes issue with: gem install --test sinatra
- return if ARGV.empty? || File.basename($0) =~ /gem/
+ return if ARGV.empty? || File.basename(self.get_app_file) =~ /
gem/
require 'optparse'
OptionParser.new do |op|
op.on('-p port') { |port| default_options[:port] = port }

Markus Prinz

unread,
Nov 4, 2008, 6:20:36 AM11/4/08
to sina...@googlegroups.com

On 04.11.2008, at 12:06, Igal Koshevoy wrote:
> PS: I would have submitted this as a github pull request, except that
> the source for the current release isn't on github.

Ryan Tomayko (rtomayko on GitHub) is managing the current releases of
sinatra, and you can find the current Sinatra code here: http://github.com/rtomayko/sinatra/tree

>
> PPS: I would have created a Lighthouse ticket, but the "Create ticket"
> button doesn't do anything when I click it with either Firefox or
> Opera.

You should contact the Lighthouse team about that. I'm afraid we can
do little for you about that here.

g, Markus

Igal Koshevoy

unread,
Nov 4, 2008, 7:06:23 AM11/4/08
to sinatrarb
On Nov 4, 3:20 am, Markus Prinz <markus.pr...@nuclearsquid.com> wrote:
> On 04.11.2008, at 12:06, Igal Koshevoy wrote:
>
> > PS: I would have submitted this as a github pull request, except that
> > the source for the current release isn't on github.
>
> Ryan Tomayko (rtomayko on GitHub) is managing the current releases of  
> sinatra, and you can find the current Sinatra code here:http://github.com/rtomayko/sinatra/tree
Thanks for the assistance. I've grabbed the latest code and submitted
a pull request to Ryan for:
http://github.com/igal/sinatra_with_app_file_fix/tree/master

> > PPS: I would have created a Lighthouse ticket, but the "Create ticket"
> > button doesn't do anything when I click it with either Firefox or
> > Opera.
> You should contact the Lighthouse team about that. I'm afraid we can  
> do little for you about that here.
Ugh. The "Create ticket" button clearly doesn't work on the Sinatra
instance of Lighthouse with Firefox, although it works fine on other
Lighthouse sites like Rails and RSpec. Unfortunately, I can't find any
place on http://lighthouseapp.com/ or http://help.lighthouseapp.com/
to file bug reports for Lighthouse. As far as I can tell, they don't
seem to ... drumroll ... provide a ticketing system for it.

-igal

Nicolás Sanguinetti

unread,
Nov 4, 2008, 8:33:36 AM11/4/08
to sina...@googlegroups.com
On Tue, Nov 4, 2008 at 10:06 AM, Igal Koshevoy <ig...@pragmaticraft.com> wrote:
> Ugh. The "Create ticket" button clearly doesn't work on the Sinatra
> instance of Lighthouse with Firefox, although it works fine on other
> Lighthouse sites like Rails and RSpec. Unfortunately, I can't find any
> place on http://lighthouseapp.com/ or http://help.lighthouseapp.com/
> to file bug reports for Lighthouse. As far as I can tell, they don't
> seem to ... drumroll ... provide a ticketing system for it.

Sorry for the offtopic, but yeah, we do provide a lighthouse for
lighthosue, although it's a bit hidden =)

http://activereload.lighthouseapp.com/projects/44-lighthouse-users

But the best way to get support on lighthouse is via our support forum
(and there's a link to it in LH's footer):

http://help.lighthouseapp.com/

Best,
-foca

Blake Mizerany

unread,
Nov 4, 2008, 4:33:40 PM11/4/08
to sina...@googlegroups.com
I've updated my repo.  Please send pull-requests to rtomayko and myself (bmizerany) for patches to the gem.
--
Blake Mizerany
blake.m...@gmail.com

Igal Koshevoy

unread,
Nov 5, 2008, 4:44:18 PM11/5/08
to sinatrarb
On Nov 4, 1:33 pm, "Blake Mizerany" <blake.mizer...@gmail.com> wrote:
> I've updated my repo.  Please send pull-requests to rtomayko and myself
> (bmizerany) for patches to the gem.
Okay. I've just sent you a pull request, and sent one to Ryan the
other day.

-igal

Igal Koshevoy

unread,
Nov 5, 2008, 5:32:23 PM11/5/08
to sinatrarb
(Sorry for the offtopic post)

On Nov 4, 5:33 am, "Nicolás Sanguinetti" <godf...@gmail.com> wrote:
> Sorry for the offtopic, but yeah, we do provide a lighthouse for
> lighthosue, although it's a bit hidden =)
>
> http://activereload.lighthouseapp.com/projects/44-lighthouse-users
That's exactly what I was looking for, thanks. I've filed a number of
bugs.

> But the best way to get support on lighthouse is via our support forum
> (and there's a link to it in LH's footer):
> http://help.lighthouseapp.com/
I can't find it. The footers contain a "RECENT DISCUSSIONS" list and
the text is "vox populi is an entp production". The closest thing I
could find on that site is a link called "Create a new issue" -- but
it doesn't create issues, it's just a misnamed link for posting things
like tips and announcements to a discussion forum, which aren't
issues.

-igal

Ryan Tomayko

unread,
Nov 6, 2008, 1:10:52 PM11/6/08
to sina...@googlegroups.com

Sorry for not responding earlier (ML seems to have eaten my previous
message). I want to take a good look at this patch and discuss a bit
before merging it in. The use of caller is interesting. I'm not sure
using Thread to memoize the result is all that beneficial. Also,
assuming all rackup files will be named "config.ru" smells funny but I
don't have any great suggestions for how to make it better.

If anyone has time to do a quick review and commentary on Igal's patch,
I'd appreciate it.

Thanks,
Ryan

Igal Koshevoy

unread,
Nov 7, 2008, 2:12:51 PM11/7/08
to sina...@googlegroups.com
On Thu, Nov 6, 2008 at 10:10 AM, Ryan Tomayko <rtom...@gmail.com> wrote:
> I want to take a good look at this patch and discuss a bit
> before merging it in. The use of caller is interesting. I'm not sure
> using Thread to memoize the result is all that beneficial. Also,
> assuming all rackup files will be named "config.ru" smells funny but I
> don't have any great suggestions for how to make it better.

Thanks for reviewing the patch. I understand and respect your concerns.

I've reworked the code and submitted pull requests. The latest
solution reverts my earlier changes and instead uses code from
lib/ramaze.rb that determines the application path using caller. The
resulting diff against 0.3.2 is much cleaner, see below.

The downside to this lastest change is that if the user doesn't call
default_options in their config.ru file, it'll set the path wrong.
Ramaze avoids this by requiring users to call a "startup" method in
the rackup configuration file and thus has a reliable way of knowing
the caller. Is there any drawback to making the Sinatra
Application.initialize set this path? Will anything other than the
rackup configuration file ever try to initialize the Sinatra app?

Another possible alternative is to use Dir.pwd. Thin and Mongrel are
typically started from the base directory of the application, while
Passenger sets to the directory with the config.ru file, which happens
to be the base directory too. Using Dir.pwd would be simpler and less
magical, but does anyone know the drawbacks to this?

-igal

diff --git a/lib/sinatra.rb b/lib/sinatra.rb
index 65db13c..b710e46 100755
--- a/lib/sinatra.rb
+++ b/lib/sinatra.rb
@@ -923,7 +923,8 @@ module Sinatra


# file, before any DSL related functions are invoked.
def self.default_options
return @default_options unless @default_options.nil?
- root = File.expand_path(File.dirname($0))

+ app_file = File.expand_path(caller[0][/^(.*?):\d+/, 1])


+ root = File.dirname(app_file)
@default_options = {
:run => true,
:port => 4567,

@@ -934,7 +935,7 @@ module Sinatra

Henrik N

unread,
Nov 23, 2008, 12:05:59 PM11/23/08
to sinatrarb
I had the same issue.

Igal, your last patch doesn't quite work for me. It fixes root, but
app_file becomes the path to config.ru instead of the actual app file.

Before I found this thread, I patched like so:
http://pastie.textmate.org/private/kyrdkcq40gz6smeq8r9bmg
Also fixed root (and the derived paths) but not app_file.

I can see how it would be difficult to figure out the app_file in
Application.default_options, but perhaps the app_file can be set at a
later time, after "run Sinatra.application" has been called, if that
makes things easier? Not very familiar with the Sinatra codebase yet.

Another possible solution is to simply have a convention for the
app_file name, perhaps "#{root}/app.rb", that is assumed when $0
doesn't return anything useful.

If nothing else, doing something like what Igal suggested +
documenting that the app_file needs to be configured explicitly (and
asking the Passenger guys to update their user's guide) is probably
Good Enough.

On Nov 7, 8:12 pm, "Igal Koshevoy" <i...@pragmaticraft.com> wrote:
Reply all
Reply to author
Forward
0 new messages