New linter CLI command #139

This commit is contained in:
sagie gur ari 2020-11-15 12:25:27 +00:00
parent 2a479400a3
commit f036028108
4 changed files with 82 additions and 6 deletions

View file

@ -1,5 +1,9 @@
## CHANGELOG
### v0.6.9
* New linter CLI command #139
### v0.6.8 (2020-10-01)
* Runtime - Fix variable expansion and support single $ and % characters #132

View file

@ -4,6 +4,7 @@ USAGE:
FLAGS:
-h, --help Prints help information
-e, --eval Evaluate script
-l, --lint Lints the provided file
ARGS:
<FILE> The script file to execute
<FILE> The script file to execute/lint

View file

@ -0,0 +1,63 @@
use duckscript::parser;
use duckscript::types::error::{ErrorInfo, ScriptError};
use duckscript::types::instruction::{Instruction, InstructionType, ScriptInstruction};
pub(crate) fn lint_file(file: &str) -> Result<(), ScriptError> {
match parser::parse_file(file) {
Ok(instructions) => {
println!("File: {} parsed correctly.", file);
match lint_instructions(instructions) {
Ok(_) => {
println!("No lint errors found in file: {}", file);
Ok(())
}
Err(error) => Err(error),
}
}
Err(error) => Err(error),
}
}
fn lint_instructions(instructions: Vec<Instruction>) -> Result<(), ScriptError> {
for instruction in &instructions {
let result = match &instruction.instruction_type {
InstructionType::Script(ref script_instruction) => lint_instruction(script_instruction),
_ => Ok(()),
};
match result {
Err(error) => {
return Err(ScriptError {
info: ErrorInfo::Runtime(error, Some(instruction.meta_info.clone())),
})
}
_ => (),
}
}
Ok(())
}
fn lint_instruction(script_instruction: &ScriptInstruction) -> Result<(), String> {
if !is_lower_case(script_instruction.label.clone()) {
Err("Labels should be all lowercase.".to_string())
} else if !is_lower_case(script_instruction.command.clone()) {
Err("Commands should be all lowercase.".to_string())
} else if !is_lower_case(script_instruction.output.clone()) {
Err("Output variable should be all lowercase.".to_string())
} else {
Ok(())
}
}
fn is_lower_case(value: Option<String>) -> bool {
match value {
Some(text) => {
let lower_case_text = text.to_lowercase();
lower_case_text == text
}
None => true,
}
}

View file

@ -141,6 +141,8 @@
//! [Apache 2](https://github.com/sagiegurari/duckscript/blob/master/LICENSE) open source license.
//!
mod linter;
use duckscript::runner;
use duckscript::types::error::ScriptError;
use duckscript::types::runtime::Context;
@ -185,17 +187,23 @@ fn run_cli() -> Result<(), ScriptError> {
Ok(())
} else {
let (value, is_file) = if args.len() == 2 {
(args[1].clone(), true)
let (value, is_file, run) = if args.len() == 2 {
(args[1].clone(), true, true)
} else {
if args[1] == "-e" || args[1] == "--eval" {
(args[2].clone(), false)
(args[2].clone(), false, true)
} else if args[1] == "-l" || args[1] == "--lint" {
(args[2].clone(), true, false)
} else {
(args[1].clone(), true)
(args[1].clone(), true, true)
}
};
run_script(&value, is_file)
if run {
run_script(&value, is_file)
} else {
linter::lint_file(&value)
}
}
}