Separate Environments from Modes

This commit is contained in:
Thomas Reynolds 2014-06-06 15:32:00 -07:00
parent d035b449ea
commit a21dca025e
19 changed files with 113 additions and 97 deletions

View file

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

View file

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

View file

@ -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 "dedoo.html", path: "/sinatra/derp.html"

View file

@ -0,0 +1 @@
set :api_key, "dev1"

View file

@ -0,0 +1,2 @@
set :api_key, "prod2"
activate :minify_css

View file

@ -0,0 +1,3 @@
<script>
// load: <%= config[:api_key] %>
</script>

View file

@ -0,0 +1,3 @@
body {
backgroud: red;
}

View file

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

View file

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

View file

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

View file

@ -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'

View file

@ -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
@ -116,15 +112,13 @@ module Middleman
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

View file

@ -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
# Don't output localizable files
app.ignore File.join(options[:templates_dir], '**')

View file

@ -1,21 +1,14 @@
# Support rack/showexceptions during development
module Middleman
module CoreExtensions
module ShowExceptions
def self.included(app)
# Require lib
module Middleman::CoreExtensions
class ShowExceptions < ::Middleman::Extension
def initialize(app, options_hash={}, &block)
super
require 'rack/showexceptions'
# Whether to catch and display exceptions
# @return [Boolean]
app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions'
# 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

View file

@ -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<Middleman::Extension>, 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<Symbol>] 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

View file

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

View file

@ -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
app.initialized do
initialize_commands.each do |p|
instance_exec(&p)
config_context.instance_exec(&p)
end
end
end

View file

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