From e18ed8118b5bf78c8ab4868c50cc98490b5118d9 Mon Sep 17 00:00:00 2001 From: Chris Eppstein Date: Fri, 3 Apr 2009 01:06:23 -0700 Subject: [PATCH] Support for Framework Patterns. A pattern is a folder in the framework's templates directory. It must have a manifest file that tells compass what to install and where. Unlike the project template, a pattern can be stamped out any number of times. It is best for pattern stylesheets to only provide example usage to get the user started. All the core styles for the pattern should be distributed as part of the framework's stylesheets as mixins to facilitate easy upgrades and bug fixing on the part of the pattern's maintainer. Patterns can install stylesheets, images, javascripts, and arbitrary files. The installer will put these assets into the correct locations according to the project type (E.g. rails, stand-alone). Example Usage: compass --framework blueprint --pattern buttons --- lib/compass/commands/create_project.rb | 31 +++--------------- lib/compass/commands/stamp_pattern.rb | 45 ++++++++++++++++++++++++++ lib/compass/exec.rb | 9 ++++++ lib/compass/installers/base.rb | 22 +++++++++++-- lib/compass/installers/manifest.rb | 1 + lib/compass/installers/rails.rb | 5 ++- lib/compass/installers/stand_alone.rb | 8 ++--- 7 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 lib/compass/commands/stamp_pattern.rb diff --git a/lib/compass/commands/create_project.rb b/lib/compass/commands/create_project.rb index 3382f6ac..373785dc 100644 --- a/lib/compass/commands/create_project.rb +++ b/lib/compass/commands/create_project.rb @@ -1,39 +1,18 @@ require 'fileutils' -require File.join(File.dirname(__FILE__), 'base') +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 - class CreateProject < ProjectBase - - include Compass::Installers - - attr_accessor :installer + class CreateProject < StampPattern def initialize(working_path, options) - super(working_path, 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_path, options).perform if installer.compilation_required? - installer.finalize(:create => true) + super(working_path, options.merge(:pattern => "project", :pattern_name => nil)) end - def project_template_directory - File.join(framework.templates_directory, "project") + def is_project_creation? + true end end diff --git a/lib/compass/commands/stamp_pattern.rb b/lib/compass/commands/stamp_pattern.rb new file mode 100644 index 00000000..c1434450 --- /dev/null +++ b/lib/compass/commands/stamp_pattern.rb @@ -0,0 +1,45 @@ +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 + + 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 + installer.run(:skip_finalization => true) + UpdateProject.new(working_path, options).perform if installer.compilation_required? + installer.finalize(:create => is_project_creation?) + end + + def is_project_creation? + false + end + + def template_directory(pattern) + File.join(framework.templates_directory, pattern) + end + + end + end +end \ No newline at end of file diff --git a/lib/compass/exec.rb b/lib/compass/exec.rb index 66686062..0ad5b9a2 100644 --- a/lib/compass/exec.rb +++ b/lib/compass/exec.rb @@ -162,6 +162,15 @@ END self.options[:command] = :validate_project end + opts.on('-p', '--pattern PATTERN', 'Stamp out a pattern into the current project. Must be used in combination with -f.') do |pattern| + self.options[:command] = :stamp_pattern + self.options[:pattern] = pattern + end + + opts.on('-n', '--pattern-name NAME', 'The name to use when stamping a pattern. Must be used in combination with -p.') do |name| + self.options[:pattern_name] = name + end + opts.on_tail("-?", "-h", "--help", "Show this message") do puts opts exit diff --git a/lib/compass/installers/base.rb b/lib/compass/installers/base.rb index 16439df9..c70b77e6 100644 --- a/lib/compass/installers/base.rb +++ b/lib/compass/installers/base.rb @@ -26,6 +26,18 @@ module Compass # Initializes the project to work with compass def init + dirs = manifest.map do |entry| + File.dirname(send("install_location_for_#{entry.type}", entry.to)) + end + + if manifest.has_stylesheet? + dirs << sass_dir + dirs << css_dir + end + + dirs.uniq.sort.each do |dir| + directory targetize(dir) + end end # Runs the installer. @@ -81,6 +93,10 @@ module Compass false end + def pattern_name_as_dir + "#{options[:pattern_name]}/" if options[:pattern_name] + end + def self.installer(type, &locator) locator ||= lambda{|to| to} loc_method = "install_location_for_#{type}".to_sym @@ -91,7 +107,7 @@ module Compass end installer :stylesheet do |to| - "#{sass_dir}/#{to}" + "#{sass_dir}/#{pattern_name_as_dir}#{to}" end installer :image do |to| @@ -102,7 +118,9 @@ module Compass "#{javascripts_dir}/#{to}" end - installer :file + installer :file do |to| + "#{pattern_name_as_dir}#{to}" + end # returns an absolute path given a path relative to the current installation target. # Paths can use unix style "/" and will be corrected for the current platform. diff --git a/lib/compass/installers/manifest.rb b/lib/compass/installers/manifest.rb index 3d016153..bd5d9a34 100644 --- a/lib/compass/installers/manifest.rb +++ b/lib/compass/installers/manifest.rb @@ -2,6 +2,7 @@ module Compass module Installers class Manifest + include Enumerable # A Manifest entry class Entry < Struct.new(:type, :from, :options) diff --git a/lib/compass/installers/rails.rb b/lib/compass/installers/rails.rb index a93367c0..1887e99e 100644 --- a/lib/compass/installers/rails.rb +++ b/lib/compass/installers/rails.rb @@ -16,12 +16,11 @@ module Compass def init set_sass_dir unless sass_dir set_css_dir unless css_dir - directory targetize(css_dir) - directory targetize(sass_dir) - write_file targetize('config/initializers/compass.rb'), initializer_contents + super end def prepare + write_file targetize('config/initializers/compass.rb'), initializer_contents end def finalize(options = {}) diff --git a/lib/compass/installers/stand_alone.rb b/lib/compass/installers/stand_alone.rb index 0b4f9c35..2a2402a5 100644 --- a/lib/compass/installers/stand_alone.rb +++ b/lib/compass/installers/stand_alone.rb @@ -14,13 +14,10 @@ module Compass def init directory targetize("") - directory targetize(css_dir) - directory targetize(sass_dir) + super end def prepare - directory targetize(images_dir) if manifest.has_image? - directory targetize(javascripts_dir) if manifest.has_javascript? end def default_css_dir @@ -61,10 +58,9 @@ This can be done in one of the following ways: compass -u path/to/project 3. To monitor your project for changes and automatically recompile: compass --watch [path/to/project] - NEXTSTEPS end - puts "To import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:" + puts "\nTo import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:" puts stylesheet_links end