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:
Max Brunsfeld 2024-03-20 14:33:26 -07:00 committed by GitHub
parent b1feeb9f29
commit 585e8671e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 165 additions and 44 deletions

View file

@ -4,27 +4,28 @@ impl Database {
pub async fn get_extensions(
&self,
filter: Option<&str>,
max_schema_version: i32,
limit: usize,
) -> Result<Vec<ExtensionMetadata>> {
self.transaction(|tx| async move {
let mut condition = Condition::all();
let mut condition = Condition::all().add(
extension::Column::LatestVersion
.into_expr()
.eq(extension_version::Column::Version.into_expr()),
);
if let Some(filter) = filter {
let fuzzy_name_filter = Self::fuzzy_like_string(filter);
condition = condition.add(Expr::cust_with_expr("name ILIKE $1", fuzzy_name_filter));
}
let extensions = extension::Entity::find()
.inner_join(extension_version::Entity)
.select_also(extension_version::Entity)
.filter(condition)
.filter(extension_version::Column::SchemaVersion.lte(max_schema_version))
.order_by_desc(extension::Column::TotalDownloadCount)
.order_by_asc(extension::Column::Name)
.limit(Some(limit as u64))
.filter(
extension::Column::LatestVersion
.into_expr()
.eq(extension_version::Column::Version.into_expr()),
)
.inner_join(extension_version::Entity)
.select_also(extension_version::Entity)
.all(&*tx)
.await?;
@ -170,6 +171,7 @@ impl Database {
authors: ActiveValue::Set(version.authors.join(", ")),
repository: ActiveValue::Set(version.repository.clone()),
description: ActiveValue::Set(version.description.clone()),
schema_version: ActiveValue::Set(version.schema_version),
download_count: ActiveValue::NotSet,
}
}))

View file

@ -13,6 +13,7 @@ pub struct Model {
pub authors: String,
pub repository: String,
pub description: String,
pub schema_version: i32,
pub download_count: i64,
}

View file

@ -16,7 +16,7 @@ async fn test_extensions(db: &Arc<Database>) {
let versions = db.get_known_extension_versions().await.unwrap();
assert!(versions.is_empty());
let extensions = db.get_extensions(None, 5).await.unwrap();
let extensions = db.get_extensions(None, 1, 5).await.unwrap();
assert!(extensions.is_empty());
let t0 = OffsetDateTime::from_unix_timestamp_nanos(0).unwrap();
@ -33,6 +33,7 @@ async fn test_extensions(db: &Arc<Database>) {
description: "an extension".into(),
authors: vec!["max".into()],
repository: "ext1/repo".into(),
schema_version: 1,
published_at: t0,
},
NewExtensionVersion {
@ -41,6 +42,7 @@ async fn test_extensions(db: &Arc<Database>) {
description: "a good extension".into(),
authors: vec!["max".into(), "marshall".into()],
repository: "ext1/repo".into(),
schema_version: 1,
published_at: t0,
},
],
@ -53,6 +55,7 @@ async fn test_extensions(db: &Arc<Database>) {
description: "a great extension".into(),
authors: vec!["marshall".into()],
repository: "ext2/repo".into(),
schema_version: 0,
published_at: t0,
}],
),
@ -75,7 +78,7 @@ async fn test_extensions(db: &Arc<Database>) {
);
// The latest version of each extension is returned.
let extensions = db.get_extensions(None, 5).await.unwrap();
let extensions = db.get_extensions(None, 1, 5).await.unwrap();
assert_eq!(
extensions,
&[
@ -102,6 +105,22 @@ async fn test_extensions(db: &Arc<Database>) {
]
);
// Extensions with too new of a schema version are excluded.
let extensions = db.get_extensions(None, 0, 5).await.unwrap();
assert_eq!(
extensions,
&[ExtensionMetadata {
id: "ext2".into(),
name: "Extension Two".into(),
version: "0.2.0".into(),
authors: vec!["marshall".into()],
description: "a great extension".into(),
repository: "ext2/repo".into(),
published_at: t0,
download_count: 0
},]
);
// Record extensions being downloaded.
for _ in 0..7 {
assert!(db.record_extension_download("ext2", "0.0.2").await.unwrap());
@ -122,7 +141,7 @@ async fn test_extensions(db: &Arc<Database>) {
.unwrap());
// Extensions are returned in descending order of total downloads.
let extensions = db.get_extensions(None, 5).await.unwrap();
let extensions = db.get_extensions(None, 1, 5).await.unwrap();
assert_eq!(
extensions,
&[
@ -161,6 +180,7 @@ async fn test_extensions(db: &Arc<Database>) {
description: "a real good extension".into(),
authors: vec!["max".into(), "marshall".into()],
repository: "ext1/repo".into(),
schema_version: 1,
published_at: t0,
}],
),
@ -172,6 +192,7 @@ async fn test_extensions(db: &Arc<Database>) {
description: "an old extension".into(),
authors: vec!["marshall".into()],
repository: "ext2/repo".into(),
schema_version: 0,
published_at: t0,
}],
),
@ -196,7 +217,7 @@ async fn test_extensions(db: &Arc<Database>) {
.collect()
);
let extensions = db.get_extensions(None, 5).await.unwrap();
let extensions = db.get_extensions(None, 1, 5).await.unwrap();
assert_eq!(
extensions,
&[