aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2022-01-14 16:51:42 +0000
committerAkshay <[email protected]>2022-01-14 16:51:42 +0000
commit305960c98b3b71d4b915003430730c76fcda3af3 (patch)
tree09a428186f1aaacca8c4447f2feb7e08aa204217
parent7d732a051e695353db5a3ddbb26ab766ff736043 (diff)
add dump command, support version overrides in statix.tomlsession-info
-rw-r--r--bin/src/config.rs78
-rw-r--r--bin/src/dump.rs7
-rw-r--r--bin/src/err.rs8
-rw-r--r--bin/src/fix.rs24
-rw-r--r--bin/src/lib.rs1
-rw-r--r--bin/src/lint.rs17
-rw-r--r--bin/src/main.rs2
-rw-r--r--bin/src/utils.rs4
8 files changed, 84 insertions, 57 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}
diff --git a/bin/src/dump.rs b/bin/src/dump.rs
new file mode 100644
index 0000000..5ec3f0d
--- /dev/null
+++ b/bin/src/dump.rs
@@ -0,0 +1,7 @@
1pub mod main {
2 use crate::{config::ConfFile, err::StatixErr};
3 pub fn main() -> Result<(), StatixErr> {
4 println!("{}", ConfFile::dump(&ConfFile::default()));
5 Ok(())
6 }
7}
diff --git a/bin/src/err.rs b/bin/src/err.rs
index f44d27b..8124c1f 100644
--- a/bin/src/err.rs
+++ b/bin/src/err.rs
@@ -1,7 +1,5 @@
1use std::io; 1use std::io;
2 2
3// use globset::ErrorKind;
4// use rnix::parser::ParseError;
5use thiserror::Error; 3use thiserror::Error;
6 4
7#[derive(Error, Debug)] 5#[derive(Error, Debug)]
@@ -14,8 +12,10 @@ pub enum ConfigErr {
14 InvalidPosition(String), 12 InvalidPosition(String),
15 #[error("unable to parse `{0}` as warning code")] 13 #[error("unable to parse `{0}` as warning code")]
16 InvalidWarningCode(String), 14 InvalidWarningCode(String),
17 #[error("unable to parse config file, error at: `{0}`")] 15 #[error("unable to parse config file: {0}")]
18 ConfFileParse(String), 16 ConfFileParse(toml::de::Error),
17 #[error("unable to parse nix version: `{0}`")]
18 ConfFileVersionParse(String),
19} 19}
20 20
21// #[derive(Error, Debug)] 21// #[derive(Error, Debug)]
diff --git a/bin/src/fix.rs b/bin/src/fix.rs
index 4b2ce0c..84186d4 100644
--- a/bin/src/fix.rs
+++ b/bin/src/fix.rs
@@ -41,22 +41,22 @@ pub mod main {
41 use std::borrow::Cow; 41 use std::borrow::Cow;
42 42
43 use crate::{ 43 use crate::{
44 config::{Fix as FixConfig, FixOut, Single as SingleConfig}, 44 config::{
45 FixOut, Single as SingleConfig, {ConfFile, Fix as FixConfig},
46 },
45 err::{FixErr, StatixErr}, 47 err::{FixErr, StatixErr},
46 utils,
47 }; 48 };
48 49
49 use lib::session::{SessionInfo, Version}; 50 use lib::session::SessionInfo;
50 use similar::TextDiff; 51 use similar::TextDiff;
51 52
52 pub fn all(fix_config: FixConfig) -> Result<(), StatixErr> { 53 pub fn all(fix_config: FixConfig) -> Result<(), StatixErr> {
53 let vfs = fix_config.vfs()?; 54 let vfs = fix_config.vfs()?;
54 let lints = fix_config.lints()?; 55 let conf_file = ConfFile::discover(&fix_config.conf_path)?;
56
57 let lints = conf_file.lints();
58 let version = conf_file.version()?;
55 59
56 let version = utils::get_version_info()
57 .unwrap()
58 .parse::<Version>()
59 .unwrap();
60 let session = SessionInfo::from_version(version); 60 let session = SessionInfo::from_version(version);
61 61
62 for entry in vfs.iter() { 62 for entry in vfs.iter() {
@@ -102,10 +102,10 @@ pub mod main {
102 let original_src = entry.contents; 102 let original_src = entry.contents;
103 let (line, col) = single_config.position; 103 let (line, col) = single_config.position;
104 104
105 let version = utils::get_version_info() 105 let conf_file = ConfFile::discover(&single_config.conf_path)?;
106 .unwrap() 106
107 .parse::<Version>() 107 let version = conf_file.version()?;
108 .unwrap(); 108
109 let session = SessionInfo::from_version(version); 109 let session = SessionInfo::from_version(version);
110 110
111 match ( 111 match (
diff --git a/bin/src/lib.rs b/bin/src/lib.rs
index 01d3ea7..8200347 100644
--- a/bin/src/lib.rs
+++ b/bin/src/lib.rs
@@ -1,5 +1,6 @@
1pub mod config; 1pub mod config;
2pub mod dirs; 2pub mod dirs;
3pub mod dump;
3pub mod err; 4pub mod err;
4pub mod explain; 5pub mod explain;
5pub mod fix; 6pub mod fix;
diff --git a/bin/src/lint.rs b/bin/src/lint.rs
index c385007..055bb76 100644
--- a/bin/src/lint.rs
+++ b/bin/src/lint.rs
@@ -43,19 +43,22 @@ pub mod main {
43 use std::io; 43 use std::io;
44 44
45 use super::lint_with; 45 use super::lint_with;
46 use crate::{config::Check as CheckConfig, err::StatixErr, traits::WriteDiagnostic, utils}; 46 use crate::{
47 config::{Check as CheckConfig, ConfFile},
48 err::StatixErr,
49 traits::WriteDiagnostic,
50 };
47 51
48 use lib::session::{SessionInfo, Version}; 52 use lib::session::SessionInfo;
49 53
50 pub fn main(check_config: CheckConfig) -> Result<(), StatixErr> { 54 pub fn main(check_config: CheckConfig) -> Result<(), StatixErr> {
51 let vfs = check_config.vfs()?; 55 let vfs = check_config.vfs()?;
52 let mut stdout = io::stdout(); 56 let mut stdout = io::stdout();
53 let lints = check_config.lints()?;
54 57
55 let version = utils::get_version_info() 58 let conf_file = ConfFile::discover(&check_config.conf_path)?;
56 .unwrap() 59 let lints = conf_file.lints();
57 .parse::<Version>() 60 let version = conf_file.version()?;
58 .unwrap(); 61
59 let session = SessionInfo::from_version(version); 62 let session = SessionInfo::from_version(version);
60 63
61 let lint = |vfs_entry| lint_with(vfs_entry, &lints, &session); 64 let lint = |vfs_entry| lint_with(vfs_entry, &lints, &session);
diff --git a/bin/src/main.rs b/bin/src/main.rs
index f504796..be79bb8 100644
--- a/bin/src/main.rs
+++ b/bin/src/main.rs
@@ -1,6 +1,7 @@
1use clap::Parser; 1use clap::Parser;
2use statix::{ 2use statix::{
3 config::{Opts, SubCommand}, 3 config::{Opts, SubCommand},
4 dump,
4 err::StatixErr, 5 err::StatixErr,
5 explain, fix, lint, 6 explain, fix, lint,
6}; 7};
@@ -12,6 +13,7 @@ fn _main() -> Result<(), StatixErr> {
12 SubCommand::Fix(config) => fix::main::all(config), 13 SubCommand::Fix(config) => fix::main::all(config),
13 SubCommand::Single(config) => fix::main::single(config), 14 SubCommand::Single(config) => fix::main::single(config),
14 SubCommand::Explain(config) => explain::main::main(config), 15 SubCommand::Explain(config) => explain::main::main(config),
16 SubCommand::Dump(_) => dump::main::main(),
15 } 17 }
16} 18}
17 19
diff --git a/bin/src/utils.rs b/bin/src/utils.rs
index a3d51b4..1adac4a 100644
--- a/bin/src/utils.rs
+++ b/bin/src/utils.rs
@@ -35,3 +35,7 @@ pub fn get_version_info() -> Option<String> {
35 .nth(2) 35 .nth(2)
36 .map(ToOwned::to_owned) 36 .map(ToOwned::to_owned)
37} 37}
38
39pub fn default_nix_version() -> String {
40 String::from("2.4")
41}