mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-12 05:27:07 +00:00
When fetching extensions from blob store, don't halt on invalid extensions. (#9241)
This fixes an error where we were failing to sync extensions from the blob store because of the presence of one invalid extensions (`gentle-dark`), which was missing the `authors` field in its manifest. Release Notes: - N/A Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
05dfe96f0c
commit
64219ba49f
1 changed files with 73 additions and 44 deletions
|
@ -140,6 +140,8 @@ async fn fetch_extensions_from_blob_store(
|
||||||
blob_store_bucket: &String,
|
blob_store_bucket: &String,
|
||||||
app_state: &Arc<AppState>,
|
app_state: &Arc<AppState>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
log::info!("fetching extensions from blob store");
|
||||||
|
|
||||||
let list = blob_store_client
|
let list = blob_store_client
|
||||||
.list_objects()
|
.list_objects()
|
||||||
.bucket(blob_store_bucket)
|
.bucket(blob_store_bucket)
|
||||||
|
@ -164,10 +166,12 @@ async fn fetch_extensions_from_blob_store(
|
||||||
let Some(version) = parts.next() else {
|
let Some(version) = parts.next() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
published_versions
|
if parts.next() == Some("manifest.json") {
|
||||||
.entry(extension_id)
|
published_versions
|
||||||
.or_default()
|
.entry(extension_id)
|
||||||
.push(version);
|
.or_default()
|
||||||
|
.push(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let known_versions = app_state.db.get_known_extension_versions().await?;
|
let known_versions = app_state.db.get_known_extension_versions().await?;
|
||||||
|
@ -182,46 +186,20 @@ async fn fetch_extensions_from_blob_store(
|
||||||
.binary_search_by_key(&published_version, String::as_str)
|
.binary_search_by_key(&published_version, String::as_str)
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
let object = blob_store_client
|
if let Some(extension) = fetch_extension_manifest(
|
||||||
.get_object()
|
blob_store_client,
|
||||||
.bucket(blob_store_bucket)
|
blob_store_bucket,
|
||||||
.key(format!(
|
extension_id,
|
||||||
"extensions/{extension_id}/{published_version}/manifest.json"
|
published_version,
|
||||||
))
|
)
|
||||||
.send()
|
.await
|
||||||
.await?;
|
.log_err()
|
||||||
let manifest_bytes = object
|
{
|
||||||
.body
|
new_versions
|
||||||
.collect()
|
.entry(extension_id)
|
||||||
.await
|
.or_default()
|
||||||
.map(|data| data.into_bytes())
|
.push(extension);
|
||||||
.with_context(|| format!("failed to download manifest for extension {extension_id} version {published_version}"))?
|
}
|
||||||
.to_vec();
|
|
||||||
let manifest = serde_json::from_slice::<ExtensionManifest>(&manifest_bytes)
|
|
||||||
.with_context(|| format!("invalid manifest for extension {extension_id} version {published_version}: {}", String::from_utf8_lossy(&manifest_bytes)))?;
|
|
||||||
|
|
||||||
let published_at = object.last_modified.ok_or_else(|| anyhow!("missing last modified timestamp for extension {extension_id} version {published_version}"))?;
|
|
||||||
let published_at =
|
|
||||||
time::OffsetDateTime::from_unix_timestamp_nanos(published_at.as_nanos())?;
|
|
||||||
let published_at = PrimitiveDateTime::new(published_at.date(), published_at.time());
|
|
||||||
|
|
||||||
let version = semver::Version::parse(&manifest.version).with_context(|| {
|
|
||||||
format!(
|
|
||||||
"invalid version for extension {extension_id} version {published_version}"
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
new_versions
|
|
||||||
.entry(extension_id)
|
|
||||||
.or_default()
|
|
||||||
.push(NewExtensionVersion {
|
|
||||||
name: manifest.name,
|
|
||||||
version,
|
|
||||||
description: manifest.description.unwrap_or_default(),
|
|
||||||
authors: manifest.authors,
|
|
||||||
repository: manifest.repository,
|
|
||||||
published_at,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,5 +209,56 @@ async fn fetch_extensions_from_blob_store(
|
||||||
.insert_extension_versions(&new_versions)
|
.insert_extension_versions(&new_versions)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
"fetched {} new extensions from blob store",
|
||||||
|
new_versions.values().map(|v| v.len()).sum::<usize>()
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_extension_manifest(
|
||||||
|
blob_store_client: &aws_sdk_s3::Client,
|
||||||
|
blob_store_bucket: &String,
|
||||||
|
extension_id: &str,
|
||||||
|
version: &str,
|
||||||
|
) -> Result<NewExtensionVersion, anyhow::Error> {
|
||||||
|
let object = blob_store_client
|
||||||
|
.get_object()
|
||||||
|
.bucket(blob_store_bucket)
|
||||||
|
.key(format!("extensions/{extension_id}/{version}/manifest.json"))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
let manifest_bytes = object
|
||||||
|
.body
|
||||||
|
.collect()
|
||||||
|
.await
|
||||||
|
.map(|data| data.into_bytes())
|
||||||
|
.with_context(|| {
|
||||||
|
format!("failed to download manifest for extension {extension_id} version {version}")
|
||||||
|
})?
|
||||||
|
.to_vec();
|
||||||
|
let manifest =
|
||||||
|
serde_json::from_slice::<ExtensionManifest>(&manifest_bytes).with_context(|| {
|
||||||
|
format!(
|
||||||
|
"invalid manifest for extension {extension_id} version {version}: {}",
|
||||||
|
String::from_utf8_lossy(&manifest_bytes)
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let published_at = object.last_modified.ok_or_else(|| {
|
||||||
|
anyhow!("missing last modified timestamp for extension {extension_id} version {version}")
|
||||||
|
})?;
|
||||||
|
let published_at = time::OffsetDateTime::from_unix_timestamp_nanos(published_at.as_nanos())?;
|
||||||
|
let published_at = PrimitiveDateTime::new(published_at.date(), published_at.time());
|
||||||
|
let version = semver::Version::parse(&manifest.version).with_context(|| {
|
||||||
|
format!("invalid version for extension {extension_id} version {version}")
|
||||||
|
})?;
|
||||||
|
Ok(NewExtensionVersion {
|
||||||
|
name: manifest.name,
|
||||||
|
version,
|
||||||
|
description: manifest.description.unwrap_or_default(),
|
||||||
|
authors: manifest.authors,
|
||||||
|
repository: manifest.repository,
|
||||||
|
published_at,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue