Add a schema to extensions, to prevent installing extensions on too old of a Zed version (#9599)
Release Notes: - N/A --------- Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
b1feeb9f29
commit
585e8671e3
22 changed files with 165 additions and 44 deletions
|
@ -37,6 +37,7 @@ serde_json.workspace = true
|
|||
settings.workspace = true
|
||||
theme.workspace = true
|
||||
toml.workspace = true
|
||||
url.workspace = true
|
||||
util.workspace = true
|
||||
wasm-encoder.workspace = true
|
||||
wasmtime.workspace = true
|
||||
|
|
|
@ -29,6 +29,7 @@ pub struct ExtensionManifest {
|
|||
pub id: Arc<str>,
|
||||
pub name: String,
|
||||
pub version: Arc<str>,
|
||||
pub schema_version: i32,
|
||||
|
||||
#[serde(default)]
|
||||
pub description: Option<String>,
|
||||
|
|
|
@ -35,6 +35,7 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
use theme::{ThemeRegistry, ThemeSettings};
|
||||
use url::Url;
|
||||
use util::{
|
||||
http::{AsyncBody, HttpClient, HttpClientWithUrl},
|
||||
paths::EXTENSIONS_DIR,
|
||||
|
@ -49,6 +50,8 @@ pub use extension_manifest::{
|
|||
const RELOAD_DEBOUNCE_DURATION: Duration = Duration::from_millis(200);
|
||||
const FS_WATCH_LATENCY: Duration = Duration::from_millis(100);
|
||||
|
||||
const CURRENT_SCHEMA_VERSION: i64 = 1;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ExtensionsApiResponse {
|
||||
pub data: Vec<ExtensionApiResponse>,
|
||||
|
@ -377,15 +380,18 @@ impl ExtensionStore {
|
|||
search: Option<&str>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<ExtensionApiResponse>>> {
|
||||
let url = self.http_client.build_zed_api_url(&format!(
|
||||
"/extensions{query}",
|
||||
query = search
|
||||
.map(|search| format!("?filter={search}"))
|
||||
.unwrap_or_default()
|
||||
));
|
||||
let version = CURRENT_SCHEMA_VERSION.to_string();
|
||||
let mut query = vec![("max_schema_version", version.as_str())];
|
||||
if let Some(search) = search {
|
||||
query.push(("filter", search));
|
||||
}
|
||||
|
||||
let url = self.http_client.build_zed_api_url("/extensions", &query);
|
||||
let http_client = self.http_client.clone();
|
||||
cx.spawn(move |_, _| async move {
|
||||
let mut response = http_client.get(&url, AsyncBody::empty(), true).await?;
|
||||
let mut response = http_client
|
||||
.get(&url?.as_ref(), AsyncBody::empty(), true)
|
||||
.await?;
|
||||
|
||||
let mut body = Vec::new();
|
||||
response
|
||||
|
@ -420,7 +426,7 @@ impl ExtensionStore {
|
|||
fn install_or_upgrade_extension_at_endpoint(
|
||||
&mut self,
|
||||
extension_id: Arc<str>,
|
||||
url: String,
|
||||
url: Url,
|
||||
operation: ExtensionOperation,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
|
@ -447,7 +453,7 @@ impl ExtensionStore {
|
|||
});
|
||||
|
||||
let mut response = http_client
|
||||
.get(&url, Default::default(), true)
|
||||
.get(&url.as_ref(), Default::default(), true)
|
||||
.await
|
||||
.map_err(|err| anyhow!("error downloading extension: {}", err))?;
|
||||
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
|
||||
|
@ -482,9 +488,13 @@ impl ExtensionStore {
|
|||
) {
|
||||
log::info!("installing extension {extension_id} latest version");
|
||||
|
||||
let url = self
|
||||
let Some(url) = self
|
||||
.http_client
|
||||
.build_zed_api_url(&format!("/extensions/{extension_id}/download"));
|
||||
.build_zed_api_url(&format!("/extensions/{extension_id}/download"), &[])
|
||||
.log_err()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.install_or_upgrade_extension_at_endpoint(
|
||||
extension_id,
|
||||
|
@ -511,9 +521,16 @@ impl ExtensionStore {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
log::info!("installing extension {extension_id} {version}");
|
||||
let url = self
|
||||
let Some(url) = self
|
||||
.http_client
|
||||
.build_zed_api_url(&format!("/extensions/{extension_id}/{version}/download"));
|
||||
.build_zed_api_url(
|
||||
&format!("/extensions/{extension_id}/{version}/download"),
|
||||
&[],
|
||||
)
|
||||
.log_err()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.install_or_upgrade_extension_at_endpoint(extension_id, url, operation, cx);
|
||||
}
|
||||
|
@ -1104,6 +1121,7 @@ fn manifest_from_old_manifest(
|
|||
description: manifest_json.description,
|
||||
repository: manifest_json.repository,
|
||||
authors: manifest_json.authors,
|
||||
schema_version: 0,
|
||||
lib: Default::default(),
|
||||
themes: {
|
||||
let mut themes = manifest_json.themes.into_values().collect::<Vec<_>>();
|
||||
|
|
|
@ -145,6 +145,7 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
|||
id: "zed-ruby".into(),
|
||||
name: "Zed Ruby".into(),
|
||||
version: "1.0.0".into(),
|
||||
schema_version: 0,
|
||||
description: None,
|
||||
authors: Vec::new(),
|
||||
repository: None,
|
||||
|
@ -169,6 +170,7 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
|||
id: "zed-monokai".into(),
|
||||
name: "Zed Monokai".into(),
|
||||
version: "2.0.0".into(),
|
||||
schema_version: 0,
|
||||
description: None,
|
||||
authors: vec![],
|
||||
repository: None,
|
||||
|
@ -324,6 +326,7 @@ async fn test_extension_store(cx: &mut TestAppContext) {
|
|||
id: "zed-gruvbox".into(),
|
||||
name: "Zed Gruvbox".into(),
|
||||
version: "1.0.0".into(),
|
||||
schema_version: 0,
|
||||
description: None,
|
||||
authors: vec![],
|
||||
repository: None,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue