Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 5268 Bytes
1 | require 'digest/sha1' |
2 | require 'pathname' |
3 | require 'fileutils' |
4 | |
5 | module Sass |
6 | # This module contains various bits of functionality |
7 | # related to finding and caching Sass files. |
8 | module Files |
9 | extend self |
10 | |
11 | # Returns the {Sass::Tree} for the given file, |
12 | # reading it from the Sass cache if possible. |
13 | # |
14 | # @param filename [String] The path to the Sass file |
15 | # @param options [{Symbol => Object}] The options hash. |
16 | # Only the {file:SASS_REFERENCE.md#cache-option `:cache_location`} option is used |
17 | # @raise [Sass::SyntaxError] if there's an error in the document |
18 | def tree_for(filename, options) |
19 | options = Sass::Engine::DEFAULT_OPTIONS.merge(options) |
20 | text = File.read(filename) |
21 | |
22 | if options[:cache] |
23 | compiled_filename = sassc_filename(filename, options) |
24 | sha = Digest::SHA1.hexdigest(text) |
25 | |
26 | if root = try_to_read_sassc(filename, compiled_filename, sha) |
27 | root.options = options.merge(:filename => filename) |
28 | return root |
29 | end |
30 | end |
31 | |
32 | engine = Sass::Engine.new(text, options.merge(:filename => filename)) |
33 | |
34 | begin |
35 | root = engine.to_tree |
36 | rescue Sass::SyntaxError => err |
37 | err.add_backtrace_entry(filename) |
38 | raise err |
39 | end |
40 | |
41 | try_to_write_sassc(root, compiled_filename, sha, options) if options[:cache] |
42 | |
43 | root |
44 | end |
45 | |
46 | # Find the full filename of a Sass or CSS file to import. |
47 | # This follows Sass's import rules: |
48 | # if the filename given ends in `".sass"` or `".css"`, |
49 | # it will try to find that type of file; |
50 | # otherwise, it will try to find the corresponding Sass file |
51 | # and fall back on CSS if it's not available. |
52 | # |
53 | # Any Sass filename returned will correspond to |
54 | # an actual Sass file on the filesystem. |
55 | # CSS filenames, however, may not; |
56 | # they're expected to be put through directly to the stylesheet |
57 | # as CSS `@import` statements. |
58 | # |
59 | # @param filename [String] The filename to search for |
60 | # @param load_paths [Array<String>] The set of filesystem paths |
61 | # to search for Sass files. |
62 | # @return [String] The filename of the imported file. |
63 | # This is an absolute path if the file is a `".sass"` file. |
64 | # @raise [Sass::SyntaxError] if `filename` ends in ``".sass"`` |
65 | # and no corresponding Sass file could be found. |
66 | def find_file_to_import(filename, load_paths) |
67 | was_sass = false |
68 | original_filename = filename |
69 | |
70 | if filename[-5..-1] == ".sass" |
71 | filename = filename[0...-5] |
72 | was_sass = true |
73 | elsif filename[-4..-1] == ".css" |
74 | return filename |
75 | end |
76 | |
77 | new_filename = find_full_path("#{filename}.sass", load_paths) |
78 | |
79 | return new_filename if new_filename |
80 | unless was_sass |
81 | warn <<END |
82 | WARNING: #{filename}.sass not found. Using #{filename}.css instead. |
83 | This behavior is deprecated and will be removed in a future version. |
84 | If you really need #{filename}.css, import it explicitly. |
85 | END |
86 | return filename + '.css' |
87 | end |
88 | |
89 | message = "File to import not found or unreadable: #{original_filename}.\n" |
90 | if load_paths.size == 1 |
91 | message << "Load path: #{load_paths.first}" |
92 | else |
93 | message << "Load paths:\n " << load_paths.join("\n ") |
94 | end |
95 | |
96 | raise SyntaxError.new(message, @line) |
97 | end |
98 | |
99 | private |
100 | |
101 | def sassc_filename(filename, options) |
102 | File.join(options[:cache_location], |
103 | Digest::SHA1.hexdigest(File.dirname(File.expand_path(filename))), |
104 | File.basename(filename) + 'c') |
105 | end |
106 | |
107 | def try_to_read_sassc(filename, compiled_filename, sha) |
108 | return unless File.readable?(compiled_filename) |
109 | |
110 | File.open(compiled_filename, "rb") do |f| |
111 | return unless f.readline("\n").strip == Sass::VERSION |
112 | return unless f.readline("\n").strip == sha |
113 | return Marshal.load(f.read) |
114 | end |
115 | rescue EOFError, TypeError, ArgumentError => e |
116 | warn "Warning. Error encountered while reading cache #{compiled_filename}: #{e}" |
117 | end |
118 | |
119 | def try_to_write_sassc(root, compiled_filename, sha, options) |
120 | return unless File.writable?(File.dirname(options[:cache_location])) |
121 | return if File.exists?(options[:cache_location]) && !File.writable?(options[:cache_location]) |
122 | return if File.exists?(File.dirname(compiled_filename)) && !File.writable?(File.dirname(compiled_filename)) |
123 | return if File.exists?(compiled_filename) && !File.writable?(compiled_filename) |
124 | FileUtils.mkdir_p(File.dirname(compiled_filename)) |
125 | File.open(compiled_filename, "wb") do |f| |
126 | f.write(Sass::VERSION) |
127 | f.write("\n") |
128 | f.write(sha) |
129 | f.write("\n") |
130 | f.write(Marshal.dump(root)) |
131 | end |
132 | end |
133 | |
134 | def find_full_path(filename, load_paths) |
135 | partial_name = File.join(File.dirname(filename), "_#{File.basename(filename)}") |
136 | |
137 | if Pathname.new(filename).absolute? |
138 | [partial_name, filename].each do |name| |
139 | return name if File.readable?(name) |
140 | end |
141 | return nil |
142 | end |
143 | |
144 | load_paths.each do |path| |
145 | [partial_name, filename].each do |name| |
146 | full_path = File.join(path, name) |
147 | if File.readable?(full_path) |
148 | return full_path |
149 | end |
150 | end |
151 | end |
152 | nil |
153 | end |
154 | end |
155 | end |