Restrict v0.0.7 of the zed_extension_api to dev builds, for now (#12170)

This PR restricts usage of v0.0.7 of the `zed_extension_api` to dev
builds, for now.

As we're still making changes to it, we don't want to ship a version of
Zed to Preview/Stable that claims to support a yet-unreleased version of
the extension API.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-05-22 19:45:34 -04:00 committed by GitHub
parent 80bd40cfa3
commit 85ff80f3c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 48 additions and 15 deletions

2
Cargo.lock generated
View file

@ -3790,6 +3790,7 @@ dependencies = [
"node_runtime", "node_runtime",
"parking_lot", "parking_lot",
"project", "project",
"release_channel",
"schemars", "schemars",
"semantic_version", "semantic_version",
"serde", "serde",
@ -3844,6 +3845,7 @@ dependencies = [
"language", "language",
"picker", "picker",
"project", "project",
"release_channel",
"semantic_version", "semantic_version",
"serde", "serde",
"settings", "settings",

View file

@ -30,6 +30,7 @@ log.workspace = true
lsp.workspace = true lsp.workspace = true
node_runtime.workspace = true node_runtime.workspace = true
project.workspace = true project.workspace = true
release_channel.workspace = true
schemars.workspace = true schemars.workspace = true
semantic_version.workspace = true semantic_version.workspace = true
serde.workspace = true serde.workspace = true

View file

@ -34,6 +34,7 @@ use language::{
}; };
use node_runtime::NodeRuntime; use node_runtime::NodeRuntime;
use project::ContextProviderWithTasks; use project::ContextProviderWithTasks;
use release_channel::ReleaseChannel;
use semantic_version::SemanticVersion; use semantic_version::SemanticVersion;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::Settings; use settings::Settings;
@ -70,7 +71,10 @@ pub fn schema_version_range() -> RangeInclusive<SchemaVersion> {
} }
/// Returns whether the given extension version is compatible with this version of Zed. /// Returns whether the given extension version is compatible with this version of Zed.
pub fn is_version_compatible(extension_version: &ExtensionMetadata) -> bool { pub fn is_version_compatible(
release_channel: ReleaseChannel,
extension_version: &ExtensionMetadata,
) -> bool {
let schema_version = extension_version.manifest.schema_version.unwrap_or(0); let schema_version = extension_version.manifest.schema_version.unwrap_or(0);
if CURRENT_SCHEMA_VERSION.0 < schema_version { if CURRENT_SCHEMA_VERSION.0 < schema_version {
return false; return false;
@ -82,7 +86,7 @@ pub fn is_version_compatible(extension_version: &ExtensionMetadata) -> bool {
.as_ref() .as_ref()
.and_then(|wasm_api_version| SemanticVersion::from_str(wasm_api_version).ok()) .and_then(|wasm_api_version| SemanticVersion::from_str(wasm_api_version).ok())
{ {
if !is_supported_wasm_api_version(wasm_api_version) { if !is_supported_wasm_api_version(release_channel, wasm_api_version) {
return false; return false;
} }
} }
@ -428,7 +432,7 @@ impl ExtensionStore {
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Task<Result<Vec<ExtensionMetadata>>> { ) -> Task<Result<Vec<ExtensionMetadata>>> {
let schema_versions = schema_version_range(); let schema_versions = schema_version_range();
let wasm_api_versions = wasm_api_version_range(); let wasm_api_versions = wasm_api_version_range(ReleaseChannel::global(cx));
let extension_settings = ExtensionSettings::get_global(cx); let extension_settings = ExtensionSettings::get_global(cx);
let extension_ids = self let extension_ids = self
.extension_index .extension_index
@ -681,7 +685,7 @@ impl ExtensionStore {
log::info!("installing extension {extension_id} latest version"); log::info!("installing extension {extension_id} latest version");
let schema_versions = schema_version_range(); let schema_versions = schema_version_range();
let wasm_api_versions = wasm_api_version_range(); let wasm_api_versions = wasm_api_version_range(ReleaseChannel::global(cx));
let Some(url) = self let Some(url) = self
.http_client .http_client

View file

@ -714,6 +714,7 @@ fn init_test(cx: &mut TestAppContext) {
cx.update(|cx| { cx.update(|cx| {
let store = SettingsStore::test(cx); let store = SettingsStore::test(cx);
cx.set_global(store); cx.set_global(store);
release_channel::init("0.0.0", cx);
theme::init(theme::LoadThemes::JustBase, cx); theme::init(theme::LoadThemes::JustBase, cx);
Project::init_settings(cx); Project::init_settings(cx);
ExtensionSettings::register(cx); ExtensionSettings::register(cx);

View file

@ -16,6 +16,7 @@ use gpui::{AppContext, AsyncAppContext, BackgroundExecutor, Task};
use http::HttpClient; use http::HttpClient;
use language::LanguageRegistry; use language::LanguageRegistry;
use node_runtime::NodeRuntime; use node_runtime::NodeRuntime;
use release_channel::ReleaseChannel;
use semantic_version::SemanticVersion; use semantic_version::SemanticVersion;
use std::{ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
@ -30,6 +31,7 @@ use wit::Extension;
pub(crate) struct WasmHost { pub(crate) struct WasmHost {
engine: Engine, engine: Engine,
release_channel: ReleaseChannel,
http_client: Arc<dyn HttpClient>, http_client: Arc<dyn HttpClient>,
node_runtime: Arc<dyn NodeRuntime>, node_runtime: Arc<dyn NodeRuntime>,
pub(crate) language_registry: Arc<LanguageRegistry>, pub(crate) language_registry: Arc<LanguageRegistry>,
@ -96,6 +98,7 @@ impl WasmHost {
http_client, http_client,
node_runtime, node_runtime,
language_registry, language_registry,
release_channel: ReleaseChannel::global(cx),
_main_thread_message_task: task, _main_thread_message_task: task,
main_thread_message_tx: tx, main_thread_message_tx: tx,
}) })
@ -124,8 +127,13 @@ impl WasmHost {
}, },
); );
let (mut extension, instance) = let (mut extension, instance) = Extension::instantiate_async(
Extension::instantiate_async(&mut store, zed_api_version, &component).await?; &mut store,
this.release_channel,
zed_api_version,
&component,
)
.await?;
extension extension
.call_init_extension(&mut store) .call_init_extension(&mut store)

View file

@ -2,6 +2,7 @@ mod since_v0_0_1;
mod since_v0_0_4; mod since_v0_0_4;
mod since_v0_0_6; mod since_v0_0_6;
mod since_v0_0_7; mod since_v0_0_7;
use release_channel::ReleaseChannel;
use since_v0_0_7 as latest; use since_v0_0_7 as latest;
use super::{wasm_engine, WasmState}; use super::{wasm_engine, WasmState};
@ -36,14 +37,23 @@ fn wasi_view(state: &mut WasmState) -> &mut WasmState {
} }
/// Returns whether the given Wasm API version is supported by the Wasm host. /// Returns whether the given Wasm API version is supported by the Wasm host.
pub fn is_supported_wasm_api_version(version: SemanticVersion) -> bool { pub fn is_supported_wasm_api_version(
wasm_api_version_range().contains(&version) release_channel: ReleaseChannel,
version: SemanticVersion,
) -> bool {
wasm_api_version_range(release_channel).contains(&version)
} }
/// Returns the Wasm API version range that is supported by the Wasm host. /// Returns the Wasm API version range that is supported by the Wasm host.
#[inline(always)] #[inline(always)]
pub fn wasm_api_version_range() -> RangeInclusive<SemanticVersion> { pub fn wasm_api_version_range(release_channel: ReleaseChannel) -> RangeInclusive<SemanticVersion> {
since_v0_0_1::MIN_VERSION..=latest::MAX_VERSION let max_version = if release_channel == ReleaseChannel::Dev {
latest::MAX_VERSION
} else {
since_v0_0_6::MAX_VERSION
};
since_v0_0_1::MIN_VERSION..=max_version
} }
pub enum Extension { pub enum Extension {
@ -56,10 +66,11 @@ pub enum Extension {
impl Extension { impl Extension {
pub async fn instantiate_async( pub async fn instantiate_async(
store: &mut Store<WasmState>, store: &mut Store<WasmState>,
release_channel: ReleaseChannel,
version: SemanticVersion, version: SemanticVersion,
component: &Component, component: &Component,
) -> Result<(Self, Instance)> { ) -> Result<(Self, Instance)> {
if version >= latest::MIN_VERSION { if release_channel == ReleaseChannel::Dev && version >= latest::MIN_VERSION {
let (extension, instance) = let (extension, instance) =
latest::Extension::instantiate_async(store, &component, latest::linker()) latest::Extension::instantiate_async(store, &component, latest::linker())
.await .await

View file

@ -8,6 +8,7 @@ use std::sync::{Arc, OnceLock};
use wasmtime::component::{Linker, Resource}; use wasmtime::component::{Linker, Resource};
pub const MIN_VERSION: SemanticVersion = SemanticVersion::new(0, 0, 6); pub const MIN_VERSION: SemanticVersion = SemanticVersion::new(0, 0, 6);
pub const MAX_VERSION: SemanticVersion = SemanticVersion::new(0, 0, 6);
wasmtime::component::bindgen!({ wasmtime::component::bindgen!({
async: true, async: true,

View file

@ -26,6 +26,7 @@ gpui.workspace = true
language.workspace = true language.workspace = true
picker.workspace = true picker.workspace = true
project.workspace = true project.workspace = true
release_channel.workspace = true
semantic_version.workspace = true semantic_version.workspace = true
serde.workspace = true serde.workspace = true
settings.workspace = true settings.workspace = true

View file

@ -9,6 +9,7 @@ use gpui::{
prelude::*, AppContext, DismissEvent, EventEmitter, FocusableView, Task, View, WeakView, prelude::*, AppContext, DismissEvent, EventEmitter, FocusableView, Task, View, WeakView,
}; };
use picker::{Picker, PickerDelegate}; use picker::{Picker, PickerDelegate};
use release_channel::ReleaseChannel;
use semantic_version::SemanticVersion; use semantic_version::SemanticVersion;
use settings::update_settings_file; use settings::update_settings_file;
use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing}; use ui::{prelude::*, HighlightedLabel, ListItem, ListItemSpacing};
@ -166,7 +167,7 @@ impl PickerDelegate for ExtensionVersionSelectorDelegate {
let candidate_id = self.matches[self.selected_index].candidate_id; let candidate_id = self.matches[self.selected_index].candidate_id;
let extension_version = &self.extension_versions[candidate_id]; let extension_version = &self.extension_versions[candidate_id];
if !extension::is_version_compatible(extension_version) { if !extension::is_version_compatible(ReleaseChannel::global(cx), extension_version) {
return; return;
} }
@ -196,12 +197,13 @@ impl PickerDelegate for ExtensionVersionSelectorDelegate {
&self, &self,
ix: usize, ix: usize,
selected: bool, selected: bool,
_cx: &mut ViewContext<Picker<Self>>, cx: &mut ViewContext<Picker<Self>>,
) -> Option<Self::ListItem> { ) -> Option<Self::ListItem> {
let version_match = &self.matches[ix]; let version_match = &self.matches[ix];
let extension_version = &self.extension_versions[version_match.candidate_id]; let extension_version = &self.extension_versions[version_match.candidate_id];
let is_version_compatible = extension::is_version_compatible(extension_version); let is_version_compatible =
extension::is_version_compatible(ReleaseChannel::global(cx), extension_version);
let disabled = !is_version_compatible; let disabled = !is_version_compatible;
Some( Some(

View file

@ -16,6 +16,7 @@ use gpui::{
FontWeight, InteractiveElement, KeyContext, ParentElement, Render, Styled, Task, TextStyle, FontWeight, InteractiveElement, KeyContext, ParentElement, Render, Styled, Task, TextStyle,
UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WhiteSpace, WindowContext, UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WhiteSpace, WindowContext,
}; };
use release_channel::ReleaseChannel;
use settings::Settings; use settings::Settings;
use std::ops::DerefMut; use std::ops::DerefMut;
use std::time::Duration; use std::time::Duration;
@ -602,7 +603,8 @@ impl ExtensionsPage {
has_dev_extension: bool, has_dev_extension: bool,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> (Button, Option<Button>) { ) -> (Button, Option<Button>) {
let is_compatible = extension::is_version_compatible(&extension); let is_compatible =
extension::is_version_compatible(ReleaseChannel::global(cx), &extension);
if has_dev_extension { if has_dev_extension {
// If we have a dev extension for the given extension, just treat it as uninstalled. // If we have a dev extension for the given extension, just treat it as uninstalled.