worked on config
This commit is contained in:
parent
a2868c8783
commit
37e5b5e555
9 changed files with 225 additions and 39 deletions
60
Cargo.lock
generated
60
Cargo.lock
generated
|
@ -2,6 +2,15 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
|
@ -46,6 +55,12 @@ version = "3.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -144,6 +159,8 @@ dependencies = [
|
|||
"ron",
|
||||
"serde",
|
||||
"termion",
|
||||
"tree-sitter",
|
||||
"tree-sitter-c",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -282,6 +299,12 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.4"
|
||||
|
@ -419,6 +442,23 @@ dependencies = [
|
|||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.0"
|
||||
|
@ -514,6 +554,26 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4423c784fe11398ca91e505cdc71356b07b1a924fc8735cfab5333afe3e18bc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-c"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cca211f4827d4b4dc79f388bf67b6fa3bc8a8cfa642161ef24f99f371ba34c7b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
|
|
|
@ -16,6 +16,8 @@ notify-debouncer-mini = "0.2.1"
|
|||
ron = "0.8.0"
|
||||
serde = { version = "1.0.144", features = ["derive"] }
|
||||
termion = "1.5.6"
|
||||
tree-sitter = "0.20.9"
|
||||
tree-sitter-c = "0.20.2"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
#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);
|
||||
}
|
||||
|
|
10
example/simple/test.c
Normal file
10
example/simple/test.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include "../../clib/test.h"
|
||||
|
||||
void test_it_works() {
|
||||
assert_eq_int(2 + 2, 4);
|
||||
}
|
||||
|
||||
void test_it_fails() {
|
||||
assert_eq_int(2 + 2, 5);
|
||||
}
|
|
@ -1,21 +1,80 @@
|
|||
pub struct UserConfig {
|
||||
main_file: Option<String>,
|
||||
test_file: Option<String>,
|
||||
includes: Option<Vec<String>>,
|
||||
}
|
||||
use std::{
|
||||
env, fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use ron::ser::PrettyConfig;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::utils::Apply;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
name: String,
|
||||
main_file: String,
|
||||
test_file: String,
|
||||
includes: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
impl Config {
|
||||
const CONFIG_FILE_NAME: &'static str = "pi.ron";
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
main_file: "main.c".into(),
|
||||
test_file: "test.c".into(),
|
||||
includes: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, mut path: PathBuf) {
|
||||
path.extend([Self::CONFIG_FILE_NAME]);
|
||||
let content =
|
||||
ron::ser::to_string_pretty(self, PrettyConfig::default().struct_names(true)).unwrap();
|
||||
fs::write(path, content).unwrap();
|
||||
}
|
||||
|
||||
pub fn get_current() -> Self {
|
||||
let path = env::current_dir().unwrap();
|
||||
Self::get(&path)
|
||||
.unwrap_or_else(|| Self::new(path.file_name().unwrap().to_str().unwrap().to_string()))
|
||||
}
|
||||
|
||||
pub fn get(path: &Path) -> Option<Self> {
|
||||
let path = path.to_path_buf().canonicalize().unwrap();
|
||||
Self::try_get(&path).or_else(|| path.parent().and_then(Self::get))
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn main_file(&self) -> &str {
|
||||
&self.main_file
|
||||
}
|
||||
|
||||
pub fn test_file(&self) -> &str {
|
||||
&self.test_file
|
||||
}
|
||||
|
||||
pub fn includes(&self) -> &Vec<String> {
|
||||
&self.includes
|
||||
}
|
||||
|
||||
fn try_get(path: &Path) -> Option<Self> {
|
||||
let path = path.to_path_buf().apply(|p| p.push(Self::CONFIG_FILE_NAME));
|
||||
fs::read_to_string(path)
|
||||
.ok()
|
||||
.and_then(|content| ron::from_str(&content).ok())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(path: String) {
|
||||
let absolute = fs::canonicalize(&path).unwrap();
|
||||
if !absolute.is_dir() {
|
||||
panic!("not a directory");
|
||||
}
|
||||
let name = absolute.file_name().unwrap();
|
||||
let config = Config::new(name.to_str().unwrap().to_string());
|
||||
config.write(absolute);
|
||||
}
|
||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -1,4 +1,5 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
use config::Config;
|
||||
|
||||
pub mod check;
|
||||
pub mod config;
|
||||
|
@ -14,8 +15,6 @@ pub struct Arguments {
|
|||
command: Commands,
|
||||
}
|
||||
|
||||
// TODO: turn files into file lists
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
|
@ -25,7 +24,7 @@ pub enum Commands {
|
|||
files: Vec<String>,
|
||||
},
|
||||
|
||||
/// Runs a file
|
||||
/// Runs a set of files or the default target.
|
||||
run {
|
||||
/// Files to run.
|
||||
files: Vec<String>,
|
||||
|
@ -33,15 +32,16 @@ pub enum Commands {
|
|||
|
||||
/// Runs tests contained within a particular test file or
|
||||
test {
|
||||
/// W.I.P. Wether to capture standard output or not.
|
||||
/// Wether to capture standard output or not.
|
||||
#[clap(short, long)]
|
||||
capture: bool,
|
||||
|
||||
/// Files to run tests from.
|
||||
files: Vec<String>,
|
||||
|
||||
/// Specific test to run.
|
||||
test: Option<String>,
|
||||
/// Specific tests to run.
|
||||
#[clap(short, long)]
|
||||
tests: Vec<String>,
|
||||
},
|
||||
|
||||
/// Watches changes to source files and re run them
|
||||
|
@ -49,6 +49,18 @@ pub enum Commands {
|
|||
/// Files to run.
|
||||
files: Vec<String>,
|
||||
},
|
||||
|
||||
///
|
||||
init { path: String },
|
||||
}
|
||||
|
||||
fn append_includes(list: &mut Vec<String>) {
|
||||
list.extend(
|
||||
Config::get_current()
|
||||
.includes()
|
||||
.iter()
|
||||
.map(|f| f.to_string()),
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -56,14 +68,23 @@ fn main() {
|
|||
|
||||
match args.command {
|
||||
Commands::check { files } => check::main(files),
|
||||
Commands::run { files } => {
|
||||
Commands::run { mut files } => {
|
||||
append_includes(&mut files);
|
||||
run::main(files);
|
||||
}
|
||||
Commands::test {
|
||||
capture,
|
||||
files,
|
||||
test,
|
||||
} => test::main(capture, files, test),
|
||||
Commands::watch { files } => watch::main(files),
|
||||
mut files,
|
||||
tests,
|
||||
} => {
|
||||
append_includes(&mut files);
|
||||
let tests = (!tests.is_empty()).then_some(tests);
|
||||
test::main(capture, files, tests)
|
||||
}
|
||||
Commands::watch { mut files } => {
|
||||
append_includes(&mut files);
|
||||
watch::main(files)
|
||||
}
|
||||
Commands::init { path } => config::create(path),
|
||||
}
|
||||
}
|
||||
|
|
21
src/tasks.rs
21
src/tasks.rs
|
@ -2,10 +2,12 @@ use std::{
|
|||
fs,
|
||||
path::PathBuf,
|
||||
process::{Command, ExitStatus},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::utils::{
|
||||
log_command_run, log_separator, log_separator_bottom, log_separator_top, tmp_file_path, Apply,
|
||||
log_command_run, log_separator_bottom, log_separator_top, tmp_file_path, Apply,
|
||||
};
|
||||
|
||||
pub struct CompileTask {
|
||||
|
@ -62,6 +64,7 @@ impl CompileTask {
|
|||
log_separator_top();
|
||||
let status = command.status().unwrap();
|
||||
log_separator_bottom();
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
status.success().then_some(output_path).ok_or(status)
|
||||
}
|
||||
}
|
||||
|
@ -88,3 +91,19 @@ impl RunTask {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GenTask {
|
||||
content: String,
|
||||
}
|
||||
|
||||
impl GenTask {
|
||||
pub fn new(content: String) -> Self {
|
||||
Self { content }
|
||||
}
|
||||
pub fn run(self) -> PathBuf {
|
||||
let output_path = tmp_file_path().apply(|o| o.set_extension("c"));
|
||||
fs::write(&output_path, &self.content).unwrap();
|
||||
dbg!(fs::read_to_string(&output_path).unwrap());
|
||||
output_path
|
||||
}
|
||||
}
|
||||
|
|
38
src/test.rs
38
src/test.rs
|
@ -1,29 +1,53 @@
|
|||
pub fn main(_capture: bool, _files: Vec<String>, _test: Option<String>) {
|
||||
let content = todo!();
|
||||
use std::fs;
|
||||
|
||||
use crate::tasks::{CompileTask, GenTask, RunTask};
|
||||
|
||||
pub fn main(_capture: bool, files: Vec<String>, _test: Option<Vec<String>>) {
|
||||
// let includes = files
|
||||
// .iter()
|
||||
// .cloned()
|
||||
// .map(|p| PathBuf::from_str(&p).unwrap())
|
||||
// .collect::<Vec<_>>();
|
||||
|
||||
for path in files {
|
||||
let content = fs::read_to_string(&path).unwrap();
|
||||
let tests = find_tests(content);
|
||||
for test in tests {
|
||||
// compile
|
||||
let content = gen_test_main(fs::canonicalize(&path).unwrap().to_str().unwrap(), &test);
|
||||
let generated_code = GenTask::new(content).run();
|
||||
|
||||
// compile with all files
|
||||
//let files = includes.clone().apply(|v| v.insert(0, generated_code));
|
||||
let generated_bin = CompileTask::new(vec![generated_code]).run().unwrap();
|
||||
// run
|
||||
RunTask::new(generated_bin).run().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_tests(source: String) -> Vec<String> {
|
||||
source
|
||||
.split([' ', '(', ')', ';'])
|
||||
.filter(|name| &name[0..5] == "test_")
|
||||
.filter(|name| name.starts_with("test_"))
|
||||
.map(String::from)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn gen_test_main(test_file: &str, test: &str) -> String {
|
||||
pub fn gen_test_main(path: &str, test: &str) -> String {
|
||||
format!(
|
||||
"
|
||||
#include \"{test_file}\"
|
||||
void ____test();
|
||||
|
||||
int main() {{
|
||||
{test}();
|
||||
____test();
|
||||
return 0;
|
||||
}}
|
||||
|
||||
#include \"{path}\"
|
||||
|
||||
void ____test() {{
|
||||
{test}();
|
||||
}}
|
||||
"
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue