Skip to content

Commit cf70f3b

Browse files
author
Andrey Fedoseev
committed
Add support for load_paths setting in get_full_source_path and locate_imported_file method for SCSS/SASS compiler
1 parent 01aad1b commit cf70f3b

File tree

2 files changed

+61
-21
lines changed

2 files changed

+61
-21
lines changed

static_precompiler/compilers/scss.py

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,18 @@ def find_imports(self, source):
207207
imports.add(import_item)
208208
return sorted(imports)
209209

210+
def get_full_source_path(self, source_path):
211+
try:
212+
return super(SCSS, self).get_full_source_path(source_path)
213+
except ValueError:
214+
# Try to locate the source file in directories specified in `load_paths`
215+
norm_source_path = utils.normalize_path(source_path.lstrip("/"))
216+
for dirname in self.load_paths:
217+
full_path = os.path.join(dirname, norm_source_path)
218+
if os.path.exists(full_path):
219+
return full_path
220+
raise
221+
210222
def locate_imported_file(self, source_dir, import_path):
211223
""" Locate the imported file in the source directory.
212224
Return the path to the imported file relative to STATIC_ROOT
@@ -218,31 +230,35 @@ def locate_imported_file(self, source_dir, import_path):
218230
:returns: str
219231
220232
"""
221-
for extension in self.import_extensions:
222-
import_path_probe = import_path
223-
if not import_path_probe.endswith("." + extension):
224-
import_path_probe += "." + extension
225-
path = posixpath.normpath(posixpath.join(source_dir, import_path_probe))
233+
import_filename = posixpath.basename(import_path)
234+
import_dirname = posixpath.dirname(import_path)
235+
import_filename_root, import_filename_extension = posixpath.splitext(import_filename)
236+
237+
if import_filename_extension:
238+
filenames_to_try = [import_filename]
239+
else:
240+
# No extension is specified for the imported file, try all supported extensions
241+
filenames_to_try = [import_filename_root + "." + extension for extension in self.import_extensions]
242+
243+
if not import_filename.startswith("_"):
244+
# Try the files with "_" prefix
245+
filenames_to_try += ["_" + filename for filename in filenames_to_try]
226246

247+
# Try to locate the file in the directory relative to `source_dir`
248+
for filename in filenames_to_try:
249+
source_path = posixpath.normpath(posixpath.join(source_dir, import_dirname, filename))
227250
try:
228-
self.get_full_source_path(path)
229-
return path
251+
self.get_full_source_path(source_path)
252+
return source_path
230253
except ValueError:
231254
pass
232255

233-
filename = posixpath.basename(import_path_probe)
234-
if filename[0] != "_":
235-
path = posixpath.normpath(posixpath.join(
236-
source_dir,
237-
posixpath.dirname(import_path_probe),
238-
"_" + filename,
239-
))
240-
241-
try:
242-
self.get_full_source_path(path)
243-
return path
244-
except ValueError:
245-
pass
256+
# Try to locate the file in the directories listed in `load_paths`
257+
for dirname in self.load_paths:
258+
for filename in filenames_to_try:
259+
source_path = posixpath.join(import_dirname, filename)
260+
if os.path.exists(os.path.join(dirname, utils.normalize_path(source_path))):
261+
return source_path
246262

247263
raise exceptions.StaticCompilationError("Can't locate the imported file: {0}".format(import_path))
248264

static_precompiler/tests/test_scss.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@
1010
from static_precompiler.compilers import libsass, scss
1111

1212

13+
@pytest.mark.parametrize("compiler_module", (libsass, scss))
14+
def test_get_full_source_path(compiler_module):
15+
16+
compiler = compiler_module.SCSS()
17+
with pytest.raises(ValueError):
18+
compiler.get_full_source_path("_extra.scss")
19+
20+
extra_path = os.path.join(os.path.dirname(__file__), "static", "styles", "sass", "extra-path")
21+
22+
compiler = compiler_module.SCSS(load_paths=(extra_path, ))
23+
24+
assert compiler.get_full_source_path("_extra.scss") == os.path.join(extra_path, "_extra.scss")
25+
26+
1327
@pytest.mark.parametrize("compiler_module", (libsass, scss))
1428
def test_compile_file(compiler_module, monkeypatch, tmpdir):
1529
monkeypatch.setattr("static_precompiler.settings.ROOT", tmpdir.strpath)
@@ -156,23 +170,33 @@ def test_find_imports():
156170

157171
@pytest.mark.parametrize("compiler_module", (libsass, scss))
158172
def test_locate_imported_file(compiler_module, monkeypatch):
159-
compiler = compiler_module.SCSS()
160173

161174
root = os.path.dirname(__file__)
162175

163176
existing_files = set()
164177
for f in ("A/B.scss", "A/_C.scss", "A/S.sass", "D.scss"):
165178
existing_files.add(os.path.join(root, "static", utils.normalize_path(f)))
166179

180+
additional_path = os.path.join(root, "static", "additional-path")
181+
existing_files.add(
182+
os.path.join(additional_path, "foo.scss")
183+
)
184+
167185
monkeypatch.setattr("os.path.exists", lambda x: x in existing_files)
168186

187+
compiler = compiler_module.SCSS(load_paths=(
188+
additional_path,
189+
))
190+
169191
assert compiler.locate_imported_file("A", "B.scss") == "A/B.scss"
170192
assert compiler.locate_imported_file("A", "C") == "A/_C.scss"
171193
assert compiler.locate_imported_file("E", "../D") == "D.scss"
172194
assert compiler.locate_imported_file("E", "../A/B.scss") == "A/B.scss"
173195
assert compiler.locate_imported_file("", "D.scss") == "D.scss"
174196
assert compiler.locate_imported_file("A", "S.sass") == "A/S.sass"
175197
assert compiler.locate_imported_file("A", "S") == "A/S.sass"
198+
assert compiler.locate_imported_file("A", "foo") == "foo.scss"
199+
assert compiler.locate_imported_file("bar", "foo") == "foo.scss"
176200

177201
with pytest.raises(exceptions.StaticCompilationError):
178202
compiler.locate_imported_file("", "Z.scss")

0 commit comments

Comments
 (0)