diff --git a/lib/compass/app_integration.rb b/lib/compass/app_integration.rb index 58e55913..9e81105d 100644 --- a/lib/compass/app_integration.rb +++ b/lib/compass/app_integration.rb @@ -1,5 +1,3 @@ -# If we're running inside Rails -require File.join(File.dirname(__FILE__), 'app_integration', 'rails') if defined?(ActionController::Base) - -# If we're running inside Merb -require File.join(File.dirname(__FILE__), 'app_integration', 'merb') if defined?(Merb::Plugins) +%w(stand_alone rails merb).each do |lib| + require File.join(File.dirname(__FILE__), 'app_integration', lib) +end diff --git a/lib/compass/app_integration/merb.rb b/lib/compass/app_integration/merb.rb index 90b9f826..bb460dc9 100644 --- a/lib/compass/app_integration/merb.rb +++ b/lib/compass/app_integration/merb.rb @@ -1,64 +1 @@ -# To configure Merb to use compass do the following: -# -# Add dependencies to config/dependencies.rb -# -# dependency "haml", ">=2.2.0" -# dependency "merb-haml", merb_gems_version -# dependency "chriseppstein-compass", :require_as => 'compass' -# -# -# To use a different sass stylesheets locations as is recommended by compass -# add this configuration to your configuration block: -# -# Merb::BootLoader.before_app_loads do -# Merb::Plugins.config[:compass] = { -# :stylesheets => "app/stylesheets", -# :compiled_stylesheets => "public/stylesheets/compiled" -# } -# end -# - -module Compass - def self.setup_template_location - # default the compass configuration if they didn't set it up yet. - Merb::Plugins.config[:compass] ||= {} - - # default sass stylesheet location unless configured to something else - Merb::Plugins.config[:compass][:stylesheets] ||= Merb.dir_for(:stylesheet) / "sass" - - # default sass css location unless configured to something else - Merb::Plugins.config[:compass][:compiled_stylesheets] ||= Merb.dir_for(:stylesheet) - - #define the template hash for the project stylesheets as well as the framework stylesheets. - template_location = { - Merb::Plugins.config[:compass][:stylesheets] => Merb::Plugins.config[:compass][:compiled_stylesheets] - } - Compass::Frameworks::ALL.each do |framework| - template_location[framework.stylesheets_directory] = Merb::Plugins.config[:compass][:compiled_stylesheets] - end - - # merge existing template locations if present - if Merb::Plugins.config[:sass][:template_location].is_a?(Hash) - template_location.merge!(Merb::Plugins.config[:sass][:template_location]) - Merb::Plugins.config[:sass][:template_location] = template_location - end - - #configure Sass to know about all these sass locations. - Sass::Plugin.options[:template_location] = template_location - end -end - -Merb::BootLoader.after_app_loads do - #set up sass if haml load didn't do it -- this happens when using a non-default stylesheet location. - unless defined?(Sass::Plugin) - require "sass/plugin" - if Merb::Plugins.config[:sass] - Sass::Plugin.options = Merb::Plugins.config[:sass] - # support old (deprecatd Merb::Config[:sass] option) - elsif Merb::Config[:sass] - Sass::Plugin.options = Merb::Config[:sass] - end - end - - Compass.setup_template_location -end +require File.join(File.dirname(__FILE__), 'merb', 'runtime') if defined?(Merb::Plugins) diff --git a/lib/compass/app_integration/merb/runtime.rb b/lib/compass/app_integration/merb/runtime.rb new file mode 100644 index 00000000..883c4de7 --- /dev/null +++ b/lib/compass/app_integration/merb/runtime.rb @@ -0,0 +1,63 @@ +# To configure Merb to use compass do the following: +# +# Add dependencies to config/dependencies.rb +# +# dependency "haml", ">=2.2.0" +# dependency "merb-haml", merb_gems_version +# dependency "chriseppstein-compass", :require_as => 'compass' +# +# +# To use a different sass stylesheets locations as is recommended by compass +# add this configuration to your configuration block: +# +# Merb::BootLoader.before_app_loads do +# Merb::Plugins.config[:compass] = { +# :stylesheets => "app/stylesheets", +# :compiled_stylesheets => "public/stylesheets/compiled" +# } +# end +# +module Compass + def self.setup_template_location + # default the compass configuration if they didn't set it up yet. + Merb::Plugins.config[:compass] ||= {} + + # default sass stylesheet location unless configured to something else + Merb::Plugins.config[:compass][:stylesheets] ||= Merb.dir_for(:stylesheet) / "sass" + + # default sass css location unless configured to something else + Merb::Plugins.config[:compass][:compiled_stylesheets] ||= Merb.dir_for(:stylesheet) + + #define the template hash for the project stylesheets as well as the framework stylesheets. + template_location = { + Merb::Plugins.config[:compass][:stylesheets] => Merb::Plugins.config[:compass][:compiled_stylesheets] + } + Compass::Frameworks::ALL.each do |framework| + template_location[framework.stylesheets_directory] = Merb::Plugins.config[:compass][:compiled_stylesheets] + end + + # merge existing template locations if present + if Merb::Plugins.config[:sass][:template_location].is_a?(Hash) + template_location.merge!(Merb::Plugins.config[:sass][:template_location]) + Merb::Plugins.config[:sass][:template_location] = template_location + end + + #configure Sass to know about all these sass locations. + Sass::Plugin.options[:template_location] = template_location + end +end + +Merb::BootLoader.after_app_loads do + #set up sass if haml load didn't do it -- this happens when using a non-default stylesheet location. + unless defined?(Sass::Plugin) + require "sass/plugin" + if Merb::Plugins.config[:sass] + Sass::Plugin.options = Merb::Plugins.config[:sass] + # support old (deprecatd Merb::Config[:sass] option) + elsif Merb::Config[:sass] + Sass::Plugin.options = Merb::Config[:sass] + end + end + + Compass.setup_template_location +end diff --git a/lib/compass/app_integration/rails.rb b/lib/compass/app_integration/rails.rb index 904be241..c095e889 100644 --- a/lib/compass/app_integration/rails.rb +++ b/lib/compass/app_integration/rails.rb @@ -1,12 +1,8 @@ -unless defined?(Compass::RAILS_LOADED) - Compass::RAILS_LOADED = true - require File.join(File.dirname(__FILE__), 'rails', 'action_controller') - require File.join(File.dirname(__FILE__), 'rails', 'sass_plugin') - require File.join(File.dirname(__FILE__), 'rails', 'urls') - # Wierd that this has to be re-included to pick up sub-modules. Ruby bug? - class Sass::Script::Functions::EvaluationContext - include Sass::Script::Functions - private - include ActionView::Helpers::AssetTagHelper - end +%w(configuration_defaults installer).each do |lib| + require File.join(File.dirname(__FILE__), 'rails', lib) end + +require File.join(File.dirname(__FILE__), 'rails', 'runtime') if defined?(ActionController::Base) + + + diff --git a/lib/compass/app_integration/rails/configuration_defaults.rb b/lib/compass/app_integration/rails/configuration_defaults.rb new file mode 100644 index 00000000..be44f13d --- /dev/null +++ b/lib/compass/app_integration/rails/configuration_defaults.rb @@ -0,0 +1,29 @@ +module Compass + module AppIntegration + module Rails + module ConfigurationDefaults + + def default_images_dir + File.join("public", "images") + end + + def default_javascripts_dir + File.join("public", "javascripts") + end + + def default_http_images_path + "/images" + end + + def default_http_javascripts_path + "/javascripts" + end + + def default_http_stylesheets_path + "/stylesheets" + end + + end + end + end +end diff --git a/lib/compass/app_integration/rails/installer.rb b/lib/compass/app_integration/rails/installer.rb new file mode 100644 index 00000000..3023c33f --- /dev/null +++ b/lib/compass/app_integration/rails/installer.rb @@ -0,0 +1,127 @@ +module Compass + module Installers + class Base + end + end + + module AppIntegration + module Rails + class Installer < Compass::Installers::Base + + def default_configuration + Compass::Configuration::Data.new.extend(ConfigurationDefaults) + end + + def completed_configuration + config = {} + config[:sass_dir] = prompt_sass_dir unless sass_dir_without_default + config[:css_dir] = prompt_css_dir unless css_dir_without_default + config unless config.empty? + end + + def write_configuration_files(config_file = nil) + config_file ||= targetize('config/compass.config') + write_file config_file, 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_configuration_files unless config_files_exist? + 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! + NEXTSTEPS + end + if manifest.has_stylesheet? + puts "\nNext add these lines to the head of your layouts:\n\n" + puts stylesheet_links + puts "\n(You are using haml, aren't you?)" + end + end + + + def install_location_for_html(to, options) + separate("public/#{pattern_name_as_dir}#{to}") + end + + 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] + answer == ?n ? default_location : recommended_location + end + + def prompt_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] + 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" + elsif prop == :output_style + "" + end + end + end + + def initializer_contents + %Q{require 'compass' + # If you have any compass plugins, require them here. + Compass.configuration.parse(File.join(RAILS_ROOT, "config", "compass.config")) + Compass.configuration.environment = RAILS_ENV.to_sym + 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| + # Skip partials. + next if File.basename(stylesheet.from)[0..0] == "_" + 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[:condition] + ss_line = " /[if #{stylesheet.options[:condition]}]\n " + ss_line + end + html << ss_line + "\n" + end + html + end + end + end + end +end diff --git a/lib/compass/app_integration/rails/runtime.rb b/lib/compass/app_integration/rails/runtime.rb new file mode 100644 index 00000000..8cc3b061 --- /dev/null +++ b/lib/compass/app_integration/rails/runtime.rb @@ -0,0 +1,14 @@ +unless defined?(Compass::RAILS_LOADED) + Compass::RAILS_LOADED = true + + %w(action_controller sass_plugin urls).each do |lib| + require File.join(File.dirname(__FILE__), lib) + end + + # Wierd that this has to be re-included to pick up sub-modules. Ruby bug? + class Sass::Script::Functions::EvaluationContext + include Sass::Script::Functions + private + include ActionView::Helpers::AssetTagHelper + end +end diff --git a/lib/compass/app_integration/stand_alone.rb b/lib/compass/app_integration/stand_alone.rb index e69de29b..f5cc3c21 100644 --- a/lib/compass/app_integration/stand_alone.rb +++ b/lib/compass/app_integration/stand_alone.rb @@ -0,0 +1,3 @@ +['configuration_defaults', 'installer'].each do |lib| + require File.join(File.dirname(__FILE__), 'stand_alone', lib) +end \ No newline at end of file diff --git a/lib/compass/app_integration/stand_alone/configuration.rb b/lib/compass/app_integration/stand_alone/configuration.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/compass/app_integration/stand_alone/configuration_defaults.rb b/lib/compass/app_integration/stand_alone/configuration_defaults.rb new file mode 100644 index 00000000..a9ed92dc --- /dev/null +++ b/lib/compass/app_integration/stand_alone/configuration_defaults.rb @@ -0,0 +1,24 @@ +module Compass + module AppIntegration + module StandAlone + module ConfigurationDefaults + def sass_dir_without_default + "src" + end + + def javascripts_dir_without_default + "javascripts" + end + + def css_dir_without_default + "stylesheets" + end + + def images_dir_without_default + "images" + end + end + + end + end +end \ No newline at end of file diff --git a/lib/compass/app_integration/stand_alone/installer.rb b/lib/compass/app_integration/stand_alone/installer.rb new file mode 100644 index 00000000..4480cc46 --- /dev/null +++ b/lib/compass/app_integration/stand_alone/installer.rb @@ -0,0 +1,71 @@ +module Compass + module Installers + class Base + end + end + + module AppIntegration + module StandAlone + class Installer < Compass::Installers::Base + + def init + directory targetize("") + super + end + + def write_configuration_files(config_file = nil) + config_file ||= targetize('config.rb') + write_file config_file, 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? || !@manifest.generate_config? + end + + def default_configuration + Compass::Configuration::Data.new.extend(Compass::AppIntegration::StandAlone::ConfigurationDefaults) + end + + def completed_configuration + nil + end + + def finalize(options = {}) + if options[:create] + puts <<-NEXTSTEPS + + Congratulations! Your compass project has been created. + You must recompile your sass stylesheets when they change. + This can be done in one of the following ways: + 1. From within your project directory run: + compass + 2. From any directory run: + compass -u path/to/project + 3. To monitor your project for changes and automatically recompile: + compass --watch [path/to/project] + NEXTSTEPS + end + if manifest.has_stylesheet? + puts "\nTo import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:" + puts stylesheet_links + end + end + + def compilation_required? + @manifest.compile? + end + end + end + end +end diff --git a/lib/compass/commands/installer_command.rb b/lib/compass/commands/installer_command.rb index 41915d36..f63f5acc 100644 --- a/lib/compass/commands/installer_command.rb +++ b/lib/compass/commands/installer_command.rb @@ -16,14 +16,14 @@ module Compass end def installer - @installer ||= case (options[:project_type] || Compass.configuration.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 + project_type = options[:project_type] || Compass.configuration.project_type + installer_class = "Compass::AppIntegration::#{camelize(project_type)}::Installer" + @installer = eval("#{installer_class}.new *installer_args") + end + + # Stolen from ActiveSupport + def camelize(s) + s.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } end def installer_args diff --git a/lib/compass/exec.rb b/lib/compass/exec.rb index 6596d2cf..12cdc29c 100644 --- a/lib/compass/exec.rb +++ b/lib/compass/exec.rb @@ -146,10 +146,14 @@ END self.options[:pattern_name] = name end - opts.on('--rails', "Sets the project type to a rails project.") do + opts.on('--rails', "Sets the app type to a rails project (same as --app rails).") do self.options[:project_type] = :rails end + opts.on('--app APP_TYPE', 'Specify the kind of application to integrate with.') do |project_type| + self.options[:project_type] = project_type.to_sym + end + opts.separator '' opts.separator 'Configuration Options:' diff --git a/lib/compass/installers.rb b/lib/compass/installers.rb index dbb2be41..7ae1b400 100644 --- a/lib/compass/installers.rb +++ b/lib/compass/installers.rb @@ -1,3 +1,3 @@ -%w(manifest template_context base stand_alone rails).each do |f| +%w(manifest template_context base).each do |f| require File.join(File.dirname(__FILE__), 'installers', f) end diff --git a/lib/compass/installers/rails.rb b/lib/compass/installers/rails.rb deleted file mode 100644 index 9be2a44d..00000000 --- a/lib/compass/installers/rails.rb +++ /dev/null @@ -1,144 +0,0 @@ -module Compass - module Installers - - class RailsInstaller < Base - - module ConfigurationDefaults - def default_images_dir - File.join("public", "images") - end - - def default_javascripts_dir - File.join("public", "javascripts") - end - - def default_http_images_path - "/images" - end - - def default_http_javascripts_path - "/javascripts" - end - - def default_http_stylesheets_path - "/stylesheets" - end - - end - - def default_configuration - Compass::Configuration::Data.new.extend(ConfigurationDefaults) - end - - def completed_configuration - config = {} - config[:sass_dir] = prompt_sass_dir unless sass_dir_without_default - config[:css_dir] = prompt_css_dir unless css_dir_without_default - config unless config.empty? - end - - def write_configuration_files(config_file = nil) - config_file ||= targetize('config/compass.config') - write_file config_file, 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_configuration_files unless config_files_exist? - 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! -NEXTSTEPS - end - if manifest.has_stylesheet? - puts "\nNext add these lines to the head of your layouts:\n\n" - puts stylesheet_links - puts "\n(You are using haml, aren't you?)" - end - end - - - def install_location_for_html(to, options) - separate("public/#{pattern_name_as_dir}#{to}") - end - - 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] - answer == ?n ? default_location : recommended_location - end - - def prompt_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] - 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" - elsif prop == :output_style - "" - end - end - end - - def initializer_contents - %Q{require 'compass' -# If you have any compass plugins, require them here. -Compass.configuration.parse(File.join(RAILS_ROOT, "config", "compass.config")) -Compass.configuration.environment = RAILS_ENV.to_sym -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| - # Skip partials. - next if File.basename(stylesheet.from)[0..0] == "_" - 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[:condition] - ss_line = " /[if #{stylesheet.options[:condition]}]\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 deleted file mode 100644 index a0113a66..00000000 --- a/lib/compass/installers/stand_alone.rb +++ /dev/null @@ -1,83 +0,0 @@ -module Compass - module Installers - - class StandAloneInstaller < Base - - module ConfigurationDefaults - def sass_dir_without_default - "src" - end - - def javascripts_dir_without_default - "javascripts" - end - - def css_dir_without_default - "stylesheets" - end - - def images_dir_without_default - "images" - end - end - - def init - directory targetize("") - super - end - - def write_configuration_files(config_file = nil) - config_file ||= targetize('config.rb') - write_file config_file, 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? || !@manifest.generate_config? - end - - def default_configuration - Compass::Configuration::Data.new.extend(ConfigurationDefaults) - end - - def completed_configuration - nil - end - - def finalize(options = {}) - if options[:create] - puts <<-NEXTSTEPS - -Congratulations! Your compass project has been created. -You must recompile your sass stylesheets when they change. -This can be done in one of the following ways: - 1. From within your project directory run: - compass - 2. From any directory run: - compass -u path/to/project - 3. To monitor your project for changes and automatically recompile: - compass --watch [path/to/project] -NEXTSTEPS - end - if manifest.has_stylesheet? - puts "\nTo import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:" - puts stylesheet_links - end - end - - def compilation_required? - @manifest.compile? - end - end - end -end diff --git a/test/command_line_helper.rb b/test/command_line_helper.rb index d74b191a..077caaf4 100644 --- a/test/command_line_helper.rb +++ b/test/command_line_helper.rb @@ -17,9 +17,11 @@ module Compass::CommandLineHelper else eof_at = nil timeout(1) do - output << io.readpartial(1024) + partial_output = io.readpartial(1024) + # puts "))))#{partial_output}(((((" + output << partial_output end - prompt = output.split("\n").last + prompt = output.split("\n").last.strip if response = responder.response_for(prompt) io.puts response end diff --git a/test/rails_integration_test.rb b/test/rails_integration_test.rb index 9f689a1b..f57c8a97 100644 --- a/test/rails_integration_test.rb +++ b/test/rails_integration_test.rb @@ -18,8 +18,8 @@ class RailsIntegrationTest < Test::Unit::TestCase generate_rails_app_directories("compass_rails") Dir.chdir "compass_rails" do compass("--rails", '--trace', ".") do |responder| - responder.respond_to "Is this OK? (Y/n) ", :with => "Y", :required => true - responder.respond_to "Emit compiled stylesheets to public/stylesheets/compiled/? (Y/n) ", :with => "Y", :required => true + responder.respond_to "Is this OK? (Y/n)", :with => "Y", :required => true + responder.respond_to "Emit compiled stylesheets to public/stylesheets/compiled/? (Y/n)", :with => "Y", :required => true end # puts ">>>#{@last_result}<<<" assert_action_performed :create, "./app/stylesheets/screen.sass"