aboutsummaryrefslogtreecommitdiff
path: root/bin/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bin/src/config.rs')
-rw-r--r--bin/src/config.rs78
1 files changed, 44 insertions, 34 deletions
diff --git a/bin/src/config.rs b/bin/src/config.rs
index 572ddde..28e6cc3 100644
--- a/bin/src/config.rs
+++ b/bin/src/config.rs
@@ -8,7 +8,7 @@ use std::{
8use crate::{dirs, err::ConfigErr, utils, LintMap}; 8use crate::{dirs, err::ConfigErr, utils, LintMap};
9 9
10use clap::Parser; 10use clap::Parser;
11use lib::LINTS; 11use lib::{session::Version, LINTS};
12use serde::{Deserialize, Serialize}; 12use serde::{Deserialize, Serialize};
13use vfs::ReadOnlyVfs; 13use vfs::ReadOnlyVfs;
14 14
@@ -29,6 +29,8 @@ pub enum SubCommand {
29 Single(Single), 29 Single(Single),
30 /// Print detailed explanation for a lint warning 30 /// Print detailed explanation for a lint warning
31 Explain(Explain), 31 Explain(Explain),
32 /// Dump a sample config to stdout
33 Dump(Dump),
32} 34}
33 35
34#[derive(Parser, Debug)] 36#[derive(Parser, Debug)]
@@ -51,7 +53,7 @@ pub struct Check {
51 pub format: OutFormat, 53 pub format: OutFormat,
52 54
53 /// Path to statix.toml 55 /// Path to statix.toml
54 #[clap(short = 'c', long = "config", default_value = ".")] 56 #[clap(short = 'c', long = "config", default_value = "./statix.toml")]
55 pub conf_path: PathBuf, 57 pub conf_path: PathBuf,
56 58
57 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout 59 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout
@@ -76,10 +78,6 @@ impl Check {
76 vfs(files.collect::<Vec<_>>()) 78 vfs(files.collect::<Vec<_>>())
77 } 79 }
78 } 80 }
79
80 pub fn lints(&self) -> Result<LintMap, ConfigErr> {
81 lints(&self.conf_path)
82 }
83} 81}
84 82
85#[derive(Parser, Debug)] 83#[derive(Parser, Debug)]
@@ -101,7 +99,7 @@ pub struct Fix {
101 pub diff_only: bool, 99 pub diff_only: bool,
102 100
103 /// Path to statix.toml 101 /// Path to statix.toml
104 #[clap(short = 'c', long = "config", default_value = ".")] 102 #[clap(short = 'c', long = "config", default_value = "./statix.toml")]
105 pub conf_path: PathBuf, 103 pub conf_path: PathBuf,
106 104
107 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout 105 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout
@@ -144,10 +142,6 @@ impl Fix {
144 FixOut::Write 142 FixOut::Write
145 } 143 }
146 } 144 }
147
148 pub fn lints(&self) -> Result<LintMap, ConfigErr> {
149 lints(&self.conf_path)
150 }
151} 145}
152 146
153#[derive(Parser, Debug)] 147#[derive(Parser, Debug)]
@@ -167,6 +161,10 @@ pub struct Single {
167 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout 161 /// Enable "streaming" mode, accept file on stdin, output diagnostics on stdout
168 #[clap(short, long = "stdin")] 162 #[clap(short, long = "stdin")]
169 pub streaming: bool, 163 pub streaming: bool,
164
165 /// Path to statix.toml
166 #[clap(short = 'c', long = "config", default_value = "./statix.toml")]
167 pub conf_path: PathBuf,
170} 168}
171 169
172impl Single { 170impl Single {
@@ -204,6 +202,9 @@ pub struct Explain {
204 pub target: u32, 202 pub target: u32,
205} 203}
206 204
205#[derive(Parser, Debug)]
206pub struct Dump {}
207
207#[derive(Debug, Copy, Clone)] 208#[derive(Debug, Copy, Clone)]
208pub enum OutFormat { 209pub enum OutFormat {
209 #[cfg(feature = "json")] 210 #[cfg(feature = "json")]
@@ -251,13 +252,19 @@ impl FromStr for OutFormat {
251 252
252#[derive(Serialize, Deserialize, Debug)] 253#[derive(Serialize, Deserialize, Debug)]
253pub struct ConfFile { 254pub struct ConfFile {
255 #[serde(default = "Vec::new")]
254 disabled: Vec<String>, 256 disabled: Vec<String>,
257 nix_version: Option<String>,
255} 258}
256 259
257impl Default for ConfFile { 260impl Default for ConfFile {
258 fn default() -> Self { 261 fn default() -> Self {
259 let disabled = vec![]; 262 let disabled = vec![];
260 Self { disabled } 263 let nix_version = Some(utils::default_nix_version());
264 Self {
265 disabled,
266 nix_version,
267 }
261 } 268 }
262} 269}
263 270
@@ -265,15 +272,7 @@ impl ConfFile {
265 pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, ConfigErr> { 272 pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, ConfigErr> {
266 let path = path.as_ref(); 273 let path = path.as_ref();
267 let config_file = fs::read_to_string(path).map_err(ConfigErr::InvalidPath)?; 274 let config_file = fs::read_to_string(path).map_err(ConfigErr::InvalidPath)?;
268 toml::de::from_str(&config_file).map_err(|err| { 275 (toml::de::from_str(&config_file)).map_err(ConfigErr::ConfFileParse)
269 let pos = err.line_col();
270 let msg = if let Some((line, col)) = pos {
271 format!("line {}, col {}", line, col)
272 } else {
273 "unknown".to_string()
274 };
275 ConfigErr::ConfFileParse(msg)
276 })
277 } 276 }
278 pub fn discover<P: AsRef<Path>>(path: P) -> Result<Self, ConfigErr> { 277 pub fn discover<P: AsRef<Path>>(path: P) -> Result<Self, ConfigErr> {
279 let cannonical_path = fs::canonicalize(path.as_ref()).map_err(ConfigErr::InvalidPath)?; 278 let cannonical_path = fs::canonicalize(path.as_ref()).map_err(ConfigErr::InvalidPath)?;
@@ -288,6 +287,29 @@ impl ConfFile {
288 pub fn dump(&self) -> String { 287 pub fn dump(&self) -> String {
289 toml::ser::to_string_pretty(&self).unwrap() 288 toml::ser::to_string_pretty(&self).unwrap()
290 } 289 }
290 pub fn lints(&self) -> LintMap {
291 utils::lint_map_of(
292 (&*LINTS)
293 .iter()
294 .filter(|l| !self.disabled.iter().any(|check| check == l.name()))
295 .cloned()
296 .collect::<Vec<_>>()
297 .as_slice(),
298 )
299 }
300 pub fn version(&self) -> Result<Version, ConfigErr> {
301 if let Some(v) = &self.nix_version {
302 v.parse::<Version>()
303 .map_err(|_| ConfigErr::ConfFileVersionParse(v.clone()))
304 } else if let Some(v) = utils::get_version_info()
305 .map(|o| o.parse::<Version>().ok())
306 .flatten()
307 {
308 Ok(v)
309 } else {
310 Ok(utils::default_nix_version().parse::<Version>().unwrap())
311 }
312 }
291} 313}
292 314
293fn parse_line_col(src: &str) -> Result<(usize, usize), ConfigErr> { 315fn parse_line_col(src: &str) -> Result<(usize, usize), ConfigErr> {
@@ -328,20 +350,8 @@ fn vfs(files: Vec<PathBuf>) -> Result<ReadOnlyVfs, ConfigErr> {
328 let _id = vfs.alloc_file_id(&file); 350 let _id = vfs.alloc_file_id(&file);
329 vfs.set_file_contents(&file, data.as_bytes()); 351 vfs.set_file_contents(&file, data.as_bytes());
330 } else { 352 } else {
331 println!("{} contains non-utf8 content", file.display()); 353 println!("`{}` contains non-utf8 content", file.display());
332 }; 354 };
333 } 355 }
334 Ok(vfs) 356 Ok(vfs)
335} 357}
336
337fn lints(conf_path: &Path) -> Result<LintMap, ConfigErr> {
338 let config_file = ConfFile::discover(conf_path)?;
339 Ok(utils::lint_map_of(
340 (&*LINTS)
341 .iter()
342 .filter(|l| !config_file.disabled.iter().any(|check| check == l.name()))
343 .cloned()
344 .collect::<Vec<_>>()
345 .as_slice(),
346 ))
347}