From fe26350932d426ab2e54457b59522e1d80d628d3 Mon Sep 17 00:00:00 2001 From: Joe Ling - uni laptop Date: Mon, 13 Jul 2020 14:52:52 +0100 Subject: [PATCH] Added load_paths for @import --- src/lib.rs | 39 ++++++++++++++++++++++++++++ src/main.rs | 16 ++++++++---- src/parse/control_flow.rs | 9 +++++++ src/parse/function.rs | 1 + src/parse/import.rs | 54 +++++++++++++++++++++++++++++++++++++++ src/parse/keyframes.rs | 2 ++ src/parse/mixin.rs | 2 ++ src/parse/mod.rs | 7 +++++ src/parse/value/parse.rs | 1 + src/value/mod.rs | 1 + 10 files changed, 127 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4d37f1b..fa33776 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,6 +161,7 @@ pub fn from_path(p: &str) -> Result { at_root_has_selector: false, extender: &mut Extender::new(empty_span), content_scopes: &mut Scopes::new(), + load_paths: &Vec::new(), } .parse() .map_err(|e| raw_to_parse_error(&map, *e))?; @@ -204,6 +205,7 @@ pub fn from_string(p: String) -> Result { at_root_has_selector: false, extender: &mut Extender::new(empty_span), content_scopes: &mut Scopes::new(), + load_paths: &Vec::new(), } .parse() .map_err(|e| raw_to_parse_error(&map, *e))?; @@ -247,3 +249,40 @@ pub fn from_string(p: String) -> std::result::Result { .pretty_print(&map) .map_err(|e| raw_to_parse_error(&map, *e).to_string())?) } + + +#[cfg_attr(feature = "profiling", inline(never))] +#[cfg_attr(not(feature = "profiling"), inline)] +#[cfg(not(feature = "wasm"))] +pub fn from_path_with_load_paths(p: &str, loadpaths: Vec<&Path>) -> Result { + let mut map = CodeMap::new(); + let file = map.add_file(p.into(), String::from_utf8(fs::read(p)?)?); + let empty_span = file.span.subspan(0, 0); + + let stmts = Parser { + toks: &mut Lexer::new(&file) + .collect::>() + .into_iter() + .peekmore(), + map: &mut map, + path: p.as_ref(), + scopes: &mut Scopes::new(), + global_scope: &mut Scope::new(), + super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), + span_before: empty_span, + content: &mut Vec::new(), + flags: ContextFlags::empty(), + at_root: true, + at_root_has_selector: false, + extender: &mut Extender::new(empty_span), + content_scopes: &mut Scopes::new(), + load_paths: &loadpaths, + } + .parse() + .map_err(|e| raw_to_parse_error(&map, *e))?; + + Css::from_stmts(stmts, false) + .map_err(|e| raw_to_parse_error(&map, *e))? + .pretty_print(&map) + .map_err(|e| raw_to_parse_error(&map, *e)) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7783259..e058af4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,13 @@ use std::{ fs::File, io::{stdout, BufWriter, Write}, + path::Path, }; use clap::{arg_enum, App, AppSettings, Arg}; #[cfg(not(feature = "wasm"))] -use grass::from_path; +use grass::from_path_with_load_paths; arg_enum! { #[derive(PartialEq, Debug)] @@ -51,11 +52,9 @@ fn main() -> std::io::Result<()> { Arg::with_name("LOAD_PATH") .short("I") .long("load-path") - .hidden(true) .help("A path to use when resolving imports. May be passed multiple times.") .multiple(true) .takes_value(true) - .number_of_values(1), ) .arg( Arg::with_name("STYLE") @@ -183,11 +182,18 @@ fn main() -> std::io::Result<()> { ) .get_matches(); + let vals: Vec<&Path>; + if let Some(load_paths) = matches.values_of("LOAD_PATH") { + vals = load_paths.map(|p| Path::new(p)).collect(); + } else { + vals = Vec::new(); + } + if let Some(name) = matches.value_of("INPUT") { if let Some(path) = matches.value_of("OUTPUT") { let mut buf = BufWriter::new(File::open(path).unwrap_or(File::create(path)?)); buf.write_all( - from_path(name) + from_path_with_load_paths(name, vals) .unwrap_or_else(|e| { eprintln!("{}", e); std::process::exit(1) @@ -197,7 +203,7 @@ fn main() -> std::io::Result<()> { } else { let mut stdout = BufWriter::new(stdout()); stdout.write_all( - from_path(name) + from_path_with_load_paths(name, vals) .unwrap_or_else(|e| { eprintln!("{}", e); std::process::exit(1) diff --git a/src/parse/control_flow.rs b/src/parse/control_flow.rs index a37fa72..48a9593 100644 --- a/src/parse/control_flow.rs +++ b/src/parse/control_flow.rs @@ -52,6 +52,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse_stmt()?; } else { @@ -110,6 +111,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse_stmt()?; } else { @@ -137,6 +139,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse_stmt(); } @@ -316,6 +319,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?; if !these_stmts.is_empty() { @@ -337,6 +341,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?, ); @@ -386,6 +391,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?; if !these_stmts.is_empty() { @@ -407,6 +413,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?, ); @@ -509,6 +516,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?; if !these_stmts.is_empty() { @@ -530,6 +538,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse()?, ); diff --git a/src/parse/function.rs b/src/parse/function.rs index 4172dd0..0721b21 100644 --- a/src/parse/function.rs +++ b/src/parse/function.rs @@ -107,6 +107,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse()?; diff --git a/src/parse/import.rs b/src/parse/import.rs index 64fef73..8ad84a8 100644 --- a/src/parse/import.rs +++ b/src/parse/import.rs @@ -91,11 +91,65 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths, } .parse(); } } + for _path in self.load_paths { + let paths; + if _path.is_dir() { + paths = vec![ + _path.join(format!("{}.scss", name.to_str().unwrap())), + _path.join(format!("_{}.scss", name.to_str().unwrap())), + _path.join("index.scss"), + _path.join("_index.scss"), + ]; + } else { + paths = vec![ + _path.to_path_buf(), + _path.with_file_name(name).with_extension("scss"), + _path + .with_file_name(format!("_{}", name.to_str().unwrap())) + .with_extension("scss"), + _path.join("index.scss"), + _path.join("_index.scss"), + ]; + } + + for name in &paths { + if name.is_file() { + println!("found file: {:?}", name); + let file = self.map.add_file( + name.to_string_lossy().into(), + String::from_utf8(fs::read(name)?)?, + ); + + return Parser { + toks: &mut Lexer::new(&file) + .collect::>() + .into_iter() + .peekmore(), + map: self.map, + path: name.as_ref(), + scopes: self.scopes, + global_scope: self.global_scope, + super_selectors: self.super_selectors, + span_before: file.span.subspan(0, 0), + content: self.content, + flags: self.flags, + at_root: self.at_root, + at_root_has_selector: self.at_root_has_selector, + extender: self.extender, + content_scopes: self.content_scopes, + load_paths: self.load_paths, + } + .parse(); + } + } + } + Err(("Can't find stylesheet to import.", span).into()) } } diff --git a/src/parse/keyframes.rs b/src/parse/keyframes.rs index 67519b9..b6db525 100644 --- a/src/parse/keyframes.rs +++ b/src/parse/keyframes.rs @@ -165,6 +165,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths }) .parse_keyframes_selector()?; @@ -195,6 +196,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse_stmt()?; diff --git a/src/parse/mixin.rs b/src/parse/mixin.rs index 52f12b6..fcad98c 100644 --- a/src/parse/mixin.rs +++ b/src/parse/mixin.rs @@ -154,6 +154,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse()?; @@ -205,6 +206,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.scopes, + load_paths: self.load_paths } .parse()? } else { diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 8e1df55..7db9ef1 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -82,6 +82,8 @@ pub(crate) struct Parser<'a> { /// not the `@at-rule` block has a super selector pub at_root_has_selector: bool, pub extender: &'a mut Extender, + + pub load_paths: &'a Vec<&'a Path>, } impl<'a> Parser<'a> { @@ -359,6 +361,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths }, allows_parent, true, @@ -597,6 +600,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse_stmt()?; @@ -664,6 +668,7 @@ impl<'a> Parser<'a> { at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse()? .into_iter() @@ -704,6 +709,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse_selector(false, true, String::new())?; @@ -781,6 +787,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse_stmt()?; diff --git a/src/parse/value/parse.rs b/src/parse/value/parse.rs index 4d1ba33..7c44737 100644 --- a/src/parse/value/parse.rs +++ b/src/parse/value/parse.rs @@ -201,6 +201,7 @@ impl<'a> Parser<'a> { at_root_has_selector: self.at_root_has_selector, extender: self.extender, content_scopes: self.content_scopes, + load_paths: self.load_paths } .parse_value(in_paren) } diff --git a/src/value/mod.rs b/src/value/mod.rs index 780f957..0b9b149 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -476,6 +476,7 @@ impl Value { at_root_has_selector: parser.at_root_has_selector, extender: parser.extender, content_scopes: parser.content_scopes, + load_paths: parser.load_paths } .parse_selector(allows_parent, true, String::new()) }