diff --git a/lib/compass/commands/create_project.rb b/lib/compass/commands/create_project.rb index 76757b8d..065abc8d 100644 --- a/lib/compass/commands/create_project.rb +++ b/lib/compass/commands/create_project.rb @@ -9,21 +9,29 @@ module Compass include Compass::Installers + attr_accessor :installer + def initialize(working_directory, options) super(working_directory, options) + installer_args = [project_template_directory, 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 installer.run(:skip_finalization => true) UpdateProject.new(working_directory, options).perform if installer.compilation_required? installer.finalize(:create => true) end - def installer - @installer ||= StandAloneInstaller.new(project_template_directory, project_directory, options) - end - def project_template_directory File.join(framework.templates_directory, "project") end diff --git a/lib/compass/commands/install_rails.rb b/lib/compass/commands/install_rails.rb deleted file mode 100644 index 6b4da241..00000000 --- a/lib/compass/commands/install_rails.rb +++ /dev/null @@ -1,97 +0,0 @@ -require File.join(File.dirname(__FILE__), 'base') -require File.join(File.dirname(__FILE__), 'create_project') - -module Compass - module Commands - class InstallRails < CreateProject - def initialize(*args) - super - end - - def perform - set_install_location - set_output_location - directory options[:stylesheets_location] - framework_templates.each do |t| - template "project/#{t}", "#{options[:stylesheets_location]}/#{t}", options - end - write_file 'config/initializers/compass.rb', initializer_contents - if has_application_layout? - next_steps - else - write_file 'app/views/layouts/application.html.haml', application_layout_contents - end - end - - def initializer_contents - %Q{require 'compass' -# If you have any compass plugins, require them here. -Sass::Plugin.options[:template_location] = { - "\#{RAILS_ROOT}#{File::SEPARATOR}#{options[:stylesheets_location]}" => "\#{RAILS_ROOT}#{File::SEPARATOR}#{options[:css_location]}" -} -Compass::Frameworks::ALL.each do |framework| - Sass::Plugin.options[:template_location][framework.stylesheets_directory] = "\#{RAILS_ROOT}#{File::SEPARATOR}#{options[:css_location]}" -end -} - end - - def application_layout_contents - %Q{!!! XML -!!! -%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"} - %head - %meta{'http-equiv' => "content-type", :content => "text/html;charset=UTF-8"} - %title= @browser_title || 'Default Browser Title' - = stylesheet_link_tag '#{stylesheet_prefix}screen.css', :media => 'screen, projection' - = stylesheet_link_tag '#{stylesheet_prefix}print.css', :media => 'print' - /[if IE] - = stylesheet_link_tag '#{stylesheet_prefix}ie.css', :media => 'screen, projection' - %body - %h1 Welcome to Compass - = yield -} - end - - def next_steps - puts < 'screen, projection' - = stylesheet_link_tag '#{stylesheet_prefix}print.css', :media => 'print' - /[if IE] - = stylesheet_link_tag '#{stylesheet_prefix}ie.css', :media => 'screen, projection' - -(you are using haml, aren't you?) -NEXTSTEPS - end - - def has_application_layout? - File.exists?(projectize('app/views/layouts/application.rhtml')) || - File.exists?(projectize('app/views/layouts/application.html.erb')) || - File.exists?(projectize('app/views/layouts/application.html.haml')) - end - - def stylesheet_prefix - if options[:css_location].length >= 19 - "#{options[:css_location][19..-1]}/" - else - nil - end - end - - def set_install_location - print "Compass recommends that you keep your stylesheets in app/stylesheets/ instead of the Sass default location of public/stylesheets/sass/.\nIs this OK? (Y/n) " - answer = gets - self.options[:stylesheets_location] = separate(answer.downcase[0] == ?n ? 'public/stylesheets/sass' : 'app/stylesheets') - end - def set_output_location - print "\nCompass recommends that you keep your compiled css in public/stylesheets/compiled/ instead the Sass default of public/stylesheets/.\nHowever, if you're exclusively using Sass, then public/stylesheets/ is recommended.\nEmit compiled stylesheets to public/stylesheets/compiled? (Y/n) " - answer = gets - self.options[:css_location] = separate(answer.downcase[0] == ?n ? 'public/stylesheets' : 'public/stylesheets/compiled') - end - end - end -end diff --git a/lib/compass/exec.rb b/lib/compass/exec.rb index 2350dd2b..e9b77d59 100644 --- a/lib/compass/exec.rb +++ b/lib/compass/exec.rb @@ -79,6 +79,7 @@ module Compass self.options[:command] ||= self.options[:project_name] ? :create_project : :update_project self.options[:environment] ||= :production self.options[:framework] ||= :compass + self.options[:project_type] ||= :stand_alone end def trim_trailing_separator(path) @@ -133,8 +134,8 @@ END require library end - opts.on('--rails', "Install compass into your Ruby on Rails project found in the current directory.") do - self.options[:command] = :install_rails + opts.on('--rails', "Sets the project type to a rails project.") do + self.options[:project_type] = :rails end opts.on('-q', '--quiet', :NONE, 'Quiet mode.') do diff --git a/lib/compass/installers.rb b/lib/compass/installers.rb index 01d5216f..3a86dff8 100644 --- a/lib/compass/installers.rb +++ b/lib/compass/installers.rb @@ -13,4 +13,5 @@ end require File.join(File.dirname(__FILE__), 'installers', 'manifest') require File.join(File.dirname(__FILE__), 'installers', 'base') require File.join(File.dirname(__FILE__), 'installers', 'stand_alone') +require File.join(File.dirname(__FILE__), 'installers', 'rails') diff --git a/lib/compass/installers/base.rb b/lib/compass/installers/base.rb index 86867b0b..f30be0b5 100644 --- a/lib/compass/installers/base.rb +++ b/lib/compass/installers/base.rb @@ -15,17 +15,21 @@ module Compass @options = options @manifest = Manifest.new(manifest_file) configure_option_with_default :logger + configure end def manifest_file @manifest_file ||= File.join(template_path, "manifest.rb") end + # Initializes the project to work with compass + def init + end + # Runs the installer. - # Every installer must conform to the installation strategy of configure, prepare, install, and then finalize. + # Every installer must conform to the installation strategy of prepare, install, and then finalize. # A default implementation is provided for each step. def run(options = {}) - configure prepare install finalize unless options[:skip_finalization] @@ -36,9 +40,13 @@ module Compass # It can be overridden it or augmented for reading config files, # prompting the user for more information, etc. def configure - [:css_dir, :sass_dir, :images_dir, :javascripts_dir].each do |opt| - configure_option_with_default opt + 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. diff --git a/lib/compass/installers/rails.rb b/lib/compass/installers/rails.rb new file mode 100644 index 00000000..f896aa65 --- /dev/null +++ b/lib/compass/installers/rails.rb @@ -0,0 +1,117 @@ +module Compass + module Installers + + class RailsInstaller < Base + + def configure + configuration_file = targetize('config/initializers/compass.rb') + if File.exists?(configuration_file) + open(configuration_file) do |config| + eval(config.read, nil, configuration_file) + end + end + end + + def init + set_sass_dir unless sass_dir + set_css_dir unless css_dir + directory css_dir + directory sass_dir + write_file 'config/initializers/compass.rb', initializer_contents + end + + def prepare + end + + def finalize(options = {}) + if options[:create] + puts <<-NEXTSTEPS + +Congratulations! Your rails project has been configured to use Compass. +Sass will automatically compile your stylesheets during the next +page request and keep them up to date when they change. +Make sure you restart your server! + +Next add these lines to the head of your layouts: + +NEXTSTEPS + end + puts stylesheet_links + puts "\n(You are using haml, aren't you?)" + end + + def sass_dir + Compass.configuration.sass_dir + end + + def css_dir + Compass.configuration.css_dir + end + + def images_dir + separate "public/images" + end + + def javascripts_dir + separate "public/javascripts" + end + + def set_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 + end + + def set_css_dir + recommended_location = separate("public/stylesheets/compiled") + default_location = separate("public/stylesheets") + puts + print %Q{Compass recommends that you keep your compiled css in #{recommended_location}/ +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 + end + + def initializer_contents + %Q{require 'compass' +# If you have any compass plugins, require them here. +Compass.configuration do |config| + config.project_path = RAILS_ROOT + config.sass_dir = "#{sass_dir}" + config.css_dir = "#{css_dir}" +end +Compass.configure_sass_plugin! +} + end + + def stylesheet_prefix + if css_dir.length >= 19 + "#{css_dir[19..-1]}/" + else + nil + end + end + + def stylesheet_links + html = "%head\n" + manifest.each_stylesheet do |stylesheet| + ss_line = " = stylesheet_link_tag '#{stylesheet_prefix}#{stylesheet.to.sub(/\.sass$/,'.css')}'" + if stylesheet.options[:media] + ss_line += ", :media => '#{stylesheet.options[:media]}'" + end + if stylesheet.options[:ie] + ss_line = " /[if IE]\n " + ss_line + end + html << ss_line + "\n" + end + html + end + end + end +end diff --git a/lib/compass/installers/stand_alone.rb b/lib/compass/installers/stand_alone.rb index 52ac28cc..ff333e83 100644 --- a/lib/compass/installers/stand_alone.rb +++ b/lib/compass/installers/stand_alone.rb @@ -12,10 +12,13 @@ module Compass super end - def prepare + def init directory "" directory css_dir directory sass_dir + end + + def prepare directory images_dir if manifest.has_image? directory javascripts_dir if manifest.has_javascript? end diff --git a/test/command_line_test.rb b/test/command_line_test.rb index 30176875..c44a5deb 100644 --- a/test/command_line_test.rb +++ b/test/command_line_test.rb @@ -47,15 +47,13 @@ class CommandLineTest < Test::Unit::TestCase within_tmp_directory do generate_rails_app("compass_rails") Dir.chdir "compass_rails" do - compass "--rails" do |responder| + compass("--rails", ".") do |responder| responder.respond_to "Is this OK? (Y/n) ", :with => "Y" - responder.respond_to "Emit compiled stylesheets to public/stylesheets/compiled? (Y/n) ", :with => "Y" + responder.respond_to "Emit compiled stylesheets to public/stylesheets/compiled/? (Y/n) ", :with => "Y" end # puts @last_result - assert_action_performed :create, "app/stylesheets/screen.sass" - assert_action_performed :create, "config/initializers/compass.rb" - assert_action_performed :create, "app/views/layouts/application.html.haml" - assert_action_performed :create, "config/initializers/compass.rb" + assert_action_performed :create, "./app/stylesheets/screen.sass" + assert_action_performed :create, "./config/initializers/compass.rb" end end rescue LoadError