plugin: report inspection package metadata
This commit is contained in:
parent
b5f10ab7dc
commit
dfa966dbfc
|
|
@ -7,8 +7,8 @@ use std::path::{Path, PathBuf};
|
||||||
use manifest::plugin::{
|
use manifest::plugin::{
|
||||||
PluginConfig, PluginDiagnostic, PluginDiagnosticKind, PluginDiscoveryLimits,
|
PluginConfig, PluginDiagnostic, PluginDiagnosticKind, PluginDiscoveryLimits,
|
||||||
PluginDiscoveryOptions, PluginDiscoveryReport, PluginPackageManifest, PluginPermission,
|
PluginDiscoveryOptions, PluginDiscoveryReport, PluginPackageManifest, PluginPermission,
|
||||||
PluginResolution, PluginSurface, ResolvedPlugin, ResolvedPluginRecord, SourceQualifiedPluginId,
|
PluginResolution, PluginSourceKind, PluginSurface, ResolvedPlugin, ResolvedPluginRecord,
|
||||||
discover_plugins, resolve_enabled_plugins,
|
SourceQualifiedPluginId, discover_plugins, resolve_enabled_plugins,
|
||||||
};
|
};
|
||||||
use manifest::{ProfileResolveOptions, ProfileResolver, ProfileSelector, paths};
|
use manifest::{ProfileResolveOptions, ProfileResolver, ProfileSelector, paths};
|
||||||
use pod::feature::plugin::{PluginStaticInspection, inspect_resolved_plugin_static};
|
use pod::feature::plugin::{PluginStaticInspection, inspect_resolved_plugin_static};
|
||||||
|
|
@ -70,10 +70,20 @@ fn render_list_snapshot_human(snapshot: &PluginInspectionSnapshot) -> Result<Str
|
||||||
for item in snapshot.items.iter().take(MAX_LIST_ITEMS) {
|
for item in snapshot.items.iter().take(MAX_LIST_ITEMS) {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
"- {} [{}] version={} digest={} source={} enabled_surfaces={} tools={} diagnostics={}",
|
"- {} [{}] version={} schema_version={} api_version={} package_path={} digest={} source={} enabled_surfaces={} tools={} diagnostics={}",
|
||||||
item.reference,
|
item.reference,
|
||||||
item.status,
|
item.status,
|
||||||
item.version.as_deref().unwrap_or("<unknown>"),
|
item.version.as_deref().unwrap_or("<unknown>"),
|
||||||
|
item.schema_version
|
||||||
|
.map(|version| version.to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string()),
|
||||||
|
item.api_version
|
||||||
|
.map(|version| version.to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string()),
|
||||||
|
item.package_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|path| path.display().to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string()),
|
||||||
item.digest.as_deref().unwrap_or("<unknown>"),
|
item.digest.as_deref().unwrap_or("<unknown>"),
|
||||||
item.source.as_deref().unwrap_or("<unknown>"),
|
item.source.as_deref().unwrap_or("<unknown>"),
|
||||||
join_or_none(&item.enabled_surfaces),
|
join_or_none(&item.enabled_surfaces),
|
||||||
|
|
@ -118,6 +128,28 @@ fn render_item_human(item: &PluginInspectionItem) -> Result<String> {
|
||||||
" package: {}",
|
" package: {}",
|
||||||
item.package.as_deref().unwrap_or("<unknown>")
|
item.package.as_deref().unwrap_or("<unknown>")
|
||||||
)?;
|
)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
" package_path: {}",
|
||||||
|
item.package_path
|
||||||
|
.as_ref()
|
||||||
|
.map(|path| path.display().to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string())
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
" schema_version: {}",
|
||||||
|
item.schema_version
|
||||||
|
.map(|version| version.to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string())
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
out,
|
||||||
|
" api_version: {}",
|
||||||
|
item.api_version
|
||||||
|
.map(|version| version.to_string())
|
||||||
|
.unwrap_or_else(|| "<unknown>".to_string())
|
||||||
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" version: {}",
|
" version: {}",
|
||||||
|
|
@ -287,8 +319,11 @@ fn snapshot_from_resolution(
|
||||||
builder.discovered = true;
|
builder.discovered = true;
|
||||||
builder.source = Some(package.identity.source.to_string());
|
builder.source = Some(package.identity.source.to_string());
|
||||||
builder.package = Some(package.package_label.clone());
|
builder.package = Some(package.package_label.clone());
|
||||||
|
builder.package_path = Some(package.package_path.clone());
|
||||||
builder.digest = Some(package.digest.clone());
|
builder.digest = Some(package.digest.clone());
|
||||||
builder.version = Some(package.manifest.version.clone());
|
builder.version = Some(package.manifest.version.clone());
|
||||||
|
builder.schema_version = Some(package.manifest.schema_version);
|
||||||
|
builder.api_version = Some(package.manifest.schema_version);
|
||||||
builder.declared_surfaces = surface_strings(package.manifest.surfaces.iter().copied());
|
builder.declared_surfaces = surface_strings(package.manifest.surfaces.iter().copied());
|
||||||
builder.requested_permissions = permission_strings(&package.manifest.permissions);
|
builder.requested_permissions = permission_strings(&package.manifest.permissions);
|
||||||
builder.tools = package
|
builder.tools = package
|
||||||
|
|
@ -322,6 +357,13 @@ fn snapshot_from_resolution(
|
||||||
builder
|
builder
|
||||||
.source
|
.source
|
||||||
.get_or_insert_with(|| identity.source.to_string());
|
.get_or_insert_with(|| identity.source.to_string());
|
||||||
|
builder.package_path.get_or_insert_with(|| {
|
||||||
|
package_path_for_source(
|
||||||
|
&workspace,
|
||||||
|
identity.source,
|
||||||
|
&format!("{}.yoi-plugin", identity.local_id),
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,6 +387,20 @@ fn snapshot_from_resolution(
|
||||||
.or_insert_with(|| ItemBuilder::new(reference))
|
.or_insert_with(|| ItemBuilder::new(reference))
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(rendered);
|
.push(rendered);
|
||||||
|
} else if let (Some(source), Some(package)) =
|
||||||
|
(diagnostic.source, diagnostic.package.as_ref())
|
||||||
|
{
|
||||||
|
let local_id = package_local_id(package);
|
||||||
|
let key = format!("{source}:{local_id}");
|
||||||
|
let builder = builders
|
||||||
|
.entry(key.clone())
|
||||||
|
.or_insert_with(|| ItemBuilder::new(key));
|
||||||
|
builder.source.get_or_insert_with(|| source.to_string());
|
||||||
|
builder.package.get_or_insert_with(|| package.clone());
|
||||||
|
builder
|
||||||
|
.package_path
|
||||||
|
.get_or_insert_with(|| package_path_for_source(&workspace, source, package));
|
||||||
|
builder.diagnostics.push(rendered);
|
||||||
} else {
|
} else {
|
||||||
let key = "<global>".to_string();
|
let key = "<global>".to_string();
|
||||||
builders
|
builders
|
||||||
|
|
@ -370,8 +426,11 @@ fn fill_resolved(builder: &mut ItemBuilder, resolved: &ResolvedPlugin) {
|
||||||
builder.resolved = true;
|
builder.resolved = true;
|
||||||
builder.source = Some(resolved.identity.source.to_string());
|
builder.source = Some(resolved.identity.source.to_string());
|
||||||
builder.package = Some(resolved.package_label.clone());
|
builder.package = Some(resolved.package_label.clone());
|
||||||
|
builder.package_path = Some(resolved.package_path.clone());
|
||||||
builder.digest = Some(resolved.digest.clone());
|
builder.digest = Some(resolved.digest.clone());
|
||||||
builder.version = Some(resolved.manifest.version.clone());
|
builder.version = Some(resolved.manifest.version.clone());
|
||||||
|
builder.schema_version = Some(resolved.manifest.schema_version);
|
||||||
|
builder.api_version = Some(resolved.manifest.schema_version);
|
||||||
builder.declared_surfaces = surface_strings(resolved.manifest.surfaces.iter().copied());
|
builder.declared_surfaces = surface_strings(resolved.manifest.surfaces.iter().copied());
|
||||||
builder.enabled_surfaces = surface_strings(resolved.enabled_surfaces.iter().copied());
|
builder.enabled_surfaces = surface_strings(resolved.enabled_surfaces.iter().copied());
|
||||||
builder.requested_permissions = permission_strings(&resolved.manifest.permissions);
|
builder.requested_permissions = permission_strings(&resolved.manifest.permissions);
|
||||||
|
|
@ -478,6 +537,28 @@ fn permission_requested(manifest: &PluginPackageManifest, permission: &PluginPer
|
||||||
.any(|requested| requested == permission)
|
.any(|requested| requested == permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn package_local_id(package_label: &str) -> String {
|
||||||
|
package_label
|
||||||
|
.strip_suffix(".yoi-plugin")
|
||||||
|
.unwrap_or(package_label)
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn package_path_for_source(
|
||||||
|
workspace: &Path,
|
||||||
|
source: PluginSourceKind,
|
||||||
|
package_label: &str,
|
||||||
|
) -> PathBuf {
|
||||||
|
match source {
|
||||||
|
PluginSourceKind::Project => workspace.join(".yoi/plugins").join(package_label),
|
||||||
|
PluginSourceKind::User => paths::data_dir()
|
||||||
|
.unwrap_or_else(|| PathBuf::from("<unavailable-user-data-dir>"))
|
||||||
|
.join("yoi/plugins")
|
||||||
|
.join(package_label),
|
||||||
|
PluginSourceKind::Builtin => PathBuf::from("<builtin>").join(package_label),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn local_ref(reference: &str) -> Option<String> {
|
fn local_ref(reference: &str) -> Option<String> {
|
||||||
SourceQualifiedPluginId::parse(reference)
|
SourceQualifiedPluginId::parse(reference)
|
||||||
.ok()
|
.ok()
|
||||||
|
|
@ -506,7 +587,10 @@ struct PluginInspectionItem {
|
||||||
status: String,
|
status: String,
|
||||||
source: Option<String>,
|
source: Option<String>,
|
||||||
package: Option<String>,
|
package: Option<String>,
|
||||||
|
package_path: Option<PathBuf>,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
|
schema_version: Option<u32>,
|
||||||
|
api_version: Option<u32>,
|
||||||
digest: Option<String>,
|
digest: Option<String>,
|
||||||
configured: bool,
|
configured: bool,
|
||||||
discovered: bool,
|
discovered: bool,
|
||||||
|
|
@ -572,7 +656,10 @@ struct ItemBuilder {
|
||||||
resolved: bool,
|
resolved: bool,
|
||||||
source: Option<String>,
|
source: Option<String>,
|
||||||
package: Option<String>,
|
package: Option<String>,
|
||||||
|
package_path: Option<PathBuf>,
|
||||||
version: Option<String>,
|
version: Option<String>,
|
||||||
|
schema_version: Option<u32>,
|
||||||
|
api_version: Option<u32>,
|
||||||
digest: Option<String>,
|
digest: Option<String>,
|
||||||
static_eligible: bool,
|
static_eligible: bool,
|
||||||
declared_surfaces: Vec<String>,
|
declared_surfaces: Vec<String>,
|
||||||
|
|
@ -593,7 +680,10 @@ impl ItemBuilder {
|
||||||
resolved: false,
|
resolved: false,
|
||||||
source: None,
|
source: None,
|
||||||
package: None,
|
package: None,
|
||||||
|
package_path: None,
|
||||||
version: None,
|
version: None,
|
||||||
|
schema_version: None,
|
||||||
|
api_version: None,
|
||||||
digest: None,
|
digest: None,
|
||||||
static_eligible: false,
|
static_eligible: false,
|
||||||
declared_surfaces: Vec::new(),
|
declared_surfaces: Vec::new(),
|
||||||
|
|
@ -649,7 +739,10 @@ impl ItemBuilder {
|
||||||
status,
|
status,
|
||||||
source: self.source,
|
source: self.source,
|
||||||
package: self.package,
|
package: self.package,
|
||||||
|
package_path: self.package_path,
|
||||||
version: self.version,
|
version: self.version,
|
||||||
|
schema_version: self.schema_version,
|
||||||
|
api_version: self.api_version,
|
||||||
digest: self.digest,
|
digest: self.digest,
|
||||||
configured: self.configured,
|
configured: self.configured,
|
||||||
discovered: self.discovered,
|
discovered: self.discovered,
|
||||||
|
|
@ -686,19 +779,47 @@ mod tests {
|
||||||
assert_eq!(item.tools[0].name, "Echo");
|
assert_eq!(item.tools[0].name, "Echo");
|
||||||
assert!(item.static_eligible);
|
assert!(item.static_eligible);
|
||||||
assert_eq!(item.package.as_deref(), Some("echo.yoi-plugin"));
|
assert_eq!(item.package.as_deref(), Some("echo.yoi-plugin"));
|
||||||
|
assert_eq!(item.schema_version, Some(1));
|
||||||
|
assert_eq!(item.api_version, Some(1));
|
||||||
|
assert_eq!(
|
||||||
|
item.package_path.as_deref(),
|
||||||
|
Some(workspace.join(".yoi/plugins/echo.yoi-plugin").as_path())
|
||||||
|
);
|
||||||
|
|
||||||
let list_json = serde_json::to_value(&snapshot).unwrap();
|
let list_json = serde_json::to_value(&snapshot).unwrap();
|
||||||
assert_eq!(list_json["items"][0]["status"], "active");
|
assert_eq!(list_json["items"][0]["status"], "active");
|
||||||
|
assert_eq!(list_json["items"][0]["schema_version"], 1);
|
||||||
|
assert_eq!(list_json["items"][0]["api_version"], 1);
|
||||||
|
assert_eq!(
|
||||||
|
list_json["items"][0]["package_path"],
|
||||||
|
workspace
|
||||||
|
.join(".yoi/plugins/echo.yoi-plugin")
|
||||||
|
.display()
|
||||||
|
.to_string()
|
||||||
|
);
|
||||||
assert_eq!(list_json["items"][0]["enabled_surfaces"][0], "tool");
|
assert_eq!(list_json["items"][0]["enabled_surfaces"][0], "tool");
|
||||||
assert_eq!(list_json["items"][0]["tools"][0]["granted"], true);
|
assert_eq!(list_json["items"][0]["tools"][0]["granted"], true);
|
||||||
|
|
||||||
let show_json = serde_json::to_value(item).unwrap();
|
let show_json = serde_json::to_value(item).unwrap();
|
||||||
assert_eq!(show_json["status"], "active");
|
assert_eq!(show_json["status"], "active");
|
||||||
|
assert_eq!(show_json["schema_version"], 1);
|
||||||
|
assert_eq!(show_json["api_version"], 1);
|
||||||
|
assert_eq!(
|
||||||
|
show_json["package_path"],
|
||||||
|
workspace
|
||||||
|
.join(".yoi/plugins/echo.yoi-plugin")
|
||||||
|
.display()
|
||||||
|
.to_string()
|
||||||
|
);
|
||||||
assert_eq!(show_json["configured_grants"][0], "surfaces.tool");
|
assert_eq!(show_json["configured_grants"][0], "surfaces.tool");
|
||||||
assert_eq!(show_json["tools"][0]["permission"], "tool.Echo");
|
assert_eq!(show_json["tools"][0]["permission"], "tool.Echo");
|
||||||
|
|
||||||
let show = render_item_human(item).unwrap();
|
let show = render_item_human(item).unwrap();
|
||||||
assert!(show.contains("status: active"));
|
assert!(show.contains("status: active"));
|
||||||
|
assert!(show.contains("schema_version: 1"));
|
||||||
|
assert!(show.contains("api_version: 1"));
|
||||||
|
assert!(show.contains("package_path:"));
|
||||||
|
assert!(show.contains("echo.yoi-plugin"));
|
||||||
assert!(show.contains("configured_grants: surfaces.tool, tool.Echo"));
|
assert!(show.contains("configured_grants: surfaces.tool, tool.Echo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -759,6 +880,11 @@ mod tests {
|
||||||
assert!(output.contains("project:spare [disabled]"));
|
assert!(output.contains("project:spare [disabled]"));
|
||||||
assert!(output.contains("project:bad [rejected]"));
|
assert!(output.contains("project:bad [rejected]"));
|
||||||
assert!(output.contains("project:missing [missing]"));
|
assert!(output.contains("project:missing [missing]"));
|
||||||
|
assert!(output.contains("schema_version=1"));
|
||||||
|
assert!(output.contains("api_version=1"));
|
||||||
|
assert!(output.contains("package_path="));
|
||||||
|
assert!(output.contains("echo.yoi-plugin"));
|
||||||
|
assert!(output.contains("missing.yoi-plugin"));
|
||||||
assert!(output.contains("enabled_surfaces=tool"));
|
assert!(output.contains("enabled_surfaces=tool"));
|
||||||
assert!(!output.contains("enabled-with-diagnostics"));
|
assert!(!output.contains("enabled-with-diagnostics"));
|
||||||
assert!(!output.contains("configured-"));
|
assert!(!output.contains("configured-"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user