Skip to content

Commit

Permalink
Hook up starbase.
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Dec 1, 2023
1 parent 3ba6211 commit e8adefa
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/cli-shim/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ path = "src/main.rs"
ctrlc = "3.4.1"
shared_child = "1.0.0"
sigpipe = "0.1.3"
starbase = { workspace = true }
69 changes: 51 additions & 18 deletions crates/cli-shim/src/main.rs
Original file line number Diff line number Diff line change
@@ -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::<VecDeque<_>>();
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 = {
Expand All @@ -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);
}

0 comments on commit e8adefa

Please sign in to comment.