diff --git a/Cargo.toml b/Cargo.toml index 17fbad1..4f0dedb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,6 @@ notify-debouncer-mini = "0.2.1" ron = "0.8.0" serde = { version = "1.0.144", features = ["derive"] } termion = "1.5.6" + +[profile.release] +lto = true diff --git a/example/simple/main.c b/example/simple/main.c new file mode 100644 index 0000000..a616ec4 --- /dev/null +++ b/example/simple/main.c @@ -0,0 +1,15 @@ +#include +#include "../../test.h" + +int main() { + int a; + printf("hello, world!! %d\n", a); +} + +void test_it_works() { + assert_eq_int(2 + 2, 4); +} + +void test_it_fails() { + assert_eq_int(2 + 2, 5); +} diff --git a/src/check.rs b/src/check.rs index ea20cb5..9e6044a 100644 --- a/src/check.rs +++ b/src/check.rs @@ -1,3 +1,3 @@ -pub fn main(_file: String) { +pub fn main(_files: Vec) { todo!() } diff --git a/src/main.rs b/src/main.rs index c3514ba..6ba98e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,16 +22,13 @@ pub enum Commands { /// Checks a source file for conformance with piscine limitations. check { /// File to check. - /// Supports globing - #[clap(default_value_t = String::from("*"))] - file: String, + files: Vec, }, /// Runs a file run { - /// File to run. - #[clap(default_value_t = String::from("./main.c"))] - file: String, + /// Files to run. + files: Vec, }, /// Runs tests contained within a particular test file or @@ -40,9 +37,8 @@ pub enum Commands { #[clap(short, long)] capture: bool, - /// File to run tests from. - #[clap(default_value_t = String::from("./test.c"))] - file: String, + /// Files to run tests from. + files: Vec, /// Specific test to run. test: Option, @@ -50,9 +46,8 @@ pub enum Commands { /// Watches changes to source files and re run them watch { - /// File to run. - #[clap(default_value_t = String::from("./main.c"))] - file: String, + /// Files to run. + files: Vec, }, } @@ -60,15 +55,15 @@ fn main() { let args: Arguments = Parser::parse(); match args.command { - Commands::check { file } => check::main(file), - Commands::run { file } => { - run::main(file); + Commands::check { files } => check::main(files), + Commands::run { files } => { + run::main(files); } Commands::test { capture, - file, + files, test, - } => test::main(capture, file, test), - Commands::watch { file } => watch::main(file), + } => test::main(capture, files, test), + Commands::watch { files } => watch::main(files), } } diff --git a/src/run.rs b/src/run.rs index 5d8685a..647a11a 100644 --- a/src/run.rs +++ b/src/run.rs @@ -3,8 +3,8 @@ use crate::{ utils::{log_failure, log_success}, }; -pub fn main(file: String) -> Option<()> { - let source_file = file.into(); +pub fn main(files: Vec) -> Option<()> { + let source_file = files.into_iter().map(|f| f.into()).collect(); let compiled = CompileTask::new(source_file) .with_flag("-Wall") .with_flag("-Wextra") diff --git a/src/tasks.rs b/src/tasks.rs index e86e451..05120d8 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -4,10 +4,12 @@ use std::{ process::{Command, ExitStatus}, }; -use crate::utils::{log_command_run, log_separator, tmp_file_path, Apply}; +use crate::utils::{ + log_command_run, log_separator, log_separator_bottom, log_separator_top, tmp_file_path, Apply, +}; pub struct CompileTask { - file: PathBuf, + files: Vec, addition: Vec, flags: Vec, } @@ -15,9 +17,9 @@ pub struct CompileTask { // TODO: split compile & compile raw impl CompileTask { - pub fn new(file: PathBuf) -> Self { + pub fn new(files: Vec) -> Self { Self { - file, + files, addition: vec![], flags: vec![], } @@ -35,7 +37,8 @@ impl CompileTask { pub fn run(self) -> Result { let proc_source = self.gen_source(); - let sources = vec![proc_source, self.file.clone()]; + let mut sources = self.files.clone(); + sources.push(proc_source); self.compile(sources) } @@ -56,9 +59,9 @@ impl CompileTask { .args(self.flags.clone()) .args(sources.iter().map(|s| s.to_str().unwrap())); log_command_run(&command); - log_separator(); + log_separator_top(); let status = command.status().unwrap(); - log_separator(); + log_separator_bottom(); status.success().then_some(output_path).ok_or(status) } } @@ -75,9 +78,9 @@ impl RunTask { pub fn run(self) -> Result<(), ExitStatus> { let mut command = Command::new(self.file); log_command_run(&command); - log_separator(); + log_separator_top(); let status = command.status().unwrap(); - log_separator(); + log_separator_bottom(); if status.success() { Ok(()) } else { diff --git a/src/test.rs b/src/test.rs index 5b4da87..523b802 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,4 +1,4 @@ -pub fn main(_capture: bool, _file: String, _test: Option) { +pub fn main(_capture: bool, _files: Vec, _test: Option) { let content = todo!(); let tests = find_tests(content); for test in tests { diff --git a/src/utils.rs b/src/utils.rs index b59b314..ecea085 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -42,6 +42,14 @@ pub fn log_separator() { println!("────────────────") } +pub fn log_separator_top() { + println!("───────────────┐") +} + +pub fn log_separator_bottom() { + println!("───────────────┘") +} + pub fn log_failure(text: &str) { log_pi_prefix(); let text = format!("{}{text}{}", color::Fg(color::Red), color::Fg(color::Reset)); diff --git a/src/watch.rs b/src/watch.rs index b62d839..cf1ad14 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -1,6 +1,5 @@ use std::{path::Path, sync::mpsc, time::Duration}; -use notify::{Error, Event, Watcher}; use notify_debouncer_mini::new_debouncer; use crate::{ @@ -9,16 +8,16 @@ use crate::{ }; pub struct Repeater { - file: String, + files: Vec, } impl Repeater { - pub fn new(file: String) -> Self { - Self { file } + pub fn new(files: Vec) -> Self { + Self { files } } pub fn repeat(&self) -> Option<()> { - let source = CompileTask::new(self.file.clone().into()) + let binary = CompileTask::new(self.files.clone().into_iter().map(|f| f.into()).collect()) .run() .map(Option::from) .unwrap_or_else(|_| { @@ -27,7 +26,7 @@ impl Repeater { })?; log_success("compilation successful"); - RunTask::new(source) + RunTask::new(binary) .run() .map(Option::from) .unwrap_or_else(|_| { @@ -41,18 +40,20 @@ impl Repeater { } } -pub fn main(file: String) { - log_process(&format!("watching file '{file}'")); - let repeater = Repeater::new(file.clone()); +pub fn main(files: Vec) { + log_process(&format!("watching files '{files:?}'")); + let repeater = Repeater::new(files.clone()); repeater.repeat(); let (send, rec) = mpsc::channel(); let mut debouncer = new_debouncer(Duration::from_millis(100), None, send).unwrap(); - debouncer - .watcher() - .watch(Path::new(&file), notify::RecursiveMode::Recursive) - .unwrap(); + for file in files { + debouncer + .watcher() + .watch(Path::new(&file), notify::RecursiveMode::Recursive) + .unwrap(); + } for events in rec { for _ in events.unwrap() { diff --git a/test.h b/test.h new file mode 100644 index 0000000..b969cee --- /dev/null +++ b/test.h @@ -0,0 +1,9 @@ +#include +#include + +void assert_eq_int(int left, int right) { + if (left != right) { + printf("assertion failed\n'%i' != '%i'\n", left, right); + exit(1); + } +} \ No newline at end of file