From d7dd2fd855955c0477b8db21f13c9b33e3150ca8 Mon Sep 17 00:00:00 2001 From: Lawrence Bethlenfalvy Date: Mon, 3 Feb 2025 12:01:21 +0100 Subject: [PATCH] Infra for debugging and testing --- .cargo/config.toml | 6 ++++ lex-hello.ps1 | 5 +-- orchid-extension/src/entrypoint.rs | 1 - orcx/Cargo.toml | 2 +- orcx/src/main.rs | 31 ++++++++++++---- xtask/src/check_api_refs.rs | 48 +++++++++++++++++++++++++ xtask/src/main.rs | 57 +++++++----------------------- xtask/src/orcx.rs | 19 ++++++++++ 8 files changed, 112 insertions(+), 57 deletions(-) create mode 100644 xtask/src/check_api_refs.rs create mode 100644 xtask/src/orcx.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 9741f11..4b6b4df 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,8 @@ [alias] xtask = "run --quiet --package xtask --" +orcx = "xtask orcx" + +[env] +ORCHID_EXTENSIONS = "target/debug/orchid-std" +ORCHID_DEFAULT_SYSTEMS = "orchid::std" +ORCHID_LOG_BUFFERS = "true" diff --git a/lex-hello.ps1 b/lex-hello.ps1 index 941a68f..eb3145d 100644 --- a/lex-hello.ps1 +++ b/lex-hello.ps1 @@ -1,5 +1,2 @@ -[System.Environment]::SetEnvironmentVariable("ORCHID_LOG_BUFFERS", "true") cargo build -p orchid-std -cargo run -p orcx -- ` - --extension .\target\debug\orchid-std.exe --system orchid::std ` - lex --file .\examples\hello-world\main.orc +cargo run -p orcx -- lex --file .\examples\hello-world\main.orc diff --git a/orchid-extension/src/entrypoint.rs b/orchid-extension/src/entrypoint.rs index 725e632..05eeef6 100644 --- a/orchid-extension/src/entrypoint.rs +++ b/orchid-extension/src/entrypoint.rs @@ -12,7 +12,6 @@ use async_std::channel::{Receiver, Sender}; use async_std::stream; use async_std::sync::Mutex; use futures::future::{LocalBoxFuture, join_all}; -use futures::task::LocalSpawn; use futures::{FutureExt, StreamExt}; use hashbrown::HashMap; use itertools::Itertools; diff --git a/orcx/Cargo.toml b/orcx/Cargo.toml index f1005b3..b441df4 100644 --- a/orcx/Cargo.toml +++ b/orcx/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] async-stream = "0.3.6" camino = "1.1.9" -clap = { version = "4.5.24", features = ["derive"] } +clap = { version = "4.5.24", features = ["derive", "env"] } futures = "0.3.31" itertools = "0.14.0" orchid-base = { version = "0.1.0", path = "../orchid-base" } diff --git a/orcx/src/main.rs b/orcx/src/main.rs index e85697a..89581de 100644 --- a/orcx/src/main.rs +++ b/orcx/src/main.rs @@ -1,7 +1,7 @@ use std::fs::File; use std::io::Read; use std::mem; -use std::process::Command; +use std::process::{Command, ExitCode}; use std::rc::Rc; use async_stream::try_stream; @@ -16,7 +16,7 @@ use orchid_base::tree::ttv_fmt; use orchid_host::ctx::Ctx; use orchid_host::extension::Extension; use orchid_host::lex::lex; -use orchid_host::parse::{self, ParseCtx, ParseCtxImpl, parse_items}; +use orchid_host::parse::{ParseCtxImpl, parse_items}; use orchid_host::subprocess::ext_command; use orchid_host::system::init_systems; use substack::Substack; @@ -25,9 +25,9 @@ use tokio::task::{LocalSet, spawn_local}; #[derive(Parser, Debug)] #[command(version, about, long_about)] pub struct Args { - #[arg(short, long)] + #[arg(short, long, env = "ORCHID_EXTENSIONS", value_delimiter = ';')] extension: Vec, - #[arg(short, long)] + #[arg(short, long, env = "ORCHID_DEFAULT_SYSTEMS", value_delimiter = ';')] system: Vec, #[command(subcommand)] command: Commands, @@ -51,7 +51,12 @@ fn get_all_extensions<'a>( ctx: &'a Ctx, ) -> impl Stream> + 'a { try_stream! { - for exe in args.extension.iter() { + for ext_path in args.extension.iter() { + let exe = if cfg!(windows) { + ext_path.with_extension("exe") + } else { + ext_path.clone() + }; let init = ext_command(Command::new(exe.as_os_str()), logger.clone(), ctx.clone()).await .unwrap(); let ext = Extension::new(init, logger.clone(), ctx.clone())?; @@ -62,7 +67,8 @@ fn get_all_extensions<'a>( } #[tokio::main(flavor = "current_thread")] -async fn main() { +async fn main() -> io::Result { + let mut code = ExitCode::SUCCESS; LocalSet::new() .run_until(async { let args = Args::parse(); @@ -93,11 +99,22 @@ async fn main() { let pctx = ParseCtxImpl { reporter: &reporter, systems: &systems }; let snip = Snippet::new(first, &lexemes, &ctx.i); let ptree = parse_items(&pctx, Substack::Bottom, snip).await.unwrap(); + if let Some(errv) = reporter.errv() { + eprintln!("{errv}"); + code = ExitCode::FAILURE; + return; + } + if ptree.is_empty() { + eprintln!("File empty only after parsing, but no errors were reported"); + code = ExitCode::FAILURE; + return; + } for item in ptree { println!("{item:?}") } }, } }) - .await + .await; + Ok(code) } diff --git a/xtask/src/check_api_refs.rs b/xtask/src/check_api_refs.rs new file mode 100644 index 0000000..66b77dc --- /dev/null +++ b/xtask/src/check_api_refs.rs @@ -0,0 +1,48 @@ +use std::env; +use std::ffi::OsStr; +use std::fs::{DirEntry, File}; +use std::io::{self, Read}; +use std::path::Path; + +use crate::Args; + +pub fn check_api_refs(_args: &Args) -> io::Result<()> { + walk_wsp(&mut |_| Ok(true), &mut |file| { + if file.path().extension() == Some(OsStr::new("rs")) && file.file_name() != "lib.rs" { + let mut contents = String::new(); + File::open(file.path())?.read_to_string(&mut contents)?; + for (l, line) in contents.lines().enumerate() { + if !line.trim().starts_with("use") { + continue; + } + let Some(c) = line.find("orchid_api") else { continue }; + if Some(c) == line.find("orchid_api_") { + continue; + } + let dname = file.path().to_string_lossy().to_string(); + eprintln!("orchid_api imported in {dname} at {};{}", l + 1, c + 1) + } + } + Ok(()) + }) +} + +fn walk_wsp( + dir_filter: &mut impl FnMut(&DirEntry) -> io::Result, + file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>, +) -> io::Result<()> { + return recurse(&env::current_dir()?, dir_filter, file_handler); + fn recurse( + dir: &Path, + dir_filter: &mut impl FnMut(&DirEntry) -> io::Result, + file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>, + ) -> io::Result<()> { + for file in dir.read_dir()?.collect::, _>>()? { + if file.metadata()?.is_dir() && dir_filter(&file)? { + recurse(&file.path(), dir_filter, file_handler)?; + } + file_handler(file)?; + } + Ok(()) + } +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index fb3a900..fb384f3 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,12 +1,13 @@ -use std::env; -use std::ffi::OsStr; -use std::fs::{DirEntry, File}; -use std::io::{self, Read}; -use std::path::Path; +mod check_api_refs; +mod orcx; + +use std::io; use std::process::ExitCode; use std::sync::atomic::{AtomicBool, Ordering}; +use check_api_refs::check_api_refs; use clap::{Parser, Subcommand}; +use orcx::orcx; #[derive(Parser)] pub struct Args { @@ -19,51 +20,19 @@ pub struct Args { #[derive(Subcommand)] pub enum Commands { CheckApiRefs, + Orcx { + #[arg(trailing_var_arg = true, num_args = 1..)] + subcommand: Vec, + }, } pub static EXIT_OK: AtomicBool = AtomicBool::new(true); fn main() -> io::Result { let args = Args::parse(); - match args.command { - Commands::CheckApiRefs => walk_wsp(&mut |_| Ok(true), &mut |file| { - if file.path().extension() == Some(OsStr::new("rs")) && file.file_name() != "lib.rs" { - let mut contents = String::new(); - File::open(file.path())?.read_to_string(&mut contents)?; - for (l, line) in contents.lines().enumerate() { - if !line.trim().starts_with("use") { - continue; - } - let Some(c) = line.find("orchid_api") else { continue }; - if Some(c) == line.find("orchid_api_") { - continue; - } - let dname = file.path().to_string_lossy().to_string(); - eprintln!("orchid_api imported in {dname} at {};{}", l + 1, c + 1) - } - } - Ok(()) - })?, + match &args.command { + Commands::CheckApiRefs => check_api_refs(&args)?, + Commands::Orcx { subcommand } => orcx(&args, subcommand)?, } Ok(if EXIT_OK.load(Ordering::Relaxed) { ExitCode::SUCCESS } else { ExitCode::FAILURE }) } - -fn walk_wsp( - dir_filter: &mut impl FnMut(&DirEntry) -> io::Result, - file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>, -) -> io::Result<()> { - return recurse(&env::current_dir()?, dir_filter, file_handler); - fn recurse( - dir: &Path, - dir_filter: &mut impl FnMut(&DirEntry) -> io::Result, - file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>, - ) -> io::Result<()> { - for file in dir.read_dir()?.collect::, _>>()? { - if file.metadata()?.is_dir() && dir_filter(&file)? { - recurse(&file.path(), dir_filter, file_handler)?; - } - file_handler(file)?; - } - Ok(()) - } -} diff --git a/xtask/src/orcx.rs b/xtask/src/orcx.rs new file mode 100644 index 0000000..774db6b --- /dev/null +++ b/xtask/src/orcx.rs @@ -0,0 +1,19 @@ +use std::io; +use std::process::Command; +use std::sync::atomic::Ordering; + +use crate::{Args, EXIT_OK}; + +pub fn orcx(_args: &Args, subcommand: &[String]) -> io::Result<()> { + eprintln!("running orcx {}", subcommand.join(" ")); + let status = Command::new("cargo").args(["build", "-p", "orchid-std"]).status()?; + if status.success() { + let status = Command::new("cargo") + .args(["run", "-p", "orcx", "--"].into_iter().chain(subcommand.iter().map(|s| s.as_str()))) + .status()?; + EXIT_OK.store(status.success(), Ordering::Relaxed); + } else { + EXIT_OK.store(false, Ordering::Relaxed); + } + Ok(()) +}