Detailed changes
@@ -4089,6 +4089,29 @@ dependencies = [
"zune-inflate",
]
+[[package]]
+name = "extension"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "async-compression",
+ "async-tar",
+ "collections",
+ "fs",
+ "futures 0.3.30",
+ "http_client",
+ "language",
+ "log",
+ "lsp",
+ "semantic_version",
+ "serde",
+ "serde_json",
+ "toml 0.8.19",
+ "wasm-encoder 0.215.0",
+ "wasmparser 0.215.0",
+ "wit-component",
+]
+
[[package]]
name = "extension_cli"
version = "0.1.0"
@@ -4096,7 +4119,7 @@ dependencies = [
"anyhow",
"clap",
"env_logger 0.11.5",
- "extension_host",
+ "extension",
"fs",
"language",
"log",
@@ -4124,6 +4147,7 @@ dependencies = [
"collections",
"ctor",
"env_logger 0.11.5",
+ "extension",
"fs",
"futures 0.3.30",
"gpui",
@@ -4151,11 +4175,8 @@ dependencies = [
"ui",
"url",
"util",
- "wasm-encoder 0.215.0",
- "wasmparser 0.215.0",
"wasmtime",
"wasmtime-wasi",
- "wit-component",
"workspace",
]
@@ -27,6 +27,7 @@ members = [
"crates/docs_preprocessor",
"crates/editor",
"crates/evals",
+ "crates/extension",
"crates/extension_api",
"crates/extension_cli",
"crates/extension_host",
@@ -201,6 +202,7 @@ copilot = { path = "crates/copilot" }
db = { path = "crates/db" }
diagnostics = { path = "crates/diagnostics" }
editor = { path = "crates/editor" }
+extension = { path = "crates/extension" }
extension_host = { path = "crates/extension_host" }
extensions_ui = { path = "crates/extensions_ui" }
feature_flags = { path = "crates/feature_flags" }
@@ -13,7 +13,6 @@ path = "src/call.rs"
doctest = false
[features]
-no-webrtc = ["live_kit_client/no-webrtc"]
test-support = [
"client/test-support",
"collections/test-support",
@@ -0,0 +1,31 @@
+[package]
+name = "extension"
+version = "0.1.0"
+edition = "2021"
+publish = false
+license = "GPL-3.0-or-later"
+
+[lints]
+workspace = true
+
+[lib]
+path = "src/extension.rs"
+
+[dependencies]
+anyhow.workspace = true
+async-compression.workspace = true
+async-tar.workspace = true
+collections.workspace = true
+fs.workspace = true
+futures.workspace = true
+http_client.workspace = true
+language.workspace = true
+log.workspace = true
+lsp.workspace = true
+semantic_version.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+toml.workspace = true
+wasm-encoder.workspace = true
+wasmparser.workspace = true
+wit-component.workspace = true
@@ -0,0 +1 @@
+../../LICENSE-GPL
@@ -0,0 +1,50 @@
+pub mod extension_builder;
+mod extension_manifest;
+
+use anyhow::{anyhow, bail, Context as _, Result};
+use semantic_version::SemanticVersion;
+
+pub use crate::extension_manifest::*;
+
+pub fn parse_wasm_extension_version(
+ extension_id: &str,
+ wasm_bytes: &[u8],
+) -> Result<SemanticVersion> {
+ let mut version = None;
+
+ for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) {
+ if let wasmparser::Payload::CustomSection(s) =
+ part.context("error parsing wasm extension")?
+ {
+ if s.name() == "zed:api-version" {
+ version = parse_wasm_extension_version_custom_section(s.data());
+ if version.is_none() {
+ bail!(
+ "extension {} has invalid zed:api-version section: {:?}",
+ extension_id,
+ s.data()
+ );
+ }
+ }
+ }
+ }
+
+ // The reason we wait until we're done parsing all of the Wasm bytes to return the version
+ // is to work around a panic that can happen inside of Wasmtime when the bytes are invalid.
+ //
+ // By parsing the entirety of the Wasm bytes before we return, we're able to detect this problem
+ // earlier as an `Err` rather than as a panic.
+ version.ok_or_else(|| anyhow!("extension {} has no zed:api-version section", extension_id))
+}
+
+fn parse_wasm_extension_version_custom_section(data: &[u8]) -> Option<SemanticVersion> {
+ if data.len() == 6 {
+ Some(SemanticVersion::new(
+ u16::from_be_bytes([data[0], data[1]]) as _,
+ u16::from_be_bytes([data[2], data[3]]) as _,
+ u16::from_be_bytes([data[4], data[5]]) as _,
+ ))
+ } else {
+ None
+ }
+}
@@ -1,6 +1,6 @@
-use crate::wasm_host::parse_wasm_extension_version;
-use crate::ExtensionManifest;
-use crate::{extension_manifest::ExtensionLibraryKind, GrammarManifestEntry};
+use crate::{
+ parse_wasm_extension_version, ExtensionLibraryKind, ExtensionManifest, GrammarManifestEntry,
+};
use anyhow::{anyhow, bail, Context as _, Result};
use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
@@ -16,7 +16,7 @@ path = "src/main.rs"
anyhow.workspace = true
clap = { workspace = true, features = ["derive"] }
env_logger.workspace = true
-extension_host = { workspace = true, features = ["no-webrtc"] }
+extension.workspace = true
fs.workspace = true
language.workspace = true
log.workspace = true
@@ -9,7 +9,7 @@ use std::{
use ::fs::{copy_recursive, CopyOptions, Fs, RealFs};
use anyhow::{anyhow, bail, Context, Result};
use clap::Parser;
-use extension_host::{
+use extension::{
extension_builder::{CompileExtensionOptions, ExtensionBuilder},
ExtensionManifest,
};
@@ -12,9 +12,6 @@ workspace = true
path = "src/extension_host.rs"
doctest = false
-[features]
-no-webrtc = ["workspace/no-webrtc"]
-
[dependencies]
anyhow.workspace = true
assistant_slash_command.workspace = true
@@ -23,6 +20,7 @@ async-tar.workspace = true
async-trait.workspace = true
client.workspace = true
collections.workspace = true
+extension.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
@@ -48,11 +46,8 @@ toml.workspace = true
ui.workspace = true
url.workspace = true
util.workspace = true
-wasm-encoder.workspace = true
-wasmparser.workspace = true
wasmtime-wasi.workspace = true
wasmtime.workspace = true
-wit-component.workspace = true
workspace.workspace = true
[dev-dependencies]
@@ -1,7 +1,5 @@
-pub mod extension_builder;
mod extension_indexed_docs_provider;
mod extension_lsp_adapter;
-mod extension_manifest;
mod extension_settings;
mod extension_slash_command;
mod wasm_host;
@@ -10,7 +8,6 @@ mod wasm_host;
mod extension_store_test;
use crate::extension_indexed_docs_provider::ExtensionIndexedDocsProvider;
-use crate::extension_manifest::SchemaVersion;
use crate::extension_slash_command::ExtensionSlashCommand;
use crate::{extension_lsp_adapter::ExtensionLspAdapter, wasm_host::wit};
use anyhow::{anyhow, bail, Context as _, Result};
@@ -19,7 +16,8 @@ use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use client::{telemetry::Telemetry, Client, ExtensionMetadata, GetExtensionsResponse};
use collections::{btree_map, BTreeMap, HashSet};
-use extension_builder::{CompileExtensionOptions, ExtensionBuilder};
+use extension::extension_builder::{CompileExtensionOptions, ExtensionBuilder};
+use extension::SchemaVersion;
use fs::{Fs, RemoveOptions};
use futures::{
channel::{
@@ -62,7 +60,7 @@ use wasm_host::{
WasmExtension, WasmHost,
};
-pub use extension_manifest::{
+pub use extension::{
ExtensionLibraryKind, ExtensionManifest, GrammarManifestEntry, OldExtensionManifest,
};
pub use extension_settings::ExtensionSettings;
@@ -1,4 +1,3 @@
-use crate::extension_manifest::SchemaVersion;
use crate::extension_settings::ExtensionSettings;
use crate::{
Event, ExtensionIndex, ExtensionIndexEntry, ExtensionIndexLanguageEntry,
@@ -8,6 +7,7 @@ use crate::{
use assistant_slash_command::SlashCommandRegistry;
use async_compression::futures::bufread::GzipEncoder;
use collections::BTreeMap;
+use extension::SchemaVersion;
use fs::{FakeFs, Fs, RealFs};
use futures::{io::BufReader, AsyncReadExt, StreamExt};
use gpui::{Context, SemanticVersion, TestAppContext};
@@ -1,7 +1,7 @@
pub(crate) mod wit;
use crate::ExtensionManifest;
-use anyhow::{anyhow, bail, Context as _, Result};
+use anyhow::{anyhow, Context as _, Result};
use fs::{normalize_path, Fs};
use futures::future::LocalBoxFuture;
use futures::{
@@ -112,7 +112,8 @@ impl WasmHost {
) -> Task<Result<WasmExtension>> {
let this = self.clone();
executor.clone().spawn(async move {
- let zed_api_version = parse_wasm_extension_version(&manifest.id, &wasm_bytes)?;
+ let zed_api_version =
+ extension::parse_wasm_extension_version(&manifest.id, &wasm_bytes)?;
let component = Component::from_binary(&this.engine, &wasm_bytes)
.context("failed to compile wasm component")?;
@@ -197,49 +198,6 @@ impl WasmHost {
}
}
-pub fn parse_wasm_extension_version(
- extension_id: &str,
- wasm_bytes: &[u8],
-) -> Result<SemanticVersion> {
- let mut version = None;
-
- for part in wasmparser::Parser::new(0).parse_all(wasm_bytes) {
- if let wasmparser::Payload::CustomSection(s) =
- part.context("error parsing wasm extension")?
- {
- if s.name() == "zed:api-version" {
- version = parse_wasm_extension_version_custom_section(s.data());
- if version.is_none() {
- bail!(
- "extension {} has invalid zed:api-version section: {:?}",
- extension_id,
- s.data()
- );
- }
- }
- }
- }
-
- // The reason we wait until we're done parsing all of the Wasm bytes to return the version
- // is to work around a panic that can happen inside of Wasmtime when the bytes are invalid.
- //
- // By parsing the entirety of the Wasm bytes before we return, we're able to detect this problem
- // earlier as an `Err` rather than as a panic.
- version.ok_or_else(|| anyhow!("extension {} has no zed:api-version section", extension_id))
-}
-
-fn parse_wasm_extension_version_custom_section(data: &[u8]) -> Option<SemanticVersion> {
- if data.len() == 6 {
- Some(SemanticVersion::new(
- u16::from_be_bytes([data[0], data[1]]) as _,
- u16::from_be_bytes([data[2], data[3]]) as _,
- u16::from_be_bytes([data[4], data[5]]) as _,
- ))
- } else {
- None
- }
-}
-
impl WasmExtension {
pub async fn call<T, Fn>(&self, f: Fn) -> T
where
@@ -13,7 +13,6 @@ path = "src/workspace.rs"
doctest = false
[features]
-no-webrtc = ["call/no-webrtc"]
test-support = [
"call/test-support",
"client/test-support",