rune/cli/
check.rs
1use std::io::Write;
2use std::path::Path;
3use std::path::PathBuf;
4
5use anyhow::{Context, Result};
6
7use crate::cli::{visitor, AssetKind, CommandBase, Config, Entry, ExitCode, Io, SharedFlags};
8use crate::compile::FileSourceLoader;
9use crate::{Diagnostics, Options, Source, Sources};
10
11mod cli {
12 use std::path::PathBuf;
13 use std::vec::Vec;
14
15 use clap::Parser;
16
17 #[derive(Parser, Debug)]
18 #[command(rename_all = "kebab-case")]
19 pub(crate) struct Flags {
20 #[arg(long)]
22 pub(super) warnings_are_errors: bool,
23 pub(super) check_path: Vec<PathBuf>,
25 }
26}
27
28pub(super) use cli::Flags;
29
30impl CommandBase for Flags {
31 #[inline]
32 fn is_debug(&self) -> bool {
33 true
34 }
35
36 #[inline]
37 fn is_workspace(&self, _: AssetKind) -> bool {
38 true
39 }
40
41 #[inline]
42 fn describe(&self) -> &str {
43 "Checking"
44 }
45
46 #[inline]
47 fn paths(&self) -> &[PathBuf] {
48 &self.check_path
49 }
50}
51
52pub(super) fn run(
53 io: &mut Io<'_>,
54 entry: &mut Entry<'_>,
55 c: &Config,
56 flags: &Flags,
57 shared: &SharedFlags,
58 options: &Options,
59 path: &Path,
60) -> Result<ExitCode> {
61 writeln!(io.stdout, "Checking: {}", path.display())?;
62
63 let context = shared.context(entry, c, None)?;
64
65 let source =
66 Source::from_path(path).with_context(|| format!("reading file: {}", path.display()))?;
67
68 let mut sources = Sources::new();
69
70 sources.insert(source)?;
71
72 let mut diagnostics = if shared.warnings || flags.warnings_are_errors {
73 Diagnostics::new()
74 } else {
75 Diagnostics::without_warnings()
76 };
77
78 let mut test_finder = visitor::FunctionVisitor::new(visitor::Attribute::None);
79 let mut source_loader = FileSourceLoader::new();
80
81 let _ = crate::prepare(&mut sources)
82 .with_context(&context)
83 .with_diagnostics(&mut diagnostics)
84 .with_options(options)
85 .with_visitor(&mut test_finder)?
86 .with_source_loader(&mut source_loader)
87 .build();
88
89 diagnostics.emit(&mut io.stdout.lock(), &sources)?;
90
91 if diagnostics.has_error() || flags.warnings_are_errors && diagnostics.has_warning() {
92 Ok(ExitCode::Failure)
93 } else {
94 Ok(ExitCode::Success)
95 }
96}