diff --git a/lib/compass/commands/base.rb b/lib/compass/commands/base.rb index 75e95af7..94c17d57 100644 --- a/lib/compass/commands/base.rb +++ b/lib/compass/commands/base.rb @@ -11,6 +11,10 @@ module Compass self.options = options end + def execute + perform + end + def perform raise StandardError.new("Not Implemented") end diff --git a/lib/compass/commands/create_project.rb b/lib/compass/commands/create_project.rb index 373785dc..3605af1e 100644 --- a/lib/compass/commands/create_project.rb +++ b/lib/compass/commands/create_project.rb @@ -1,7 +1,6 @@ require 'fileutils' require File.join(File.dirname(__FILE__), 'stamp_pattern') require File.join(File.dirname(__FILE__), 'update_project') -require File.join(Compass.lib_directory, 'compass', 'installers') module Compass module Commands diff --git a/lib/compass/commands/installer_command.rb b/lib/compass/commands/installer_command.rb new file mode 100644 index 00000000..b59d451b --- /dev/null +++ b/lib/compass/commands/installer_command.rb @@ -0,0 +1,31 @@ +require File.join(Compass.lib_directory, 'compass', 'installers') + +module Compass + module Commands + module InstallerCommand + include Compass::Installers + + def configure! + read_project_configuration + Compass.configuration.set_maybe(options) + Compass.configuration.default_all(installer.configuration_defaults) + Compass.configuration.set_defaults! + end + + def installer + @installer ||= case options[:project_type] + when :stand_alone + StandAloneInstaller.new *installer_args + when :rails + RailsInstaller.new *installer_args + else + raise "Unknown project type: #{options[:project_type].inspect}" + end + end + + def installer_args + [template_directory(options[:pattern]), project_directory, options] + end + end + end +end \ No newline at end of file diff --git a/lib/compass/commands/project_base.rb b/lib/compass/commands/project_base.rb index 1aba29b3..9c66bef1 100644 --- a/lib/compass/commands/project_base.rb +++ b/lib/compass/commands/project_base.rb @@ -3,6 +3,7 @@ require 'sass' require 'fileutils' require 'pathname' require File.join(File.dirname(__FILE__), 'base') +require File.join(File.dirname(__FILE__), 'installer_command') module Compass module Commands @@ -13,13 +14,21 @@ module Compass super(working_path, options) self.project_name = determine_project_name(working_path, options) Compass.configuration.project_path = determine_project_directory(working_path, options) + end + + def execute + configure! + super + end + + protected + + def configure! read_project_configuration Compass.configuration.set_maybe(options) Compass.configuration.set_defaults! end - protected - def projectize(path) File.join(project_directory, separate(path)) end @@ -42,13 +51,19 @@ module Compass # Read the configuration file for this project def read_project_configuration - if File.exists?(projectize('config.rb')) - Compass.configuration.parse(projectize('config.rb')) - elsif File.exists?(projectize('src/config.rb')) - Compass.configuration.parse(projectize('src/config.rb')) + if file = detect_configuration_file + Compass.configuration.parse(file) end end + # TODO: Deprecate the src/config.rb location. + KNOWN_CONFIG_LOCATIONS = ["config/compass.config", "config.rb", "src/config.rb"] + + # Finds the configuration file, if it exists in a known location. + def detect_configuration_file + KNOWN_CONFIG_LOCATIONS.map{|f| projectize(f)}.detect{|f| File.exists?(f)} + end + def assert_project_directory_exists! if File.exists?(project_directory) && !File.directory?(project_directory) raise Compass::FilesystemConflict.new("#{project_directory} is not a directory.") diff --git a/lib/compass/commands/stamp_pattern.rb b/lib/compass/commands/stamp_pattern.rb index c1434450..47f02b84 100644 --- a/lib/compass/commands/stamp_pattern.rb +++ b/lib/compass/commands/stamp_pattern.rb @@ -1,29 +1,17 @@ require 'fileutils' require File.join(File.dirname(__FILE__), 'base') require File.join(File.dirname(__FILE__), 'update_project') -require File.join(Compass.lib_directory, 'compass', 'installers') module Compass module Commands class StampPattern < ProjectBase - include Compass::Installers - - attr_accessor :installer + include InstallerCommand def initialize(working_path, options) super(working_path, options) - installer_args = [template_directory(options[:pattern]), project_directory, self.options] - @installer = case options[:project_type] - when :stand_alone - StandAloneInstaller.new *installer_args - when :rails - RailsInstaller.new *installer_args - else - raise "Unknown project type: #{project_type}" - end end - + # all commands must implement perform def perform installer.init diff --git a/lib/compass/commands/write_configuration.rb b/lib/compass/commands/write_configuration.rb index 8f0af86c..758fbdfc 100644 --- a/lib/compass/commands/write_configuration.rb +++ b/lib/compass/commands/write_configuration.rb @@ -4,31 +4,17 @@ module Compass module Commands class WriteConfiguration < ProjectBase + include InstallerCommand + def initialize(working_path, options) super assert_project_directory_exists! end def perform - config_file = projectize("config.rb") - if File.exists?(config_file) - if options[:force] - logger.record(:overwrite, config_file) - else - message = "#{config_file} already exists. Run with --force to overwrite." - raise Compass::FilesystemConflict.new(message) - end - else - logger.record(:create, basename(config_file)) - end - project_path, Compass.configuration.project_path = Compass.configuration.project_path, nil - open(config_file,'w') do |config| - config.puts Compass.configuration.serialize - end - Compass.configuration.project_path = project_path + installer.write_configuration_files end - end end end \ No newline at end of file diff --git a/lib/compass/configuration.rb b/lib/compass/configuration.rb index d84a5be8..db412ed4 100644 --- a/lib/compass/configuration.rb +++ b/lib/compass/configuration.rb @@ -120,12 +120,16 @@ module Compass if block_given? && (to_emit = yield(prop, value)) contents << to_emit else - contents << %Q(#{prop} = #{value.inspect}\n) unless value.nil? + contents << Configuration.serialize_property(prop, value) unless value.nil? end end contents end + def self.serialize_property(prop, value) + %Q(#{prop} = #{value.inspect}\n) + end + def to_sass_plugin_options if project_path && sass_dir && css_dir proj_sass_path = File.join(project_path, sass_dir) diff --git a/lib/compass/exec.rb b/lib/compass/exec.rb index 0ad5b9a2..7207fd26 100644 --- a/lib/compass/exec.rb +++ b/lib/compass/exec.rb @@ -194,7 +194,7 @@ END def do_command(command) command_class_name = command.to_s.split(/_/).map{|p| p.capitalize}.join('') command_class = eval("::Compass::Commands::#{command_class_name}") - command_class.new(Dir.getwd, options).perform + command_class.new(Dir.getwd, options).execute end end diff --git a/lib/compass/installers/base.rb b/lib/compass/installers/base.rb index c70b77e6..d6483fcd 100644 --- a/lib/compass/installers/base.rb +++ b/lib/compass/installers/base.rb @@ -8,7 +8,6 @@ module Compass attr_accessor :template_path, :target_path, :working_path attr_accessor :options attr_accessor :manifest - attr_accessor :css_dir, :sass_dir, :images_dir, :javascripts_dir def initialize(template_path, target_path, options = {}) @template_path = template_path @@ -17,13 +16,18 @@ module Compass @options = options @manifest = Manifest.new(manifest_file) self.logger = options[:logger] - configure end def manifest_file @manifest_file ||= File.join(template_path, "manifest.rb") end + [:css_dir, :sass_dir, :images_dir, :javascripts_dir].each do |dir| + define_method dir do + Compass.configuration.send(dir) + end + end + # Initializes the project to work with compass def init dirs = manifest.map do |entry| @@ -49,20 +53,6 @@ module Compass finalize unless options[:skip_finalization] end - # The default configure method -- it sets up directories from the options - # and corresponding default_* methods for those not found in the options hash. - # It can be overridden it or augmented for reading config files, - # prompting the user for more information, etc. - def configure - unless @configured - [:css_dir, :sass_dir, :images_dir, :javascripts_dir].each do |opt| - configure_option_with_default opt - end - end - ensure - @configured = true - end - # The default prepare method -- it is a no-op. # Generally you would create required directories, etc. def prepare diff --git a/lib/compass/installers/rails.rb b/lib/compass/installers/rails.rb index f8846b0a..3f41210f 100644 --- a/lib/compass/installers/rails.rb +++ b/lib/compass/installers/rails.rb @@ -3,29 +3,27 @@ module Compass class RailsInstaller < Base - def configure - configuration_file = targetize('config/compass.config') - if File.exists?(configuration_file) - open(configuration_file) do |config| - eval(config.read, nil, configuration_file) - end - end - Compass.configuration.set_maybe(options) + def configuration_defaults + { + :sass_dir => (sass_dir || prompt_sass_dir), + :css_dir => (css_dir || prompt_css_dir), + :images_dir => default_images_dir, + :javascripts_dir => default_javascripts_dir + } end - def init - set_sass_dir unless sass_dir - set_css_dir unless css_dir - super + def write_configuration_files + write_file targetize('config/compass.config'), config_contents + write_file targetize('config/initializers/compass.rb'), initializer_contents + end + + def config_files_exist? + File.exists?(targetize('config/compass.config')) && + File.exists?(targetize('config/initializers/compass.rb')) end def prepare - write_file(targetize('config/compass.config'), Compass.configuration.serialize do |prop, value| - if prop == :project_path - "project_path = RAILS_ROOT if defined?(RAILS_ROOT)\n" - end - end) - write_file targetize('config/initializers/compass.rb'), initializer_contents + write_configuration_files unless config_files_exist? end def finalize(options = {}) @@ -45,33 +43,25 @@ NEXTSTEPS puts "\n(You are using haml, aren't you?)" end - def sass_dir - Compass.configuration.sass_dir + def default_images_dir + separate("public/images") end - def css_dir - Compass.configuration.css_dir + def default_javascripts_dir + separate("public/javascripts") end - def images_dir - separate "public/images" - end - - def javascripts_dir - separate "public/javascripts" - end - - def set_sass_dir + def prompt_sass_dir recommended_location = separate('app/stylesheets') default_location = separate('public/stylesheets/sass') print %Q{Compass recommends that you keep your stylesheets in #{recommended_location} instead of the Sass default location of #{default_location}. Is this OK? (Y/n) } answer = gets.downcase[0] - Compass.configuration.sass_dir = answer == ?n ? default_location : recommended_location + answer == ?n ? default_location : recommended_location end - def set_css_dir + def prompt_css_dir recommended_location = separate("public/stylesheets/compiled") default_location = separate("public/stylesheets") puts @@ -80,7 +70,15 @@ instead the Sass default of #{default_location}/. However, if you're exclusively using Sass, then #{default_location}/ is recommended. Emit compiled stylesheets to #{recommended_location}/? (Y/n) } answer = gets.downcase[0] - Compass.configuration.css_dir = answer == ?n ? default_location : recommended_location + answer == ?n ? default_location : recommended_location + end + + def config_contents + Compass.configuration.serialize do |prop, value| + if prop == :project_path + "project_path = RAILS_ROOT if defined?(RAILS_ROOT)\n" + end + end end def initializer_contents diff --git a/lib/compass/installers/stand_alone.rb b/lib/compass/installers/stand_alone.rb index 2a2402a5..115600c4 100644 --- a/lib/compass/installers/stand_alone.rb +++ b/lib/compass/installers/stand_alone.rb @@ -3,46 +3,33 @@ module Compass class StandAloneInstaller < Base - def configure - if File.exists?(config_file) - Compass.configuration.parse(config_file) - elsif File.exists?(old_config_file) - Compass.configuration.parse(old_config_file) - end - super - end - def init directory targetize("") super end + def write_configuration_files + write_file targetize('config.rb'), config_contents + end + + def config_files_exist? + File.exists? targetize('config.rb') + end + + def config_contents + project_path, Compass.configuration.project_path = Compass.configuration.project_path, nil + Compass.configuration.serialize + ensure + Compass.configuration.project_path = project_path + end + def prepare + write_configuration_files unless config_files_exist? end - def default_css_dir - Compass.configuration.css_dir || "stylesheets" - end - - def default_sass_dir - Compass.configuration.sass_dir ||"src" - end - - def default_images_dir - Compass.configuration.images_dir || "images" - end - - def default_javascripts_dir - Compass.configuration.javascripts_dir || "javascripts" - end - - # Read the configuration file for this project - def config_file - @config_file ||= targetize('config.rb') - end - - def old_config_file - @old_config_file ||= targetize('src/config.rb') + # We want to rely on the defaults provided by Configuration + def configuration_defaults + {} end def finalize(options = {})