From 8ec36f1e2bdea337236048170a356ec034eaa046 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 27 Aug 2024 11:10:58 -0400 Subject: [PATCH] extension: Define capabilities in the extension manifest (#16953) This PR adds an initial notion of extension capabilities. Capabilities are used to express the operations an extension is capable of doing. This will provide further insights into what an extension can do, as well as provide the ability to grant or deny the set of capabilities. Capabilities are defined in the `capabilities` field in the extension manifest. This field contains an array of capabilities. Each capability has a `kind` to denote the known capability it corresponds to. Individual capabilities may have additional fields, based on the `kind`. Here's an example of some capabilities: ```toml capabilities = [ { kind = "download-file", host = "github.com", path_prefix = "owner/repo" }, { kind = "npm:install", package = "@vue/language-server" }, ] ``` In order to avoid a breaking change, the `capabilities` field is currently optional and defaults to an empty array. This will allow us to add support for extensions to define capabilities before we start enforcing them. Release Notes: - N/A --- crates/extension/src/extension_manifest.rs | 25 ++++++++++++++++++++ crates/extension/src/extension_store_test.rs | 3 +++ extensions/gleam/extension.toml | 4 ++++ 3 files changed, 32 insertions(+) diff --git a/crates/extension/src/extension_manifest.rs b/crates/extension/src/extension_manifest.rs index 9d8a841686feb5c760d5fb0a01b97380d732bf41..b4416db57454b4b591c1c1c348abeac7a1306d45 100644 --- a/crates/extension/src/extension_manifest.rs +++ b/crates/extension/src/extension_manifest.rs @@ -64,6 +64,8 @@ pub struct ExtensionManifest { #[serde(default)] pub authors: Vec, #[serde(default)] + pub capabilities: Vec, + #[serde(default)] pub lib: LibManifestEntry, #[serde(default)] @@ -82,6 +84,28 @@ pub struct ExtensionManifest { pub snippets: Option, } +/// A capability for an extension. +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[serde(tag = "kind")] +pub enum ExtensionCapability { + /// The capability to download a file from a server. + #[serde(rename = "download-file")] + DownloadFile { + /// The host name of the server from which the file will be downloaded (e.g., `github.com`). + host: String, + /// The path prefix to the file that will be downloaded. + /// + /// Any path that starts with this prefix will be allowed. + path_prefix: String, + }, + /// The capability to install a package from npm. + #[serde(rename = "npm:install")] + NpmInstall { + /// The name of the package. + package: String, + }, +} + #[derive(Clone, Default, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct LibManifestEntry { pub kind: Option, @@ -186,6 +210,7 @@ fn manifest_from_old_manifest( repository: manifest_json.repository, authors: manifest_json.authors, schema_version: SchemaVersion::ZERO, + capabilities: Vec::new(), lib: Default::default(), themes: { let mut themes = manifest_json.themes.into_values().collect::>(); diff --git a/crates/extension/src/extension_store_test.rs b/crates/extension/src/extension_store_test.rs index d4227c05f9b44019335a39a225ecef54ae482b57..1a6fb253f068f5d2952732fba2761473ed124896 100644 --- a/crates/extension/src/extension_store_test.rs +++ b/crates/extension/src/extension_store_test.rs @@ -150,6 +150,7 @@ async fn test_extension_store(cx: &mut TestAppContext) { authors: Vec::new(), repository: None, themes: Default::default(), + capabilities: Vec::new(), lib: Default::default(), languages: vec!["languages/erb".into(), "languages/ruby".into()], grammars: [ @@ -181,6 +182,7 @@ async fn test_extension_store(cx: &mut TestAppContext) { "themes/monokai-pro.json".into(), "themes/monokai.json".into(), ], + capabilities: Vec::new(), lib: Default::default(), languages: Default::default(), grammars: BTreeMap::default(), @@ -344,6 +346,7 @@ async fn test_extension_store(cx: &mut TestAppContext) { authors: vec![], repository: None, themes: vec!["themes/gruvbox.json".into()], + capabilities: Vec::new(), lib: Default::default(), languages: Default::default(), grammars: BTreeMap::default(), diff --git a/extensions/gleam/extension.toml b/extensions/gleam/extension.toml index 7cedbca5d463c810e5027c7280dd8e50682ff22f..6fac2ade2e3cad4b254ce2777d1ed6979e2902ff 100644 --- a/extensions/gleam/extension.toml +++ b/extensions/gleam/extension.toml @@ -6,6 +6,10 @@ schema_version = 1 authors = ["Marshall Bowers "] repository = "https://github.com/zed-industries/zed" +capabilities = [ + { kind = "download-file", host = "github.com", path_prefix = "gleam-lang/gleam" }, +] + [language_servers.gleam] name = "Gleam LSP" language = "Gleam"