Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 2 additions & 120 deletions cli/golem-cli/src/app/build/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,14 @@ use crate::model::app_raw::{
InjectToPrebuiltQuickJs,
};
use crate::model::text::fmt::log_error;
use crate::process::{with_hidden_output_unless_error, CommandExt};
use crate::wasm_rpc_stubgen::commands;
use crate::wasm_rpc_stubgen::commands::composition::Plug;
use anyhow::{anyhow, bail, Context as AnyhowContext};
use camino::Utf8Path;
use colored::Colorize;
use gag::BufferRedirect;
use golem_common::model::component::ComponentName;
use std::io::{Read, Write};
use std::path::Path;
use std::process::{ExitStatus, Stdio};
use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::process::{Child, Command};
use tracing::{enabled, Level};
use tokio::process::Command;
use wasm_rquickjs::{EmbeddingMode, JsModuleSpec};

pub async fn execute_build_command(
Expand Down Expand Up @@ -563,116 +558,3 @@ pub async fn ensure_common_deps_for_tool(
_ => Ok(()),
}
}

trait ExitStatusExt {
fn check_exit_status(&self) -> anyhow::Result<()>;
}

impl ExitStatusExt for ExitStatus {
fn check_exit_status(&self) -> anyhow::Result<()> {
if self.success() {
Ok(())
} else {
Err(anyhow!(format!(
"Command failed with exit code: {}",
self.code()
.map(|code| code.to_string().log_color_error_highlight().to_string())
.unwrap_or_else(|| "?".to_string())
)))
}
}
}

trait CommandExt {
async fn stream_and_wait_for_status(
&mut self,
command_name: &str,
) -> anyhow::Result<ExitStatus>;

async fn stream_and_run(&mut self, command_name: &str) -> anyhow::Result<()> {
self.stream_and_wait_for_status(command_name)
.await?
.check_exit_status()
}

fn stream_output(command_name: &str, child: &mut Child) -> anyhow::Result<()> {
let stdout = child
.stdout
.take()
.ok_or_else(|| anyhow!("Failed to capture stdout for {command_name}"))?;

let stderr = child
.stderr
.take()
.ok_or_else(|| anyhow!("Failed to capture stderr for {command_name}"))?;

tokio::spawn({
let prefix = format!("{} | ", command_name).green().bold();
async move {
let mut lines = BufReader::new(stdout).lines();
while let Ok(Some(line)) = lines.next_line().await {
logln(format!("{prefix} {line}"));
}
}
});

tokio::spawn({
let prefix = format!("{} | ", command_name).yellow().bold();
async move {
let mut lines = BufReader::new(stderr).lines();
while let Ok(Some(line)) = lines.next_line().await {
logln(format!("{prefix} {line}"));
}
}
});

Ok(())
}
}

impl CommandExt for Command {
async fn stream_and_wait_for_status(
&mut self,
command_name: &str,
) -> anyhow::Result<ExitStatus> {
let _indent = LogIndent::stash();

let mut child = self
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.with_context(|| format!("Failed to spawn {command_name}"))?;

Self::stream_output(command_name, &mut child)?;

child
.wait()
.await
.with_context(|| format!("Failed to execute {command_name}"))
}
}

fn with_hidden_output_unless_error<F, R>(f: F) -> anyhow::Result<R>
where
F: FnOnce() -> anyhow::Result<R>,
{
let redirect = (!enabled!(Level::WARN))
.then(|| BufferRedirect::stderr().ok())
.flatten();

let result = f();

if result.is_err() {
if let Some(mut redirect) = redirect {
let mut output = Vec::new();
let read_result = redirect.read_to_end(&mut output);
drop(redirect);
read_result.expect("Failed to read stderr from moonbit redirect");
std::io::stderr()
.write_all(output.as_slice())
.expect("Failed to write captured moonbit stderr");
}
}

result
}
13 changes: 8 additions & 5 deletions cli/golem-cli/src/app/build/extract_agent_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub async fn extract_and_store_agent_types(

let agent_types = ctx
.wit
.get_extracted_agent_types(component_name, &wasm)
.get_or_extract_component_agent_types(component_name, &wasm)
.await?;

fs::write_str(
Expand All @@ -68,9 +68,12 @@ pub async fn extract_and_store_agent_types(

match agent_types {
Some(agent_types) => Ok(agent_types),
None => Ok(
serde_json::from_str(&fs::read_to_string(&extracted_agent_types)?)
.context("Failed to deserialize agent types")?,
),
None => {
let agent_types = serde_json::from_str(&fs::read_to_string(&extracted_agent_types)?)
.context("Failed to deserialize agent types")?;
ctx.wit
.add_cached_component_agent_types(component_name, agent_types)
.await
}
}
}
Loading
Loading