diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f4e8962..df41d316 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
master
===
+* Add support for `environments` with the `-e` CLI flag. Loads additional config from `environments/envname.rb`. Removed `development?` helper in favor of `environment?(:development)`. Added `server?` helper to differentiate between build and server mode.
* Removed `with_layout`. Use loops of `page` instead.
* Removed Queryable Sitemap API
* Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead.
diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb
index 7b105629..60538431 100644
--- a/middleman-cli/lib/middleman-cli/build.rb
+++ b/middleman-cli/lib/middleman-cli/build.rb
@@ -18,6 +18,10 @@ module Middleman::Cli
namespace :build
desc 'build [options]', 'Builds the static site for deployment'
+ method_option :environment,
+ aliases: '-e',
+ default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
+ desc: 'The environment Middleman will run under'
method_option :clean,
type: :boolean,
default: true,
@@ -58,18 +62,26 @@ module Middleman::Cli
@debugging = Middleman::Cli::Base.respond_to?(:debugging) && Middleman::Cli::Base.debugging
self.had_errors = false
- self.class.shared_instance(options['verbose'], options['instrument'])
+ env = options['environment'].to_sym
+ verbose = options['verbose'] ? 0 : 1
+ instrument = options['instrument']
+
+ app = ::Middleman::Application.server.inst do
+ config[:mode] = :build
+ config[:environment] = env
+ ::Middleman::Logger.singleton(verbose, instrument)
+ end
opts = {}
opts[:glob] = options['glob'] if options.key?('glob')
opts[:clean] = options['clean']
- self.class.shared_instance.run_hook :before_build, self
+ app.run_hook :before_build, self
- action BuildAction.new(self, opts)
+ action BuildAction.new(self, app, opts)
- self.class.shared_instance.run_hook :after_build, self
- self.class.shared_instance.config_context.execute_after_build_callbacks(self)
+ app.run_hook :after_build, self
+ app.config_context.execute_after_build_callbacks(self)
if had_errors && !debugging
msg = 'There were errors during this build'
@@ -87,16 +99,6 @@ module Middleman::Cli
def exit_on_failure?
true
end
-
- # Middleman::Application singleton
- #
- # @return [Middleman::Application]
- def shared_instance(verbose=false, instrument=false)
- @_shared_instance ||= ::Middleman::Application.server.inst do
- config[:environment] = :build
- ::Middleman::Logger.singleton(verbose ? 0 : 1, instrument)
- end
- end
end
end
@@ -109,8 +111,8 @@ module Middleman::Cli
#
# @param [Middleman::Cli::Build] base
# @param [Hash] config
- def initialize(base, config={})
- @app = base.class.shared_instance
+ def initialize(base, app, config={})
+ @app = app
@source_dir = Pathname(@app.source_dir)
@build_dir = Pathname(@app.config[:build_dir])
@to_clean = Set.new
diff --git a/middleman-core/features/mount_rack.feature b/middleman-core/features/mount_rack.feature
index ab105021..dcb83146 100644
--- a/middleman-core/features/mount_rack.feature
+++ b/middleman-core/features/mount_rack.feature
@@ -47,9 +47,7 @@ Feature: Support Rack apps mounted using map
run MySinatra
end
- configure :build do
- endpoint "sinatra/index2.html", path: "/sinatra/"
- end
+ endpoint "sinatra/index2.html", path: "/sinatra/"
endpoint "dedoo.html", path: "/sinatra/derp.html"
diff --git a/middleman-core/fixtures/env-app/config.rb b/middleman-core/fixtures/env-app/config.rb
new file mode 100644
index 00000000..e69de29b
diff --git a/middleman-core/fixtures/env-app/environments/development.rb b/middleman-core/fixtures/env-app/environments/development.rb
new file mode 100644
index 00000000..bce85faf
--- /dev/null
+++ b/middleman-core/fixtures/env-app/environments/development.rb
@@ -0,0 +1 @@
+set :api_key, "dev1"
diff --git a/middleman-core/fixtures/env-app/environments/production.rb b/middleman-core/fixtures/env-app/environments/production.rb
new file mode 100644
index 00000000..1f217266
--- /dev/null
+++ b/middleman-core/fixtures/env-app/environments/production.rb
@@ -0,0 +1,2 @@
+set :api_key, "prod2"
+activate :minify_css
diff --git a/middleman-core/fixtures/env-app/source/index.html.erb b/middleman-core/fixtures/env-app/source/index.html.erb
new file mode 100644
index 00000000..4b6d6950
--- /dev/null
+++ b/middleman-core/fixtures/env-app/source/index.html.erb
@@ -0,0 +1,3 @@
+
diff --git a/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss b/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss
new file mode 100644
index 00000000..bcb115c5
--- /dev/null
+++ b/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss
@@ -0,0 +1,3 @@
+body {
+ backgroud: red;
+}
diff --git a/middleman-core/fixtures/generator-test/config.rb b/middleman-core/fixtures/generator-test/config.rb
index 9fc9561c..f3b6a505 100644
--- a/middleman-core/fixtures/generator-test/config.rb
+++ b/middleman-core/fixtures/generator-test/config.rb
@@ -51,8 +51,8 @@
# Change the images directory
# set :images_dir, "alternative_image_directory"
-# Build-specific configuration
-configure :build do
+# Production build configuration
+configure :production do
# For example, change the Compass output style for deployment
# activate :minify_css
diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb
index 64ce952e..e264ea09 100644
--- a/middleman-core/lib/middleman-core/application.rb
+++ b/middleman-core/lib/middleman-core/application.rb
@@ -31,9 +31,6 @@ require 'middleman-core/core_extensions/request'
# Custom Extension API and config.rb handling
require 'middleman-core/core_extensions/extensions'
-# Catch and show exceptions at the Rack level
-require 'middleman-core/core_extensions/show_exceptions'
-
# Core Middleman Class
module Middleman
class Application
@@ -73,9 +70,13 @@ module Middleman
# @return [String]
config.define_setting :source, 'source', 'Name of the source directory'
- # Middleman environment. Defaults to :development, set to :build by the build process
+ # Middleman mode. Defaults to :server, set to :build by the build process
# @return [String]
- config.define_setting :environment, ((ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :development), 'Middleman environment. Defaults to :development, set to :build by the build process'
+ config.define_setting :mode, ((ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :server), 'Middleman mode. Defaults to :server'
+
+ # Middleman environment. Defaults to :development
+ # @return [String]
+ config.define_setting :environment, :development, 'Middleman environment. Defaults to :development'
# Which file should be used for directory indexes
# @return [String]
@@ -139,9 +140,6 @@ module Middleman
# Basic Rack Request Handling
include Middleman::CoreExtensions::Request
- # Handle exceptions
- include Middleman::CoreExtensions::ShowExceptions
-
# Setup custom rendering
include Middleman::CoreExtensions::Rendering
@@ -179,9 +177,7 @@ module Middleman
# Setup the default values from calls to set before initialization
self.class.config.load_settings(self.class.superclass.config.all_settings)
- ::Middleman::Extensions.auto_activate[:before_sitemap].each do |ext_name|
- activate ext_name
- end
+ ::Middleman::Extensions.auto_activate(:before_sitemap, self)
# Initialize the Sitemap
@sitemap = ::Middleman::Sitemap::Store.new(self)
@@ -204,16 +200,22 @@ module Middleman
@config_context.define_singleton_method(name, &func)
end
- # Whether we're in development mode
+ # Whether we're in server mode
# @return [Boolean] If we're in dev mode
- def development?
- config[:environment] == :development
+ def server?
+ config[:mode] == :server
end
# Whether we're in build mode
- # @return [Boolean] If we're in build mode
+ # @return [Boolean] If we're in dev mode
def build?
- config[:environment] == :build
+ config[:mode] == :build
+ end
+
+ # Whether we're in a specific environment
+ # @return [Boolean]
+ def environment?(key)
+ config[:environment] == key
end
# The full path to the source directory
diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb
index ff5ffa76..96f30d1d 100644
--- a/middleman-core/lib/middleman-core/config_context.rb
+++ b/middleman-core/lib/middleman-core/config_context.rb
@@ -8,7 +8,7 @@ module Middleman
attr_reader :app
# Whitelist methods that can reach out.
- delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :root, to: :app
+ delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :files, :root, to: :app
def initialize(app, template_context_class)
@app = app
@@ -34,6 +34,14 @@ module Middleman
end
end
+ def include_environment(name)
+ path = File.dirname(__FILE__)
+ other_config = File.join(path, name.to_s)
+ if File.exist? other_config
+ instance_eval File.read(other_config), other_config, 1
+ end
+ end
+
def ready(&block)
@ready_callbacks << block
end
diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb
index 9fd5f985..e85afac3 100644
--- a/middleman-core/lib/middleman-core/core_extensions.rb
+++ b/middleman-core/lib/middleman-core/core_extensions.rb
@@ -11,6 +11,12 @@ Middleman::Extensions.register :data, auto_activate: :before_sitemap do
Middleman::CoreExtensions::Data
end
+# Catch and show exceptions at the Rack level
+Middleman::Extensions.register :show_exceptions, auto_activate: :before_configuration, modes: [:server] do
+ require 'middleman-core/core_extensions/show_exceptions'
+ Middleman::CoreExtensions::ShowExceptions
+end
+
# File Change Notifier
Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do
require 'middleman-core/core_extensions/file_watcher'
diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb
index 475024a1..7a76776c 100644
--- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb
+++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb
@@ -11,8 +11,6 @@ module Middleman
app.define_hook :instance_available
app.define_hook :after_configuration
app.define_hook :before_configuration
- app.define_hook :build_config
- app.define_hook :development_config
app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?'
app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS']
@@ -26,11 +24,11 @@ module Middleman
#
# @example
# # Only minify when building
- # configure :build do
+ # configure :production do
# activate :minify_javascript
# end
#
- # @param [String, Symbol] env The environment to run in (:build, :development)
+ # @param [String, Symbol] env The environment to run in
# @return [void]
def configure(env, &block)
send("#{env}_config", &block)
@@ -80,18 +78,19 @@ module Middleman
# Override application initialization to load `config.rb` and to call lifecycle hooks.
def initialize(&block)
- super
-
self.class.inst = self
# Search the root of the project for required files
$LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root)
+ # Evaluate a passed block if given
+ config_context.instance_exec(&block) if block_given?
+
+ super
+
::Middleman::Extension.clear_after_extension_callbacks
- ::Middleman::Extensions.auto_activate[:before_configuration].each do |ext_name|
- activate ext_name
- end
+ ::Middleman::Extensions.auto_activate(:before_configuration, self)
if config[:autoload_sprockets]
begin
@@ -102,9 +101,6 @@ module Middleman
end
end
- # Evaluate a passed block if given
- config_context.instance_exec(&block) if block_given?
-
run_hook :initialized
run_hook :before_configuration
@@ -112,19 +108,17 @@ module Middleman
# Check for and evaluate local configuration in `config.rb`
local_config = File.join(root, 'config.rb')
if File.exist? local_config
- logger.debug '== Reading: Local config'
+ logger.debug '== Reading: Local config'
config_context.instance_eval File.read(local_config), local_config, 1
end
- if build?
- run_hook :build_config
- config_context.execute_configure_callbacks(:build)
+ env_config = File.join(root, 'environments', "#{config[:environment]}.rb")
+ if File.exist? env_config
+ logger.debug "== Reading: #{config[:environment]} config"
+ config_context.instance_eval File.read(env_config), env_config, 1
end
- if development?
- run_hook :development_config
- config_context.execute_configure_callbacks(:development)
- end
+ config_context.execute_configure_callbacks(config[:environment])
run_hook :instance_available
diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb
index e83f7cfc..41e2ba0f 100644
--- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb
+++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb
@@ -37,9 +37,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
configure_i18n
- unless app.build?
- logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})"
- end
+ logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})"
# Don't output localizable files
app.ignore File.join(options[:templates_dir], '**')
diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb
index 67fad3c3..3f039ca6 100644
--- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb
+++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb
@@ -1,21 +1,14 @@
# Support rack/showexceptions during development
-module Middleman
- module CoreExtensions
- module ShowExceptions
- def self.included(app)
- # Require lib
- require 'rack/showexceptions'
+module Middleman::CoreExtensions
+ class ShowExceptions < ::Middleman::Extension
+ def initialize(app, options_hash={}, &block)
+ super
- # Whether to catch and display exceptions
- # @return [Boolean]
- app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions'
+ require 'rack/showexceptions'
+ end
- # When in dev
- app.configure :development do
- # Include middlemare
- use ::Rack::ShowExceptions if config[:show_exceptions]
- end
- end
+ def after_configuration
+ app.use ::Rack::ShowExceptions
end
end
end
diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb
index 519493be..a33bf203 100644
--- a/middleman-core/lib/middleman-core/extensions.rb
+++ b/middleman-core/lib/middleman-core/extensions.rb
@@ -14,6 +14,8 @@ module Middleman
before_configuration: []
}
+ AutoActivation = Struct.new(:name, :modes)
+
class << self
# @api private
# A hash of all registered extensions. Registered extensions are not necessarily active - this
@@ -21,12 +23,6 @@ module Middleman
# @return [Hash{Symbol => Class, Proc}] A directory of known extensions indexed by the name they were registered under. The value may be a Proc, which can be lazily called to return an extension class.
attr_reader :registered
- # @api private
- # A list of extensions that should be automatically loaded at different points in the application startup lifecycle.
- # Only internal, built-in Middleman extensions should be listed here.
- # @return [Hash{Symbol => Symbol}] A hash from event name to extension name.
- attr_reader :auto_activate
-
# Register a new extension. Choose a name which will be
# used to activate the extension in `config.rb`, like this:
#
@@ -71,7 +67,10 @@ module Middleman
raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension'
end
- @auto_activate[options[:auto_activate]] << name if options[:auto_activate]
+ if options[:auto_activate]
+ descriptor = AutoActivation.new(name, options[:modes] || :all)
+ @auto_activate[options[:auto_activate]] << descriptor
+ end
end
# @api private
@@ -106,7 +105,19 @@ module Middleman
# A flattened list of all extensions which are automatically activated
# @return [Array] A list of extension names which are automatically activated.
def auto_activated
- @auto_activate.values.flatten
+ @auto_activate.values.map(&:name).flatten
+ end
+
+ # @api private
+ # Load autoactivatable extensions for the given env.
+ # @param [Symbol] group The name of the auto_activation group.
+ # @param [Middleman::Application] app An instance of the app.
+ def auto_activate(group, app)
+ @auto_activate[group].each do |descriptor|
+ if descriptor[:modes] == :all || descriptor[:modes].include?(app.config[:mode])
+ app.activate descriptor[:name]
+ end
+ end
end
end
end
diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb
index e6f57cb4..b8519845 100644
--- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb
+++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb
@@ -30,7 +30,7 @@ module Middleman
# @param [Hash] locals
# @return [String]
def evaluate(context, locals, &block)
- return super if middleman_app.build?
+ return super unless middleman_app.server?
begin
super
diff --git a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb
index c72d8712..4ea87dc8 100644
--- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb
+++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb
@@ -29,10 +29,6 @@ Given /^"([^\"]*)" is set to "([^\"]*)"$/ do |variable, value|
}
end
-Given /^current environment is "([^\"]*)"$/ do |env|
- @current_env = env.to_sym
-end
-
Given /^the Server is running$/ do
root_dir = File.expand_path(current_dir)
@@ -45,14 +41,12 @@ Given /^the Server is running$/ do
ENV['MM_ROOT'] = root_dir
initialize_commands = @initialize_commands || []
- initialize_commands.unshift lambda {
- config[:environment] = @current_env || :development
- config[:show_exceptions] = false
- }
@server_inst = Middleman::Application.server.inst do
- initialize_commands.each do |p|
- instance_exec(&p)
+ app.initialized do
+ initialize_commands.each do |p|
+ config_context.instance_exec(&p)
+ end
end
end
diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb
index 48ccad41..a81db78b 100644
--- a/middleman-core/lib/middleman-core/template_context.rb
+++ b/middleman-core/lib/middleman-core/template_context.rb
@@ -19,7 +19,7 @@ module Middleman
attr_accessor :current_engine
# Shorthand references to global values on the app instance.
- delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, to: :app
+ delegate :config, :logger, :sitemap, :server?, :build?, :environment?, :data, :extensions, :source_dir, :root, to: :app
# Initialize a context with the current app and predefined locals and options hashes.
#