From e8adefa2f39530e3b74a37b5270242373aa367ce Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Fri, 1 Dec 2023 12:22:46 -0800 Subject: [PATCH] Hook up starbase. --- Cargo.lock | 1 + crates/cli-shim/Cargo.toml | 1 + crates/cli-shim/src/main.rs | 69 +++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66200e3ce..f632529f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2496,6 +2496,7 @@ dependencies = [ "ctrlc", "shared_child", "sigpipe", + "starbase", ] [[package]] diff --git a/crates/cli-shim/Cargo.toml b/crates/cli-shim/Cargo.toml index c291e7f33..51b65795a 100644 --- a/crates/cli-shim/Cargo.toml +++ b/crates/cli-shim/Cargo.toml @@ -12,3 +12,4 @@ path = "src/main.rs" ctrlc = "3.4.1" shared_child = "1.0.0" sigpipe = "0.1.3" +starbase = { workspace = true } diff --git a/crates/cli-shim/src/main.rs b/crates/cli-shim/src/main.rs index 9bb136a72..ddecca518 100644 --- a/crates/cli-shim/src/main.rs +++ b/crates/cli-shim/src/main.rs @@ -1,20 +1,44 @@ use shared_child::SharedChild; +use starbase::diagnostics::{self, miette, IntoDiagnostic, Result}; +use starbase::tracing::{self, trace, TracingOptions}; use std::collections::VecDeque; use std::io::{IsTerminal, Read, Write}; +use std::path::PathBuf; use std::process::{Command, Stdio}; use std::sync::Arc; use std::{env, io, process}; -pub fn main() { +pub fn main() -> Result<()> { sigpipe::reset(); + diagnostics::setup_miette(); + + // Setup tracing and pass log level down + let log_level = env::var("PROTO_LOG").unwrap_or_else(|_| "info".into()); + + tracing::setup_tracing(TracingOptions { + filter_modules: vec!["proto".into()], + intercept_log: env::var("PROTO_WASM_LOG").is_err(), + log_env: "PROTO_LOG".into(), + ..TracingOptions::default() + }); // Extract arguments to pass-through let mut args = env::args().collect::>(); - let shim_name = args.pop_front().unwrap(); + let exe_path = env::current_exe().unwrap_or_else(|_| PathBuf::from(&args[0])); + + let shim_name = exe_path + .file_name() + .map(|file| String::from_utf8_lossy(file.as_encoded_bytes())) + .unwrap_or_default(); - dbg!("Args", &args); - dbg!("Shim name", shim_name); - dbg!("Exec with", env::current_exe().unwrap()); + trace!(args = ?args, shim = ?exe_path, "Running {} shim", shim_name); + + if shim_name.is_empty() || shim_name.contains("proto-shim") { + return Err(miette!( + code = "proto::invalid_shim", + "Invalid shim name detected. Unable to execute the appropriate proto tool.\nPlease refer to the documentation or ask for support on Discord." + )); + } // Capture any piped input let input = { @@ -24,48 +48,57 @@ pub fn main() { // Only read piped data when stdin is not a TTY, // otherwise the process will hang indefinitely waiting for EOF if !stdin.is_terminal() { - stdin.read_to_string(&mut buffer).unwrap(); + stdin.read_to_string(&mut buffer).into_diagnostic()?; } buffer }; let has_piped_stdin = !input.is_empty(); - dbg!("Input", &input); + // Create the actual command to execute + let mut command = Command::new(if cfg!(windows) { "proto.exe" } else { "proto" }); + command.args(["run", &shim_name]); - // The actual command to execute - let mut command = Command::new("node"); - command.arg("./docs/shim-test.mjs"); - command.args(args); + if args.len() > 1 { + args.pop_front(); + command.arg("--"); + command.args(args); + } + + command.env("PROTO_LOG", log_level); if has_piped_stdin { command.stdin(Stdio::piped()); } // Spawn a shareable child process - let shared_child = SharedChild::spawn(&mut command).unwrap(); + trace!("Spawning proto child process"); + + let shared_child = SharedChild::spawn(&mut command).into_diagnostic()?; let child = Arc::new(shared_child); let child_clone = Arc::clone(&child); // Handle CTRL+C and kill the child ctrlc::set_handler(move || { - child_clone.kill().unwrap(); + trace!("Received CTRL+C, killing child process"); + let _ = child_clone.kill(); }) - .unwrap(); + .into_diagnostic()?; // If we have piped data, pass it through if has_piped_stdin { if let Some(mut stdin) = child.take_stdin() { - stdin.write_all(input.as_bytes()).unwrap(); - drop(stdin); + trace!(input, "Received piped input, passing through"); + + stdin.write_all(input.as_bytes()).into_diagnostic()?; } } // Wait for the process to finish or be killed - let status = child.wait().unwrap(); + let status = child.wait().into_diagnostic()?; let code = status.code().unwrap_or(0); - println!("status code = {}", code); + trace!(code, "Received exit code"); process::exit(code); }