Skip to content

Commit

Permalink
Merge pull request #180 from timblair/single_env
Browse files Browse the repository at this point in the history
Stop runner overwriting RACK_ENV environment variable.
  • Loading branch information
dj2 committed May 27, 2012
2 parents deb77db + c8ab75d commit 18fbc85
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 24 deletions.
13 changes: 0 additions & 13 deletions lib/goliath/application.rb
Expand Up @@ -2,19 +2,6 @@
require 'goliath/runner'
require 'goliath/rack'

# Pre-load the goliath environment so it's available as we try to parse the class.
# This means we can use Goliath.env?(:development) or Goliath.env?(:produdction) in the use statements.
#
# Note, as implmented, you have to have -e as it's own flag, you can't do -sve dev
# as it won't pickup the e flag.
env = ENV['RACK_ENV']
env ||= begin
if ((i = ARGV.index('-e')) || (i = ARGV.index('--environment')))
ARGV[i + 1]
end
end
Goliath.env = env if env

module Goliath
# The main execution class for Goliath. This will execute in the at_exit
# handler to run the server.
Expand Down
2 changes: 1 addition & 1 deletion lib/goliath/goliath.rb
Expand Up @@ -31,7 +31,7 @@ class << self
#
# @return [String] the current environment
def env
@env or fail "environment has not been set"
@env
end

# Sets the current goliath environment
Expand Down
49 changes: 46 additions & 3 deletions lib/goliath/runner.rb
Expand Up @@ -4,6 +4,44 @@
require 'log4r'

module Goliath

# The default run environment, should one not be set.
DEFAULT_ENV = :development

# The environment for a Goliath app can come from a variety of different
# sources. Due to the loading order of middleware, we must parse this out
# at load-time rather than run time.
#
# Note that, as implemented, you cannot pass -e as part of a compound flag
# (e.g. `-sve production`) as it won't be picked up. The example given would
# have to be provided as `-sv -e production`.
#
# For more detail, see: https://github.com/postrank-labs/goliath/issues/18
class EnvironmentParser

# Work out the current runtime environemnt.
#
# The sources of environment, in increasing precedence, are:
#
# 1. Default (see Goliath::DEFAULT_ENV)
# 2. RACK_ENV
# 3. -e/--environment command line options
# 4. Hard-coded call to Goliath#env=
#
# @param argv [Array] The command line arguments
# @return [Symbol] The current environemnt
def self.parse(argv = [])
env = ENV["RACK_ENV"] || Goliath::DEFAULT_ENV
if (i = argv.index('-e')) || (i = argv.index('--environment'))
env = argv[i + 1]
end
env.to_sym
end
end

# Set the environment immediately before we do anything else.
Goliath.env = Goliath::EnvironmentParser.parse(ARGV)

# The Goliath::Runner is responsible for parsing any provided options, setting up the
# rack application, creating a logger, and then executing the Goliath::Server with the loaded information.
class Runner
Expand Down Expand Up @@ -63,7 +101,9 @@ class Runner
def initialize(argv, api)
api.options_parser(options_parser, options) if api
options_parser.parse!(argv)
Goliath.env = options.delete(:env)

# We've already dealt with the environemnt, so just discard it.
options.delete(:env)

@api = api
@address = options.delete(:address)
Expand All @@ -90,7 +130,7 @@ def options_parser
:daemonize => false,
:verbose => false,
:log_stdout => false,
:env => :development,
:env => Goliath::DEFAULT_ENV
}

@options_parser ||= OptionParser.new do |opts|
Expand All @@ -99,7 +139,10 @@ def options_parser
opts.separator ""
opts.separator "Server options:"

opts.on('-e', '--environment NAME', "Set the execution environment (prod, dev or test) (default: #{@options[:env]})") { |val| @options[:env] = val }
# The environment isn't set as part of this option parsing routine, but
# we'll leave the flag here so a call to --help shows it correctly.
opts.on('-e', '--environment NAME', "Set the execution environment (default: #{@options[:env]})") { |val| @options[:env] = val }

opts.on('-a', '--address HOST', "Bind to HOST address (default: #{@options[:address]})") { |addr| @options[:address] = addr }
opts.on('-p', '--port PORT', "Use PORT (default: #{@options[:port]})") { |port| @options[:port] = port.to_i }
opts.on('-S', '--socket FILE', "Bind to unix domain socket") { |v| @options[:address] = v; @options[:port] = nil }
Expand Down
28 changes: 21 additions & 7 deletions spec/unit/runner_spec.rb
Expand Up @@ -10,13 +10,6 @@
@r.stub!(:setup_logger).and_return(@log_mock)
end

after(:each) do
# Runner default env is development.
# We do need to revert to test
Goliath.env = :test
end


describe 'server execution' do
describe 'daemonization' do
it 'daemonizes if specified' do
Expand Down Expand Up @@ -140,3 +133,24 @@
end
end
end

describe Goliath::EnvironmentParser do
before(:each) do
ENV['RACK_ENV'] = nil
end

it 'returns the default environment if no other options are set' do
Goliath::EnvironmentParser.parse.should == Goliath::DEFAULT_ENV
end

it 'gives precendence to RACK_ENV over the default' do
ENV['RACK_ENV'] = 'rack_env'
Goliath::EnvironmentParser.parse.should == :rack_env
end

it 'gives precendence to command-line flag over RACK_ENV' do
ENV['RACK_ENV'] = 'rack_env'
args = %w{ -e flag_env }
Goliath::EnvironmentParser.parse(args).should == :flag_env
end
end

0 comments on commit 18fbc85

Please sign in to comment.