mirror of
https://github.com/pesde-pkg/pesde.git
synced 2025-04-09 05:10:54 +01:00
refactor: use iteration over recursion
Replaces the recursive implementation of fallback Wally registries with an iterative approach.
This commit is contained in:
parent
6856746ae2
commit
f0e69a08e2
3 changed files with 101 additions and 98 deletions
|
@ -306,7 +306,7 @@ impl PruneCommand {
|
||||||
if removed_hashes.contains(&hash) {
|
if removed_hashes.contains(&hash) {
|
||||||
let cas_dir = project.cas_dir().to_path_buf();
|
let cas_dir = project.cas_dir().to_path_buf();
|
||||||
tasks.spawn(async move {
|
tasks.spawn(async move {
|
||||||
fs::remove_file(dbg!(&path))
|
fs::remove_file(&path)
|
||||||
.await
|
.await
|
||||||
.context("failed to remove unused file")?;
|
.context("failed to remove unused file")?;
|
||||||
|
|
||||||
|
|
|
@ -466,8 +466,7 @@ pub struct IndexFileEntry {
|
||||||
/// The target for this package
|
/// The target for this package
|
||||||
pub target: Target,
|
pub target: Target,
|
||||||
/// When this package was published
|
/// When this package was published
|
||||||
#[serde(default = "chrono::Utc::now")]
|
pub published_at: jiff::Timestamp,
|
||||||
pub published_at: chrono::DateTime<chrono::Utc>,
|
|
||||||
/// The engines this package supports
|
/// The engines this package supports
|
||||||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
pub engines: BTreeMap<EngineKind, VersionReq>,
|
pub engines: BTreeMap<EngineKind, VersionReq>,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
manifest::target::{Target, TargetKind},
|
manifest::target::{Target, TargetKind},
|
||||||
names::PackageNames,
|
names::{wally::WallyPackageName, PackageNames},
|
||||||
reporters::{response_to_async_read, DownloadProgressReporter},
|
reporters::{response_to_async_read, DownloadProgressReporter},
|
||||||
source::{
|
source::{
|
||||||
fs::{store_in_cas, FsEntry, PackageFs},
|
fs::{store_in_cas, FsEntry, PackageFs},
|
||||||
|
@ -84,6 +84,26 @@ impl WallyPackageSource {
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn read_index_file(
|
||||||
|
&self,
|
||||||
|
project: &Project,
|
||||||
|
name: &WallyPackageName,
|
||||||
|
) -> Result<Option<String>, errors::ResolveError> {
|
||||||
|
let path = self.path(project);
|
||||||
|
let pkg_name = name.clone();
|
||||||
|
|
||||||
|
spawn_blocking(move || {
|
||||||
|
let repo = gix::open(&path).map_err(Box::new)?;
|
||||||
|
let tree = root_tree(&repo).map_err(Box::new)?;
|
||||||
|
let (scope, name) = pkg_name.as_str();
|
||||||
|
|
||||||
|
read_file(&tree, [scope, name])
|
||||||
|
.map_err(|e| errors::ResolveError::Read(pkg_name.to_string(), Box::new(e)))
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PackageSource for WallyPackageSource {
|
impl PackageSource for WallyPackageSource {
|
||||||
|
@ -105,110 +125,94 @@ impl PackageSource for WallyPackageSource {
|
||||||
specifier: &Self::Specifier,
|
specifier: &Self::Specifier,
|
||||||
options: &ResolveOptions,
|
options: &ResolveOptions,
|
||||||
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> {
|
) -> Result<ResolveResult<Self::Ref>, Self::ResolveError> {
|
||||||
async fn inner(
|
let ResolveOptions {
|
||||||
source: &WallyPackageSource,
|
project,
|
||||||
specifier: &specifier::WallyDependencySpecifier,
|
refreshed_sources,
|
||||||
options: &ResolveOptions,
|
..
|
||||||
) -> Result<ResolveResult<WallyPackageRef>, errors::ResolveError> {
|
} = options;
|
||||||
let ResolveOptions {
|
|
||||||
project,
|
|
||||||
refreshed_sources,
|
|
||||||
..
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
let Some(string) = ({
|
let mut string = self.read_index_file(project, &specifier.name).await?;
|
||||||
let repo = gix::open(source.path(project)).map_err(Box::new)?;
|
let mut index_url = self.repo_url.clone();
|
||||||
let tree = root_tree(&repo).map_err(Box::new)?;
|
|
||||||
let (scope, name) = specifier.name.as_str();
|
|
||||||
match read_file(&tree, [scope, name]) {
|
|
||||||
Ok(string) => string,
|
|
||||||
Err(e) => {
|
|
||||||
return Err(errors::ResolveError::Read(
|
|
||||||
specifier.name.to_string(),
|
|
||||||
Box::new(e),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) else {
|
|
||||||
tracing::debug!(
|
|
||||||
"{} not found in wally registry. searching in backup registries",
|
|
||||||
specifier.name
|
|
||||||
);
|
|
||||||
let config = source.config(project).await.map_err(Box::new)?;
|
|
||||||
for registry in config.fallback_registries {
|
|
||||||
let source = WallyPackageSource::new(registry);
|
|
||||||
match refreshed_sources
|
|
||||||
.refresh(
|
|
||||||
&PackageSources::Wally(source.clone()),
|
|
||||||
&RefreshOptions {
|
|
||||||
project: project.clone(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(super::errors::RefreshError::Wally(e)) => {
|
|
||||||
return Err(errors::ResolveError::Refresh(Box::new(e)));
|
|
||||||
}
|
|
||||||
Err(e) => panic!("unexpected error: {e:?}"),
|
|
||||||
}
|
|
||||||
|
|
||||||
match Box::pin(inner(&source, specifier, options)).await {
|
if string.is_none() {
|
||||||
Ok((name, results)) => {
|
tracing::debug!(
|
||||||
tracing::debug!("found {name} in backup registry {}", source.repo_url);
|
"{} not found in Wally registry. searching in backup registries",
|
||||||
return Ok((name, results));
|
specifier.name
|
||||||
}
|
);
|
||||||
Err(errors::ResolveError::NotFound(_)) => {
|
let config = self.config(project).await.map_err(Box::new)?;
|
||||||
continue;
|
|
||||||
}
|
for url in config.fallback_registries {
|
||||||
Err(e) => {
|
let source = WallyPackageSource::new(url);
|
||||||
return Err(e);
|
|
||||||
}
|
match refreshed_sources
|
||||||
|
.refresh(
|
||||||
|
&PackageSources::Wally(source.clone()),
|
||||||
|
&RefreshOptions {
|
||||||
|
project: project.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(super::errors::RefreshError::Wally(e)) => {
|
||||||
|
return Err(errors::ResolveError::Refresh(Box::new(e)));
|
||||||
}
|
}
|
||||||
|
Err(e) => panic!("unexpected error: {e:?}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(errors::ResolveError::NotFound(specifier.name.to_string()));
|
match source.read_index_file(project, &specifier.name).await {
|
||||||
};
|
Ok(Some(res)) => {
|
||||||
|
string = Some(res);
|
||||||
|
index_url = source.repo_url;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
tracing::debug!("{} not found in {}", specifier.name, source.repo_url);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let entries: Vec<WallyManifest> = string
|
let Some(string) = string else {
|
||||||
.lines()
|
return Err(errors::ResolveError::NotFound(specifier.name.to_string()));
|
||||||
.map(serde_json::from_str)
|
};
|
||||||
.collect::<Result<_, _>>()
|
|
||||||
.map_err(|e| errors::ResolveError::Parse(specifier.name.to_string(), e))?;
|
|
||||||
|
|
||||||
tracing::debug!("{} has {} possible entries", specifier.name, entries.len());
|
let entries: Vec<WallyManifest> = string
|
||||||
|
.lines()
|
||||||
|
.map(serde_json::from_str)
|
||||||
|
.collect::<Result<_, _>>()
|
||||||
|
.map_err(|e| errors::ResolveError::Parse(specifier.name.to_string(), e))?;
|
||||||
|
|
||||||
Ok((
|
tracing::debug!("{} has {} possible entries", specifier.name, entries.len());
|
||||||
PackageNames::Wally(specifier.name.clone()),
|
|
||||||
entries
|
|
||||||
.into_iter()
|
|
||||||
.filter(|manifest| {
|
|
||||||
version_matches(&specifier.version, &manifest.package.version)
|
|
||||||
})
|
|
||||||
.map(|manifest| {
|
|
||||||
let dependencies = manifest.all_dependencies().map_err(|e| {
|
|
||||||
errors::ResolveError::AllDependencies(specifier.to_string(), e)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
VersionId(
|
PackageNames::Wally(specifier.name.clone()),
|
||||||
manifest.package.version,
|
entries
|
||||||
match manifest.package.realm {
|
.into_iter()
|
||||||
Realm::Server => TargetKind::RobloxServer,
|
.filter(|manifest| version_matches(&specifier.version, &manifest.package.version))
|
||||||
_ => TargetKind::Roblox,
|
.map(|manifest| {
|
||||||
},
|
let dependencies = manifest.all_dependencies().map_err(|e| {
|
||||||
),
|
errors::ResolveError::AllDependencies(specifier.to_string(), e)
|
||||||
WallyPackageRef {
|
})?;
|
||||||
index_url: source.repo_url.clone(),
|
|
||||||
dependencies,
|
Ok((
|
||||||
|
VersionId(
|
||||||
|
manifest.package.version,
|
||||||
|
match manifest.package.realm {
|
||||||
|
Realm::Server => TargetKind::RobloxServer,
|
||||||
|
_ => TargetKind::Roblox,
|
||||||
},
|
},
|
||||||
))
|
),
|
||||||
})
|
WallyPackageRef {
|
||||||
.collect::<Result<_, errors::ResolveError>>()?,
|
index_url: index_url.clone(),
|
||||||
))
|
dependencies,
|
||||||
}
|
},
|
||||||
|
))
|
||||||
inner(self, specifier, options).await
|
})
|
||||||
|
.collect::<Result<_, errors::ResolveError>>()?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all, level = "debug")]
|
#[instrument(skip_all, level = "debug")]
|
||||||
|
|
Loading…
Add table
Reference in a new issue