diff --git a/src/compilation.rs b/src/compilation.rs index c3bd9d514d..dd600baef0 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -5,15 +5,10 @@ pub(crate) struct Compilation<'src> { pub(crate) asts: HashMap>, pub(crate) justfile: Justfile<'src>, pub(crate) root: PathBuf, - pub(crate) srcs: HashMap, } impl<'src> Compilation<'src> { pub(crate) fn root_ast(&self) -> &Ast<'src> { self.asts.get(&self.root).unwrap() } - - pub(crate) fn root_src(&self) -> &'src str { - self.srcs.get(&self.root).unwrap() - } } diff --git a/src/compiler.rs b/src/compiler.rs index 55b4e9f346..76bf610748 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -11,8 +11,6 @@ impl Compiler { let mut asts = HashMap::::new(); let mut loaded = Vec::new(); let mut paths = HashMap::::new(); - let mut srcs = HashMap::::new(); - let mut stack = Vec::new(); stack.push(Source::root(root)); @@ -23,18 +21,9 @@ impl Compiler { let (relative, src) = loader.load(root, ¤t.path)?; loaded.push(relative.into()); - - let tokens = Lexer::lex(relative, src)?; - let mut ast = Parser::parse( - current.file_depth, - ¤t.import_offsets, - current.namepath.as_ref(), - &tokens, - ¤t.working_directory, - )?; + let mut ast = Parser::parse_source(relative, src, ¤t)?; paths.insert(current.path.clone(), relative.into()); - srcs.insert(current.path.clone(), src); for item in &mut ast.items { match item { @@ -107,7 +96,6 @@ impl Compiler { asts, justfile, root: root.into(), - srcs, }) } @@ -244,43 +232,6 @@ impl Compiler { mod tests { use {super::*, temptree::temptree}; - #[test] - fn include_justfile() { - let justfile_a = r#" -# A comment at the top of the file -import "./justfile_b" - -#some_recipe: recipe_b -some_recipe: - echo "some recipe" -"#; - - let justfile_b = r#"import "./subdir/justfile_c" - -recipe_b: recipe_c - echo "recipe b" -"#; - - let justfile_c = r#"recipe_c: - echo "recipe c" -"#; - - let tmp = temptree! { - justfile: justfile_a, - justfile_b: justfile_b, - subdir: { - justfile_c: justfile_c - } - }; - - let loader = Loader::new(); - - let justfile_a_path = tmp.path().join("justfile"); - let compilation = Compiler::compile(&Config::default(), &loader, &justfile_a_path).unwrap(); - - assert_eq!(compilation.root_src(), justfile_a); - } - #[test] fn recursive_includes_fail() { let tmp = temptree! { diff --git a/src/parser.rs b/src/parser.rs index b1346354eb..a48fc86ba2 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -58,6 +58,22 @@ impl<'run, 'src> Parser<'run, 'src> { .parse_ast() } + pub(crate) fn parse_source( + path: &'src Path, + src: &'src str, + source: &Source<'src>, + ) -> CompileResult<'src, Ast<'src>> { + let tokens = Lexer::lex(path, src)?; + + Parser::parse( + source.file_depth, + &source.import_offsets, + source.namepath.as_ref(), + &tokens, + &source.working_directory, + ) + } + fn error(&self, kind: CompileErrorKind<'src>) -> CompileResult<'src, CompileError<'src>> { Ok(self.next()?.error(kind)) } diff --git a/src/subcommand.rs b/src/subcommand.rs index 1fb8deab31..e78a6b797e 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -87,6 +87,10 @@ impl Subcommand { return Self::edit(&search); } + if matches!(self, Format) { + return Self::format(config, loader, &search); + } + let compilation = Self::compile(config, loader, &search)?; let justfile = &compilation.justfile; @@ -98,7 +102,6 @@ impl Subcommand { justfile.run(config, &search, &[])?; } Dump => Self::dump(config, compilation)?, - Format => Self::format(config, &search, compilation)?, Groups => Self::groups(config, justfile), List { path } => Self::list(config, justfile, path)?, Run { arguments } => Self::run(config, loader, search, compilation, arguments)?, @@ -106,7 +109,9 @@ impl Subcommand { Summary => Self::summary(config, justfile), Usage { path } => Self::usage(config, justfile, path)?, Variables => Self::variables(justfile), - Changelog | Completions { .. } | Edit | Init | Man | Request { .. } => unreachable!(), + Changelog | Completions { .. } | Edit | Format | Init | Man | Request { .. } => { + unreachable!() + } } Ok(()) @@ -324,12 +329,29 @@ impl Subcommand { Ok(()) } - fn format(config: &Config, search: &Search, compilation: Compilation) -> RunResult<'static> { - let justfile = &compilation.justfile; - let src = compilation.root_src(); - let ast = compilation.root_ast(); + fn format<'src>(config: &Config, loader: &'src Loader, search: &Search) -> RunResult<'src> { + let root = search.justfile.parent().unwrap(); + + let (path, src) = loader.load(root, &search.justfile)?; + + let ast = Parser::parse_source(path, src, &Source::root(&search.justfile))?; - config.require_unstable(justfile, UnstableFeature::FormatSubcommand)?; + let unstable = config.unstable + || ast.items.iter().any(|item| { + matches!( + item, + Item::Set(Set { + value: Setting::Unstable(true), + .. + }) + ) + }); + + if !unstable { + return Err(Error::UnstableFeature { + unstable_feature: UnstableFeature::FormatSubcommand, + }); + } let formatted = ast.to_string(); diff --git a/tests/format.rs b/tests/format.rs index e7a4918e12..31937090b7 100644 --- a/tests/format.rs +++ b/tests/format.rs @@ -1700,3 +1700,21 @@ fn arg_attribute_help() { ) .success(); } + +#[test] +fn missing_import_file() { + Test::new() + .args(["--unstable", "--fmt", "--check"]) + .justfile("import 'foo'\n") + .test_round_trip(false) + .success(); +} + +#[test] +fn missing_module_file() { + Test::new() + .args(["--unstable", "--fmt", "--check"]) + .justfile("mod foo\n") + .test_round_trip(false) + .success(); +}