more robustly handle import paths
This commit is contained in:
parent
f88c22f360
commit
cc881db254
@ -7,10 +7,13 @@ use crate::error::SassResult;
|
||||
use crate::scope::Scope;
|
||||
use crate::{Stmt, StyleSheet};
|
||||
|
||||
pub(crate) fn import<P: AsRef<Path>>(path: P) -> SassResult<(Vec<Spanned<Stmt>>, Scope)> {
|
||||
pub(crate) fn import(ctx: &Path, path: &Path) -> SassResult<(Vec<Spanned<Stmt>>, Scope)> {
|
||||
let mut rules = Vec::new();
|
||||
let mut scope = Scope::new();
|
||||
let path_buf = path.as_ref().to_path_buf();
|
||||
if path.is_absolute() {
|
||||
todo!("absolute import")
|
||||
}
|
||||
let path_buf = ctx.parent().unwrap_or(Path::new("")).join(path);
|
||||
let name = path_buf.file_name().expect("todo! path ended in `..`");
|
||||
if path_buf.extension() == Some(OsStr::new(".css")) {
|
||||
// || name.starts_with("http://") || name.starts_with("https://") {
|
||||
|
@ -204,6 +204,7 @@ impl StyleSheet {
|
||||
lexer: Lexer::new(&file).peekmore(),
|
||||
nesting: 0,
|
||||
map: &map,
|
||||
path: Path::new(""),
|
||||
}
|
||||
.parse_toplevel()
|
||||
.map_err(|e| raw_to_parse_error(&map, e).to_string())?
|
||||
@ -237,6 +238,7 @@ impl StyleSheet {
|
||||
lexer: Lexer::new(&file).peekmore(),
|
||||
nesting: 0,
|
||||
map: &map,
|
||||
path: Path::new(""),
|
||||
}
|
||||
.parse_toplevel()
|
||||
.map_err(|e| raw_to_parse_error(&map, e))?
|
||||
@ -261,12 +263,13 @@ impl StyleSheet {
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
pub fn from_path<P: AsRef<Path> + Into<String> + Clone>(p: P) -> SassResult<String> {
|
||||
let mut map = CodeMap::new();
|
||||
let file = map.add_file(p.clone().into(), String::from_utf8(fs::read(p)?)?);
|
||||
let file = map.add_file(p.clone().into(), String::from_utf8(fs::read(p.clone())?)?);
|
||||
Css::from_stylesheet(StyleSheet(
|
||||
StyleSheetParser {
|
||||
lexer: Lexer::new(&file).peekmore(),
|
||||
nesting: 0,
|
||||
map: &map,
|
||||
path: p.as_ref(),
|
||||
}
|
||||
.parse_toplevel()
|
||||
.map_err(|e| raw_to_parse_error(&map, e))?
|
||||
@ -286,6 +289,7 @@ impl StyleSheet {
|
||||
lexer: Lexer::new(&file).peekmore(),
|
||||
nesting: 0,
|
||||
map: &map,
|
||||
path: p.as_ref(),
|
||||
}
|
||||
.parse_toplevel()?)
|
||||
}
|
||||
@ -299,6 +303,7 @@ struct StyleSheetParser<'a> {
|
||||
lexer: PeekMoreIterator<Lexer<'a>>,
|
||||
nesting: u32,
|
||||
map: &'a CodeMap,
|
||||
path: &'a Path,
|
||||
}
|
||||
|
||||
impl<'a> StyleSheetParser<'a> {
|
||||
@ -382,7 +387,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
|
||||
devour_whitespace(&mut self.lexer);
|
||||
|
||||
let (new_rules, new_scope) = import(file_name)?;
|
||||
let (new_rules, new_scope) = import(self.path, file_name.as_ref())?;
|
||||
rules.extend(new_rules);
|
||||
GLOBAL_SCOPE.with(|s| {
|
||||
s.borrow_mut().extend(new_scope);
|
||||
|
@ -19,6 +19,21 @@ macro_rules! tempfile {
|
||||
.unwrap();
|
||||
write!(f, "{}", $content).unwrap();
|
||||
};
|
||||
($name:literal, $content:literal, dir=$dir:literal) => {
|
||||
let _d = Builder::new()
|
||||
.rand_bytes(0)
|
||||
.prefix("")
|
||||
.suffix($dir)
|
||||
.tempdir_in("")
|
||||
.unwrap();
|
||||
let mut f = dbg!(Builder::new()
|
||||
.rand_bytes(0)
|
||||
.prefix("")
|
||||
.suffix($name)
|
||||
.tempfile_in($dir)
|
||||
.unwrap());
|
||||
write!(f, "{}", $content).unwrap();
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -99,3 +114,24 @@ fn chained_imports() {
|
||||
&StyleSheet::new(input.to_string()).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chained_imports_in_directory() {
|
||||
let input = "@import \"chained_imports_in_directory__a\";\na {\n color: $a;\n}";
|
||||
tempfile!(
|
||||
"chained_imports_in_directory__a.scss",
|
||||
"@import \"chained_imports_in_directory__b\";"
|
||||
);
|
||||
tempfile!(
|
||||
"index.scss",
|
||||
"@import \"../chained_imports_in_directory__c\";",
|
||||
dir = "chained_imports_in_directory__b"
|
||||
);
|
||||
tempfile!("chained_imports_in_directory__c.scss", "$a: red;");
|
||||
assert_eq!(
|
||||
"a {\n color: red;\n}\n",
|
||||
&StyleSheet::new(input.to_string()).expect(input)
|
||||
);
|
||||
}
|
||||
|
||||
// todo: test for calling paths, e.g. `grass b\index.scss`
|
||||
|
Loading…
x
Reference in New Issue
Block a user