class Sass::Importers::Filesystem
Simply loads Sass files from the filesystem using the default logic.
The default importer, used for any strings found in the load path.
def _find(dir, name, options)
def _find(dir, name, options) full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options)) return unless full_filename && File.file?(full_filename) && File.readable?(full_filename) # TODO: this preserves historical behavior, but it's possible # :filename should be either normalized to the native format # or consistently URI-format. full_filename = full_filename.tr("\\", "/") if Sass::Util.windows? options[:syntax] = syntax options[:filename] = full_filename options[:importer] = self Sass::Engine.new(File.read(full_filename), options) end
def directories_to_watch
- See: Base#directories_to_watch -
def directories_to_watch [root] end
def eql?(other)
def eql?(other) !other.nil? && other.respond_to?(:root) && root.eql?(other.root) end
def escape_glob_characters(name)
def escape_glob_characters(name) name.gsub(/[\*\[\]\{\}\?]/) do |char| "\\#{char}" end end
def extensions
-
({String => Symbol})
-
def extensions {'sass' => :sass, 'scss' => :scss} end
def find(name, options)
- See: Base#find -
def find(name, options) _find(@root, name, options) end
def find_real_file(dir, name, options)
-
((String, Symbol))
- A filename-syntax pair.
Parameters:
-
name
(String
) -- The filename to search for. -
dir
(String
) -- The directory relative to which to search.
def find_real_file(dir, name, options) # On windows 'dir' or 'name' can be in native File::ALT_SEPARATOR form. dir = dir.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil? name = name.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless File::ALT_SEPARATOR.nil? found = possible_files(remove_root(name)).map do |f, s| path = if dir == "." || Sass::Util.pathname(f).absolute? f else "#{escape_glob_characters(dir)}/#{f}" end Dir[path].map do |full_path| full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR) [Sass::Util.cleanpath(full_path).to_s, s] end end.flatten(1) if found.empty? && split(name)[2].nil? && File.directory?("#{dir}/#{name}") return find_real_file("#{dir}/#{name}", "index", options) end if found.size > 1 && !@same_name_warnings.include?(found.first.first) found.each {|(f, _)| @same_name_warnings << f} relative_to = Sass::Util.pathname(dir) if options[:_from_import_node] # If _line exists, we're here due to an actual import in an # import_node and we want to print a warning for a user writing an # ambiguous import. candidates = found.map do |(f, _)| " " + Sass::Util.pathname(f).relative_path_from(relative_to).to_s end.join("\n") raise Sass::SyntaxError.new(<<MESSAGE) ot clear which file to import for '@import "#{name}"'. ates: idates} delete or rename all but one of these files. E else # Otherwise, we're here via StalenessChecker, and we want to print a # warning for a user running `sass --watch` with two ambiguous files. candidates = found.map {|(f, _)| " " + File.basename(f)}.join("\n") Sass::Util.sass_warn <<WARNING G: In #{File.dirname(name)}: e are multiple files that match the name "#{File.basename(name)}": idates} G end end found.first end
def find_relative(name, base, options)
- See: Base#find_relative -
def find_relative(name, base, options) _find(File.dirname(base), name, options) end
def hash
def hash @root.hash end
def initialize(root)
-
root
(String
) -- The root path.
def initialize(root) @root = File.expand_path(root) @real_root = Sass::Util.realpath(@root).to_s @same_name_warnings = Set.new end
def key(name, options)
- See: Base#key -
def key(name, options) [self.class.name + ":" + File.dirname(File.expand_path(name)), File.basename(name)] end
def mtime(name, options)
- See: Base#mtime -
def mtime(name, options) file, _ = Sass::Util.destructure(find_real_file(@root, name, options)) File.mtime(file) if file rescue Errno::ENOENT nil end
def possible_files(name)
-
(Array(String, Symbol))
- An array of pairs.
Parameters:
-
name
(String
) -- The filename.
def possible_files(name) name = escape_glob_characters(name) dirname, basename, extname = split(name) sorted_exts = extensions.sort syntax = extensions[extname] if syntax ret = [["#{dirname}/{_,}#{basename}.#{extensions.invert[syntax]}", syntax]] else ret = sorted_exts.map {|ext, syn| ["#{dirname}/{_,}#{basename}.#{ext}", syn]} end # JRuby chokes when trying to import files from JARs when the path starts with './'. ret.map {|f, s| [f.sub(%r{^\./}, ''), s]} end
def public_url(name, sourcemap_directory)
def public_url(name, sourcemap_directory) file_pathname = Sass::Util.cleanpath(File.absolute_path(name, @root)) return Sass::Util.file_uri_from_path(file_pathname) if sourcemap_directory.nil? sourcemap_pathname = Sass::Util.cleanpath(sourcemap_directory) begin Sass::Util.file_uri_from_path( Sass::Util.relative_path_from(file_pathname, sourcemap_pathname)) rescue ArgumentError # when a relative path cannot be constructed Sass::Util.file_uri_from_path(file_pathname) end end
def remove_root(name)
If a full uri is passed, this removes the root from it
def remove_root(name) if name.index(@root + "/") == 0 name[(@root.length + 1)..-1] else name end end
def split(name)
Splits a filename into three parts, a directory part, a basename, and an extension
def split(name) extension = nil dirname, basename = File.dirname(name), File.basename(name) if basename =~ /^(.*)\.(#{extensions.keys.map {|e| Regexp.escape(e)}.join('|')})$/ basename = $1 extension = $2 end [dirname, basename, extension] end
def to_s
- See: Base#to_s -
def to_s @root end
def watched_file?(filename)
- See: Base#watched_file? -
def watched_file?(filename) # Check against the root with symlinks resolved, since Listen # returns fully-resolved paths. filename =~ /\.s[ac]ss$/ && filename.start_with?(@real_root + File::SEPARATOR) end