Skip to content

Instantly share code, notes, and snippets.

@svallory
Last active December 11, 2015 05:08
Show Gist options
  • Save svallory/4549615 to your computer and use it in GitHub Desktop.
Save svallory/4549615 to your computer and use it in GitHub Desktop.
Sass custom importer which only imports the same file once, Compass required config and patch.
##
# the ImportOnce importer itself
# colorize is used for colorized terminal output, useful for debugging, but you can strip that off
##
require 'colorize'
module Sass
module Importers
class ImportOnce < Filesystem
attr_accessor :root, :debug_level, :staleness_check, :imported, :original_filename
# Creates a new filesystem importer that imports files relative to a given path.
#
# @param root [String] The root path.
# This importer will import files relative to this path.
def initialize(root)
@debug_level = 0
@imported = []
super(root)
end
def debug?
return true
end
def debug(text, level = 1)
if debug? && debug_level >= level
puts "__ DEBUG: " + text.to_s
end
end
def dir(obj)
obj.each {|k,v|
puts k.inspect + " = " + (v ? v.inspect : "") + "\n"
}
end
def update_imported_list(options)
@original_filename ||= options[:original_filename]
if @original_filename != options[:original_filename]
@imported = []
@original_filename = options[:original_filename]
end
end
def staleness_check?(options)
# as per sass/importers/filesystem.rb : 135, 148
# If options[:_line] exists, we're here due to an actual import in an import_node
# Otherwise, we're here via StalenessChecker.
# But it's only true for the first file, all subsequent imports will
# have a :_line, so, unfortunately, for now, will have to check the stack
Kernel.caller.each {|call|
return true if call.include? "staleness_checker"
}
return false
end
# @see Base#find_relative
def find_relative(name, base, options)
update_imported_list options
debug " finding relative ".yellow + name.blue
just_checking = staleness_check? options
# get the real file
real_file, syntax = Sass::Util.destructure(find_real_file(File.dirname(base), name, options))
if !real_file
debug " Could not find a RELATIVE file for #{name}".red, 2
return nil
end
unless just_checking
if @imported.include? real_file
debug " already included".red
debug @imported.join(", ").yellow, 3
return empty(options)
end
else
debug " Just checking", 2
end
f = _find(File.dirname(base), name, options)
if f
debug " imported: ".yellow + real_file.green
@imported << real_file unless just_checking
end
return f
end
# @see Base#find
def find(name, options)
update_imported_list options
debug "finding absolute " + name.blue
just_checking = staleness_check? options
# get the real file
real_file, syntax = Sass::Util.destructure(find_real_file(@root, name, options))
if !real_file
debug "Could not find the file for #{name}".red, 2
return nil
end
unless just_checking
if @imported.include? real_file
debug "already included".red
debug @imported.join(", ").yellow, 3
return empty(options)
end
else
debug "Just checking", 2
end
f = _find(@root, name, options)
if f
debug " imported: " + real_file.green
@imported << real_file unless just_checking
else
debug "NOT FOUND!".red
end
return f
end
protected
def split_filename(name)
parts = name.split('/')
name = parts[0..-2].join('/') + '/{_,}' + parts[-1]
return [[name+'.scss', :scss], [name+'.sass', :sass]]
end
def empty(options)
return Sass::Engine.new("", options)
end
end
end
end
From 7c50b90ee66906c4f9e60f3e56cfad442d552499 Mon Sep 17 00:00:00 2001
From: Saulo Vallory <[email protected]>
Date: Wed, 16 Jan 2013 15:53:15 -0200
Subject: [PATCH] Uses :filesystem_importer sass option, when provided, to
create importers
Sass allows the user to overwrite the default importer using :filesystem_importer option. This makes Compass respect that option when used.
---
lib/compass/compiler.rb | 3 ++-
lib/compass/configuration/adapters.rb | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/compass/compiler.rb b/lib/compass/compiler.rb
index 00a931f..2447461 100644
--- a/lib/compass/compiler.rb
+++ b/lib/compass/compiler.rb
@@ -15,7 +15,8 @@ module Compass
self.sass_options.delete(:quiet)
self.sass_options.update(sass_opts)
self.sass_options[:cache_location] ||= determine_cache_location
- self.sass_options[:importer] = self.importer = Sass::Importers::Filesystem.new(from)
+ self.sass_options[:filesystem_importer] ||= Sass::Importers::Filesystem
+ self.sass_options[:importer] = self.importer = self.sass_options[:filesystem_importer].new(from)
self.sass_options[:compass] ||= {}
self.sass_options[:compass][:logger] = self.logger
self.sass_options[:compass][:environment] = Compass.configuration.environment
diff --git a/lib/compass/configuration/adapters.rb b/lib/compass/configuration/adapters.rb
index a139de1..afe42df 100644
--- a/lib/compass/configuration/adapters.rb
+++ b/lib/compass/configuration/adapters.rb
@@ -64,10 +64,12 @@ module Compass
Compass::Frameworks::ALL.each do |f|
load_paths << f.stylesheets_directory if File.directory?(f.stylesheets_directory)
end
+ importer = sass_options[:filesystem_importer] if sass_options && sass_options[:filesystem_importer]
+ importer ||= Sass::Importers::Filesystem
load_paths += resolve_additional_import_paths
load_paths.map! do |p|
next p if p.respond_to?(:find_relative)
- Sass::Importers::Filesystem.new(p.to_s)
+ importer.new(p.to_s)
end
load_paths << Compass::SpriteImporter.new
load_paths
--
1.7.10.2 (Apple Git-33)
##
# Add these lines to your compass project config.rb file
##
require 'importer.rb'
sass_options ||= {}
sass_options[:filesystem_importer] = Sass::Importers::ImportOnce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment