refactor: rename manifest metadata fields and improve error display

Rename wrapperRepo→packageRepo, marketingSite→marketingUrl,
docsUrl→docsUrls (array), remove supportSite. Add display_src/display_dbg
helpers to Error. Fix DepInfo description type to LocaleString. Update
web UI, SDK bindings, tests, and fixtures to match. Clean up cli_attach
error handling and remove dead commented code.
This commit is contained in:
Aiden McClelland
2026-02-17 18:40:50 -07:00
parent 313b2df540
commit 4cae00cb33
16 changed files with 142 additions and 173 deletions

View File

@@ -45,7 +45,7 @@ impl TS for DepInfo {
"DepInfo".into()
}
fn inline() -> String {
"{ description: string | null, optional: boolean } & MetadataSrc".into()
"{ description: LocaleString | null, optional: boolean } & MetadataSrc".into()
}
fn inline_flattened() -> String {
Self::inline()
@@ -54,7 +54,8 @@ impl TS for DepInfo {
where
Self: 'static,
{
v.visit::<MetadataSrc>()
v.visit::<MetadataSrc>();
v.visit::<LocaleString>();
}
fn output_path() -> Option<&'static std::path::Path> {
Some(Path::new("DepInfo.ts"))

View File

@@ -3,6 +3,7 @@ use std::fmt::{Debug, Display};
use axum::http::StatusCode;
use axum::http::uri::InvalidUri;
use color_eyre::eyre::eyre;
use imbl_value::InternedString;
use num_enum::TryFromPrimitive;
use patch_db::Value;
use rpc_toolkit::reqwest;
@@ -204,17 +205,12 @@ pub struct Error {
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {:#}", &self.kind.as_str(), self.source)
write!(f, "{}: {}", &self.kind.as_str(), self.display_src())
}
}
impl Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}: {:?}",
&self.kind.as_str(),
self.debug.as_ref().unwrap_or(&self.source)
)
write!(f, "{}: {}", &self.kind.as_str(), self.display_dbg())
}
}
impl Error {
@@ -235,8 +231,13 @@ impl Error {
}
pub fn clone_output(&self) -> Self {
Error {
source: eyre!("{}", self.source),
debug: self.debug.as_ref().map(|e| eyre!("{e}")),
source: eyre!("{:#}", self.source),
debug: Some(
self.debug
.as_ref()
.map(|e| eyre!("{e}"))
.unwrap_or_else(|| eyre!("{:?}", self.source)),
),
kind: self.kind,
info: self.info.clone(),
task: None,
@@ -257,6 +258,30 @@ impl Error {
self.task.take();
self
}
pub fn display_src(&self) -> impl Display {
struct D<'a>(&'a Error);
impl<'a> Display for D<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:#}", self.0.source)
}
}
D(self)
}
pub fn display_dbg(&self) -> impl Display {
struct D<'a>(&'a Error);
impl<'a> Display for D<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(debug) = &self.0.debug {
write!(f, "{}", debug)
} else {
write!(f, "{:?}", self.0.source)
}
}
}
D(self)
}
}
impl axum::response::IntoResponse for Error {
fn into_response(self) -> axum::response::Response {
@@ -433,9 +458,11 @@ impl Debug for ErrorData {
impl std::error::Error for ErrorData {}
impl From<Error> for ErrorData {
fn from(value: Error) -> Self {
let details = value.display_src().to_string();
let debug = value.display_dbg().to_string();
Self {
details: value.to_string(),
debug: format!("{:?}", value),
details,
debug,
info: value.info,
}
}
@@ -623,13 +650,10 @@ impl<T> ResultExt<T, Error> for Result<T, Error> {
fn with_ctx<F: FnOnce(&Error) -> (ErrorKind, D), D: Display>(self, f: F) -> Result<T, Error> {
self.map_err(|e| {
let (kind, ctx) = f(&e);
let ctx = InternedString::from_display(&ctx);
let source = e.source;
let with_ctx = format!("{ctx}: {source}");
let source = source.wrap_err(with_ctx);
let debug = e.debug.map(|e| {
let with_ctx = format!("{ctx}: {e}");
e.wrap_err(with_ctx)
});
let source = source.wrap_err(ctx.clone());
let debug = e.debug.map(|e| e.wrap_err(ctx));
Error {
kind,
source,

View File

@@ -206,9 +206,7 @@ impl TryFrom<ManifestV1> for Manifest {
license: value.license.into(),
package_repo: value.wrapper_repo,
upstream_repo: value.upstream_repo,
marketing_url: Some(
value.marketing_site.unwrap_or_else(|| default_url.clone()),
),
marketing_url: Some(value.marketing_site.unwrap_or_else(|| default_url.clone())),
donation_url: value.donation_url,
docs_urls: Vec::new(),
description: value.description,

View File

@@ -16,7 +16,7 @@ use futures::{FutureExt, SinkExt, StreamExt, TryStreamExt};
use imbl_value::{InternedString, json};
use itertools::Itertools;
use nix::sys::signal::Signal;
use persistent_container::{PersistentContainer, Subcontainer};
use persistent_container::PersistentContainer;
use rpc_toolkit::HandlerArgs;
use rpc_toolkit::yajrc::RpcError;
use serde::{Deserialize, Serialize};
@@ -1195,10 +1195,12 @@ pub async fn cli_attach(
{
Ok(a) => a,
Err(e) => {
if e.kind != ErrorKind::InvalidRequest {
return Err(e);
}
let prompt = e.to_string();
let options: Vec<SubcontainerInfo> = from_value(e.info)?;
let choice = choose(&prompt, &options).await?;
println!();
params["subcontainer"] = to_value(&choice.id)?;
context
.call_remote::<RpcContext>(&method, params.clone())
@@ -1208,6 +1210,7 @@ pub async fn cli_attach(
)?;
let mut ws = context.ws_continuation(guid).await?;
print!("\r");
let (kill, thread_kill) = tokio::sync::oneshot::channel();
let (thread_send, recv) = tokio::sync::mpsc::channel(4 * CAP_1_KiB);
let stdin_thread: NonDetachingJoinHandle<()> = tokio::task::spawn_blocking(move || {
@@ -1236,18 +1239,6 @@ pub async fn cli_attach(
let mut stderr = Some(stderr);
loop {
futures::select_biased! {
// signal = tokio:: => {
// let exit = exit?;
// if current_out != "exit" {
// ws.send(Message::Text("exit".into()))
// .await
// .with_kind(ErrorKind::Network)?;
// current_out = "exit";
// }
// ws.send(Message::Binary(
// i32::to_be_bytes(exit.into_raw()).to_vec()
// )).await.with_kind(ErrorKind::Network)?;
// }
input = stdin.as_mut().map_or(
futures::future::Either::Left(futures::future::pending()),
|s| futures::future::Either::Right(s.recv())