fix(plugins): list command and menu contributions in manifest schema

This commit is contained in:
Jinpy
2026-09-26 13:49:16 +08:00
committed by GitHub
parent 2851da891e
commit d1d02547fd
2 changed files with 103 additions and 1 deletions
@@ -2392,6 +2392,52 @@ mod tests {
Ok(())
}
/// The runtime `PluginContribution` enum is the source of truth for
/// contribution `type` tags; the published schema's `contributions.oneOf`
/// must accept every one of them, or schema-validating tooling (CI,
/// editors) rejects manifests the host itself accepts. Adding a runtime
/// variant without extending the schema fails here.
#[test]
fn manifest_schema_lists_every_runtime_contribution_kind() {
let schema_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
.join("plugins")
.join("manifest.schema.json");
let schema: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(&schema_path).unwrap()).unwrap();
let referenced: Vec<String> = schema["properties"]["contributions"]["items"]["oneOf"]
.as_array()
.expect("contributions.items.oneOf must be an array")
.iter()
.map(|entry| {
entry["$ref"]
.as_str()
.expect("every oneOf entry must be a $ref")
.trim_start_matches("#/$defs/")
.to_string()
})
.collect();
// Mirrors the PluginContribution variants and their kebab-case serde
// tags; the schema def names append "Contribution".
let kinds = [
("connection-provider", "connectionProviderContribution"),
("workbench", "workbenchContribution"),
("filesystem-provider", "filesystemProviderContribution"),
("context-menu", "contextMenuContribution"),
("result-view", "resultViewContribution"),
("command", "commandContribution"),
("menus", "menusContribution"),
];
assert_eq!(referenced, kinds.iter().map(|(_, def)| def.to_string()).collect::<Vec<_>>());
for (tag, def) in kinds {
assert_eq!(
schema["$defs"][def]["properties"]["type"]["const"], tag,
"schema def {def} must pin the {tag:?} contribution type tag"
);
}
}
#[test]
fn manifest_schema_context_menu_enum_matches_runtime_targets() {
let schema_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
+57 -1
View File
@@ -46,7 +46,7 @@
"contributions": {
"type": "array",
"items": {
"oneOf": [{ "$ref": "#/$defs/connectionProviderContribution" }, { "$ref": "#/$defs/workbenchContribution" }, { "$ref": "#/$defs/filesystemProviderContribution" }, { "$ref": "#/$defs/contextMenuContribution" }, { "$ref": "#/$defs/resultViewContribution" }]
"oneOf": [{ "$ref": "#/$defs/connectionProviderContribution" }, { "$ref": "#/$defs/workbenchContribution" }, { "$ref": "#/$defs/filesystemProviderContribution" }, { "$ref": "#/$defs/contextMenuContribution" }, { "$ref": "#/$defs/resultViewContribution" }, { "$ref": "#/$defs/commandContribution" }, { "$ref": "#/$defs/menusContribution" }]
}
},
"localizations": {
@@ -368,6 +368,62 @@
"items": { "enum": ["read", "write", "delete", "rename", "mkdir"] }
}
}
},
"commandContribution": {
"type": "object",
"additionalProperties": false,
"required": ["type", "id", "label", "action"],
"properties": {
"type": { "const": "command" },
"id": { "$ref": "#/$defs/identifier" },
"label": { "type": "string", "minLength": 1 },
"description": { "type": "string" },
"icon": { "$ref": "#/$defs/assetPath" },
"action": { "$ref": "#/$defs/commandAction" },
"enablement": { "$ref": "#/$defs/commandEnablement" }
}
},
"commandAction": {
"oneOf": [{ "$ref": "#/$defs/openWorkbenchAction" }]
},
"openWorkbenchAction": {
"type": "object",
"required": ["type", "workbench"],
"properties": {
"type": { "const": "open-workbench" },
"workbench": { "$ref": "#/$defs/identifier" },
"presentation": { "enum": ["tab", "panel"] },
"context": { "type": "object" }
}
},
"menusContribution": {
"type": "object",
"additionalProperties": false,
"required": ["type", "id"],
"properties": {
"type": { "const": "menus" },
"id": { "$ref": "#/$defs/identifier" },
"items": { "type": "array", "items": { "$ref": "#/$defs/menuItem" } }
}
},
"menuItem": {
"type": "object",
"additionalProperties": false,
"required": ["location", "command", "group", "order"],
"properties": {
"location": { "enum": ["commandPalette", "appToolbar", "appSidebar"] },
"command": { "type": "string", "minLength": 1 },
"group": { "type": "string" },
"order": { "type": "integer" },
"default_visible": { "type": "boolean" },
"when": { "$ref": "#/$defs/commandEnablement" }
}
},
"commandEnablement": {
"type": "object",
"properties": {
"all": { "type": "array", "items": { "type": "object" } }
}
}
}
}