From f642675c89f1bc12eaaba57278c59ea6e4082bd0 Mon Sep 17 00:00:00 2001 From: Jon Frisby Date: Mon, 25 Mar 2013 12:39:37 -0700 Subject: [PATCH] Make Octopress only load its configs once per process. --- Rakefile | 4 +- config.rb | 2 +- lib/octopress.rb | 21 ++++- lib/octopress/configuration.rb | 16 +++- lib/spec/fixtures/env/defaults/classic.yml | 2 + lib/spec/octopress/configuration_spec.rb | 41 ++++++++ lib/spec/octopress/octopress_spec.rb | 105 +++++++++++++++++++++ 7 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 lib/spec/fixtures/env/defaults/classic.yml create mode 100644 lib/spec/octopress/octopress_spec.rb diff --git a/Rakefile b/Rakefile index 6102a35..76b8b6a 100644 --- a/Rakefile +++ b/Rakefile @@ -20,8 +20,8 @@ require 'open3' ### Please do not change anything below if you want help -- ### otherwise, you're on your own ;-) -configurator = Octopress::Configuration.new -configuration = configurator.read_configuration +configurator = Octopress.configurator +configuration = Octopress.configuration full_stash_dir = "#{configuration[:source]}/#{configuration[:stash_dir]}" desc "Initial setup for Octopress: copies the default theme into the path of Jekyll's generator. Rake install defaults to rake install[classic] to install a different theme run rake install[some_theme_name]" diff --git a/config.rb b/config.rb index 50f5dd4..8fc13d0 100644 --- a/config.rb +++ b/config.rb @@ -2,7 +2,7 @@ $:.unshift File.expand_path("lib", File.dirname(__FILE__)) # For use/testing whe require "octopress" require 'sass-globbing' -config = Octopress::Configuration.new.read_configuration +config = Octopress.configuration project_path = File.dirname(__FILE__) project_type = :stand_alone diff --git a/lib/octopress.rb b/lib/octopress.rb index b6a5aa9..62facca 100644 --- a/lib/octopress.rb +++ b/lib/octopress.rb @@ -5,10 +5,27 @@ require "octopress/configuration" require "octopress/js_asset_manager" module Octopress + class InquirableString < String + def method_missing(name, *args, &block) + if(name =~ /^.*\?$/) + val = name.to_s.sub(/\?$/, '') + return self == val + else + super + end + end + end # Static: Fetches the Octopress environment def self.env - configurator = Octopress::Configuration.new - ENV["OCTOPRESS_ENV"] || configurator.read_config("defaults/jekyll.yml").deep_merge(configurator.read_config("site.yml"))[:env] + # Not simply memoizing the result in case the configuration changes out + # from under us at runtime... Not sure if that can happen, but just in + # case let's be conservative in our behavior here. + env_raw_tmp = (ENV["OCTOPRESS_ENV"] || self.configuration[:env]).to_s + if(env_raw_tmp != @env_raw) + @env = nil + end + @env_raw = env_raw_tmp + @env ||= InquirableString.new(@env_raw) end end diff --git a/lib/octopress/configuration.rb b/lib/octopress/configuration.rb index 15d3a3c..e5163e0 100644 --- a/lib/octopress/configuration.rb +++ b/lib/octopress/configuration.rb @@ -1,6 +1,19 @@ require 'yaml' module Octopress + def self.configurator(root_dir = Octopress::Configuration::DEFAULT_CONFIG_DIR) + @configurator ||= Configuration.new(root_dir) + end + + def self.configuration + @configuration ||= self.configurator.read_configuration + end + + def self.clear_config! + @configurator = nil + @configuration = nil + end + class Configuration DEFAULT_CONFIG_DIR = File.join(File.dirname(__FILE__), '../', '../' '_config') attr_accessor :config_directory @@ -91,10 +104,9 @@ module Octopress # # Returns a Hash of the items which were written to the Jekyll configuration file def write_configs_for_generation - config = self.read_configuration jekyll_configs = {} File.open("_config.yml", "w") do |f| - jekyll_configs = config.to_string_keys.to_yaml :canonical => false + jekyll_configs = Octopress.configuration.to_string_keys.to_yaml :canonical => false f.write(jekyll_configs) end diff --git a/lib/spec/fixtures/env/defaults/classic.yml b/lib/spec/fixtures/env/defaults/classic.yml new file mode 100644 index 0000000..5f45754 --- /dev/null +++ b/lib/spec/fixtures/env/defaults/classic.yml @@ -0,0 +1,2 @@ +--- +env: config_specified_environment diff --git a/lib/spec/octopress/configuration_spec.rb b/lib/spec/octopress/configuration_spec.rb index 8f9ceb3..8b13225 100644 --- a/lib/spec/octopress/configuration_spec.rb +++ b/lib/spec/octopress/configuration_spec.rb @@ -1,6 +1,47 @@ require 'minitest/autorun' require_relative '../../octopress' +describe Octopress do + describe ".configurator" do + before do + Octopress.clear_config! + @old_env = ENV['OCTOPRESS_ENV'] + ENV['OCTOPRESS_ENV'] = nil + end + + after do + ENV['OCTOPRESS_ENV'] = @old_env + end + + it "should accept a path pointing to a config directory" do + Octopress.configurator(File.join(File.dirname(__FILE__), '../', 'fixtures', 'env')) + + Octopress.env.must_equal 'config_specified_environment' + end + end + + describe ".configuration" do + before do + Octopress.clear_config! + @old_env = ENV['OCTOPRESS_ENV'] + ENV['OCTOPRESS_ENV'] = nil + Octopress.configurator(File.join(File.dirname(__FILE__), '../', 'fixtures', 'env')) + end + + after do + ENV['OCTOPRESS_ENV'] = @old_env + end + + subject do + Octopress.configuration + end + + it "should provide access to the specified configuration" do + subject[:env].must_equal 'config_specified_environment' + end + end +end + describe Octopress::Configuration do describe '#read_configuration' do describe "when no override" do diff --git a/lib/spec/octopress/octopress_spec.rb b/lib/spec/octopress/octopress_spec.rb new file mode 100644 index 0000000..eeae584 --- /dev/null +++ b/lib/spec/octopress/octopress_spec.rb @@ -0,0 +1,105 @@ +require 'minitest/autorun' +require_relative '../../octopress' + +describe Octopress do + describe '#env' do + describe "when ENV['OCTOPRESS_ENV'] is specified" do + before do + @old_value = ENV['OCTOPRESS_ENV'] + ENV['OCTOPRESS_ENV'] = 'some_environment' + end + + after do + ENV['OCTOPRESS_ENV'] = @old_value + end + + subject do + Octopress.env + end + + it "returns the environment as something that quacks like a string" do + subject.must_equal 'some_environment' + end + + # For the InquirableString functionality... + describe "#some_environment?" do + subject do + Octopress.env.some_environment? + end + + it "returns true when the environment is set to 'some_environment'" do + subject.must_equal true + end + end + + describe "#some_other_environment?" do + subject do + Octopress.env.some_other_environment? + end + + it "returns false when the environment is set to 'some_environment'" do + subject.must_equal false + end + end + end + + describe "when ENV['OCTOPRESS_ENV'] is NOT specified and a value is specified in config files" do + before do + @old_value = ENV['OCTOPRESS_ENV'] + ENV['OCTOPRESS_ENV'] = nil + Octopress.configurator(File.join(File.dirname(__FILE__), '..', 'fixtures', 'env')) + end + + after do + ENV['OCTOPRESS_ENV'] = @old_value + Octopress.clear_config! + end + + subject do + Octopress.env + end + + it "returns the environment as something that quacks like a string" do + subject.must_equal 'config_specified_environment' + end + + # For the InquirableString functionality... + describe "#config_specified_environment?" do + subject do + Octopress.env.config_specified_environment? + end + + it "returns true when the environment is set to 'config_specified_environment'" do + subject.must_equal true + end + end + + describe "#some_other_environment?" do + subject do + Octopress.env.some_other_environment? + end + + it "returns false when the environment is set to 'config_specified_environment'" do + subject.must_equal false + end + end + end + + describe "when the configuration value changes mid-execution" do + before do + @old_value = ENV['OCTOPRESS_ENV'] + ENV['OCTOPRESS_ENV'] = 'value_a' + end + + after do + ENV['OCTOPRESS_ENV'] = @old_value + end + + it "returns the initial environment value, then after it's changed, returns the new one" do + Octopress.env.must_equal 'value_a' + ENV['OCTOPRESS_ENV'] = 'value_b' + Octopress.env.must_equal 'value_b' + end + end + end +end