option for multiple inputs

This commit is contained in:
matthieu.jolimaitre 2022-09-24 21:54:34 +02:00
parent cbd6eb52b1
commit a2868c8783
10 changed files with 78 additions and 44 deletions

View file

@ -16,3 +16,6 @@ notify-debouncer-mini = "0.2.1"
ron = "0.8.0" ron = "0.8.0"
serde = { version = "1.0.144", features = ["derive"] } serde = { version = "1.0.144", features = ["derive"] }
termion = "1.5.6" termion = "1.5.6"
[profile.release]
lto = true

15
example/simple/main.c Normal file
View file

@ -0,0 +1,15 @@
#include <stdio.h>
#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);
}

View file

@ -1,3 +1,3 @@
pub fn main(_file: String) { pub fn main(_files: Vec<String>) {
todo!() todo!()
} }

View file

@ -22,16 +22,13 @@ pub enum Commands {
/// Checks a source file for conformance with piscine limitations. /// Checks a source file for conformance with piscine limitations.
check { check {
/// File to check. /// File to check.
/// Supports globing files: Vec<String>,
#[clap(default_value_t = String::from("*"))]
file: String,
}, },
/// Runs a file /// Runs a file
run { run {
/// File to run. /// Files to run.
#[clap(default_value_t = String::from("./main.c"))] files: Vec<String>,
file: String,
}, },
/// Runs tests contained within a particular test file or /// Runs tests contained within a particular test file or
@ -40,9 +37,8 @@ pub enum Commands {
#[clap(short, long)] #[clap(short, long)]
capture: bool, capture: bool,
/// File to run tests from. /// Files to run tests from.
#[clap(default_value_t = String::from("./test.c"))] files: Vec<String>,
file: String,
/// Specific test to run. /// Specific test to run.
test: Option<String>, test: Option<String>,
@ -50,9 +46,8 @@ pub enum Commands {
/// Watches changes to source files and re run them /// Watches changes to source files and re run them
watch { watch {
/// File to run. /// Files to run.
#[clap(default_value_t = String::from("./main.c"))] files: Vec<String>,
file: String,
}, },
} }
@ -60,15 +55,15 @@ fn main() {
let args: Arguments = Parser::parse(); let args: Arguments = Parser::parse();
match args.command { match args.command {
Commands::check { file } => check::main(file), Commands::check { files } => check::main(files),
Commands::run { file } => { Commands::run { files } => {
run::main(file); run::main(files);
} }
Commands::test { Commands::test {
capture, capture,
file, files,
test, test,
} => test::main(capture, file, test), } => test::main(capture, files, test),
Commands::watch { file } => watch::main(file), Commands::watch { files } => watch::main(files),
} }
} }

View file

