New Ruby on Rails project installer.

This commit is contained in:
Chris Eppstein 2009-02-03 11:34:39 -08:00
parent 94f4471ad5
commit a7406659b6
8 changed files with 153 additions and 114 deletions

View File

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

View File

@ -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 <<NEXTSTEPS
Congratulations! Your project has been configured to use Compass.
Next add these lines to the head of your application.html.haml:
%head
= 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'
(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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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