@ -3,8 +3,8 @@ use crate::{
utils::{log_failure, log_success}, utils::{log_failure, log_success},
}; };
pub fn main(file: String) -> Option<()> { pub fn main(files: Vec<String>) -> Option<()> {
let source_file = file.into(); let source_file = files.into_iter().map(|f| f.into()).collect();
let compiled = CompileTask::new(source_file) let compiled = CompileTask::new(source_file)
.with_flag("-Wall") .with_flag("-Wall")
.with_flag("-Wextra") .with_flag("-Wextra")

View file

@ -4,10 +4,12 @@ use std::{
process::{Command, ExitStatus}, 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 { pub struct CompileTask {
file: PathBuf, files: Vec<PathBuf>,
addition: Vec<String>, addition: Vec<String>,
flags: Vec<String>, flags: Vec<String>,
} }
@ -15,9 +17,9 @@ pub struct CompileTask {
// TODO: split compile & compile raw // TODO: split compile & compile raw
impl CompileTask { impl CompileTask {
pub fn new(file: PathBuf) -> Self { pub fn new(files: Vec<PathBuf>) -> Self {
Self { Self {
file, files,
addition: vec![], addition: vec![],
flags: vec![], flags: vec![],
} }
@ -35,7 +37,8 @@ impl CompileTask {
pub fn run(self) -> Result<PathBuf, ExitStatus> { pub fn run(self) -> Result<PathBuf, ExitStatus> {
let proc_source = self.gen_source(); 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) self.compile(sources)
} }
@ -56,9 +59,9 @@ impl CompileTask {
.args(self.flags.clone()) .args(self.flags.clone())
.args(sources.iter().map(|s| s.to_str().unwrap())); .args(sources.iter().map(|s| s.to_str().unwrap()));
log_command_run(&command); log_command_run(&command);
log_separator(); log_separator_top();
let status = command.status().unwrap(); let status = command.status().unwrap();
log_separator(); log_separator_bottom();
status.success().then_some(output_path).ok_or(status) status.success().then_some(output_path).ok_or(status)
} }
} }
@ -75,9 +78,9 @@ impl RunTask {
pub fn run(self) -> Result<(), ExitStatus> { pub fn run(self) -> Result<(), ExitStatus> {
let mut command = Command::new(self.file); let mut command = Command::new(self.file);
log_command_run(&command); log_command_run(&command);
log_separator(); log_separator_top();
let status = command.status().unwrap(); let status = command.status().unwrap();
log_separator(); log_separator_bottom();
if status.success() { if status.success() {
Ok(()) Ok(())
} else { } else {

View file

@ -1,4 +1,4 @@
pub fn main(_capture: bool, _file: String, _test: Option<String>) { pub fn main(_capture: bool, _files: Vec<String>, _test: Option<String>) {
let content = todo!(); let content = todo!();
let tests = find_tests(content); let tests = find_tests(content);
for test in tests { for test in tests {

View file

@ -42,6 +42,14 @@ pub fn log_separator() {
println!("────────────────") println!("────────────────")
} }
pub fn log_separator_top() {
println!("───────────────┐")
}
pub fn log_separator_bottom() {
println!("───────────────┘")
}
pub fn log_failure(text: &str) { pub fn log_failure(text: &str) {
log_pi_prefix(); log_pi_prefix();
let text = format!("{}{text}{}", color::Fg(color::Red), color::Fg(color::Reset)); let text = format!("{}{text}{}", color::Fg(color::Red), color::Fg(color::Reset));

View file

@ -1,6 +1,5 @@
use std::{path::Path, sync::mpsc, time::Duration}; use std::{path::Path, sync::mpsc, time::Duration};
use notify::{Error, Event, Watcher};
use notify_debouncer_mini::new_debouncer; use notify_debouncer_mini::new_debouncer;
use crate::{ use crate::{
@ -9,16 +8,16 @@ use crate::{
}; };
pub struct Repeater { pub struct Repeater {
file: String, files: Vec<String>,
} }
impl Repeater { impl Repeater {
pub fn new(file: String) -> Self { pub fn new(files: Vec<String>) -> Self {
Self { file } Self { files }
} }
pub fn repeat(&self) -> Option<()> { 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() .run()
.map(Option::from) .map(Option::from)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -27,7 +26,7 @@ impl Repeater {
})?; })?;
log_success("compilation successful"); log_success("compilation successful");
RunTask::new(source) RunTask::new(binary)
.run() .run()
.map(Option::from) .map(Option::from)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {
@ -41,18 +40,20 @@ impl Repeater {
} }
} }
pub fn main(file: String) { pub fn main(files: Vec<String>) {
log_process(&format!("watching file '{file}'")); log_process(&format!("watching files '{files:?}'"));
let repeater = Repeater::new(file.clone()); let repeater = Repeater::new(files.clone());
repeater.repeat(); repeater.repeat();
let (send, rec) = mpsc::channel(); let (send, rec) = mpsc::channel();
let mut debouncer = new_debouncer(Duration::from_millis(100), None, send).unwrap(); let mut debouncer = new_debouncer(Duration::from_millis(100), None, send).unwrap();
for file in files {
debouncer debouncer
.watcher() .watcher()
.watch(Path::new(&file), notify::RecursiveMode::Recursive) .watch(Path::new(&file), notify::RecursiveMode::Recursive)
.unwrap(); .unwrap();
}
for events in rec { for events in rec {
for _ in events.unwrap() { for _ in events.unwrap() {

9
test.h Normal file
View file

@ -0,0 +1,9 @@
#include <stdlib.h>
#include <stdio.h>
void assert_eq_int(int left, int right) {
if (left != right) {
printf("assertion failed\n'%i' != '%i'\n", left, right);
exit(1);
}
}