mirror of
https://github.com/pesde-pkg/pesde.git
synced 2025-04-05 19:30:57 +01:00
feat: add override by alias support
This commit is contained in:
parent
2936f88a99
commit
2aeee9de34
6 changed files with 86 additions and 13 deletions
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
## [Unreleased]
|
||||
### Added
|
||||
- Improve installation experience by @lukadev-0
|
||||
- Support using aliases of own dependencies for overrides by @daimond113
|
||||
|
||||
### Performance
|
||||
- Use `Arc` for more efficient cloning of multiple structs by @daimond113
|
||||
|
|
|
@ -20,7 +20,7 @@ use tokio::task::JoinSet;
|
|||
use crate::cli::{
|
||||
bin_dir,
|
||||
reporters::{self, CliReporter},
|
||||
run_on_workspace_members, up_to_date_lockfile,
|
||||
resolve_overrides, run_on_workspace_members, up_to_date_lockfile,
|
||||
};
|
||||
|
||||
use super::files::make_executable;
|
||||
|
@ -198,7 +198,7 @@ pub async fn install(
|
|||
} else {
|
||||
match project.deser_lockfile().await {
|
||||
Ok(lockfile) => {
|
||||
if lockfile.overrides != manifest.overrides {
|
||||
if lockfile.overrides != resolve_overrides(&manifest)? {
|
||||
tracing::debug!("overrides are different");
|
||||
None
|
||||
} else if lockfile.target != manifest.target.kind() {
|
||||
|
@ -217,6 +217,8 @@ pub async fn install(
|
|||
}
|
||||
};
|
||||
|
||||
let overrides = resolve_overrides(&manifest)?;
|
||||
|
||||
let (new_lockfile, old_graph) =
|
||||
reporters::run_with_reporter(|_, root_progress, reporter| async {
|
||||
let root_progress = root_progress;
|
||||
|
@ -323,7 +325,7 @@ pub async fn install(
|
|||
name: manifest.name.clone(),
|
||||
version: manifest.version,
|
||||
target: manifest.target.kind(),
|
||||
overrides: manifest.overrides,
|
||||
overrides,
|
||||
|
||||
graph: downloaded_graph,
|
||||
|
||||
|
|
|
@ -4,9 +4,16 @@ use fs_err::tokio as fs;
|
|||
use futures::StreamExt;
|
||||
use pesde::{
|
||||
lockfile::Lockfile,
|
||||
manifest::target::TargetKind,
|
||||
manifest::{
|
||||
overrides::{OverrideKey, OverrideSpecifier},
|
||||
target::TargetKind,
|
||||
Manifest,
|
||||
},
|
||||
names::{PackageName, PackageNames},
|
||||
source::{version_id::VersionId, workspace::specifier::VersionTypeOrReq},
|
||||
source::{
|
||||
specifiers::DependencySpecifiers, version_id::VersionId,
|
||||
workspace::specifier::VersionTypeOrReq,
|
||||
},
|
||||
Project,
|
||||
};
|
||||
use relative_path::RelativePathBuf;
|
||||
|
@ -44,6 +51,40 @@ pub async fn bin_dir() -> anyhow::Result<PathBuf> {
|
|||
Ok(bin_dir)
|
||||
}
|
||||
|
||||
pub fn resolve_overrides(
|
||||
manifest: &Manifest,
|
||||
) -> anyhow::Result<BTreeMap<OverrideKey, DependencySpecifiers>> {
|
||||
let mut dependencies = None;
|
||||
let mut overrides = BTreeMap::new();
|
||||
|
||||
for (key, spec) in &manifest.overrides {
|
||||
overrides.insert(
|
||||
key.clone(),
|
||||
match spec {
|
||||
OverrideSpecifier::Specifier(spec) => spec,
|
||||
OverrideSpecifier::Alias(alias) => {
|
||||
if dependencies.is_none() {
|
||||
dependencies = Some(
|
||||
manifest
|
||||
.all_dependencies()
|
||||
.context("failed to get all dependencies")?,
|
||||
);
|
||||
}
|
||||
|
||||
&dependencies
|
||||
.as_ref()
|
||||
.and_then(|deps| deps.get(alias))
|
||||
.with_context(|| format!("alias `{alias}` not found in manifest"))?
|
||||
.0
|
||||
}
|
||||
}
|
||||
.clone(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(overrides)
|
||||
}
|
||||
|
||||
#[instrument(skip(project), ret(level = "trace"), level = "debug")]
|
||||
pub async fn up_to_date_lockfile(project: &Project) -> anyhow::Result<Option<Lockfile>> {
|
||||
let manifest = project.deser_manifest().await?;
|
||||
|
@ -57,7 +98,7 @@ pub async fn up_to_date_lockfile(project: &Project) -> anyhow::Result<Option<Loc
|
|||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
|
||||
if manifest.overrides != lockfile.overrides {
|
||||
if resolve_overrides(&manifest)? != lockfile.overrides {
|
||||
tracing::debug!("overrides are different");
|
||||
return Ok(None);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{
|
||||
manifest::{overrides::OverrideKey, target::Target},
|
||||
manifest::{
|
||||
overrides::{OverrideKey, OverrideSpecifier},
|
||||
target::Target,
|
||||
},
|
||||
names::PackageName,
|
||||
source::specifiers::DependencySpecifiers,
|
||||
};
|
||||
|
@ -58,7 +61,7 @@ pub struct Manifest {
|
|||
pub wally_indices: BTreeMap<String, gix::Url>,
|
||||
/// The overrides this package has
|
||||
#[serde(default, skip_serializing)]
|
||||
pub overrides: BTreeMap<OverrideKey, DependencySpecifiers>,
|
||||
pub overrides: BTreeMap<OverrideKey, OverrideSpecifier>,
|
||||
/// The files to include in the package
|
||||
#[serde(default)]
|
||||
pub includes: Vec<String>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::source::specifiers::DependencySpecifiers;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{DeserializeFromStr, SerializeDisplay};
|
||||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
|
@ -47,6 +49,16 @@ impl Display for OverrideKey {
|
|||
}
|
||||
}
|
||||
|
||||
/// A specifier for an override
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
|
||||
#[serde(untagged)]
|
||||
pub enum OverrideSpecifier {
|
||||
/// A specifier for a dependency
|
||||
Specifier(DependencySpecifiers),
|
||||
/// An alias for a dependency the current project depends on
|
||||
Alias(String),
|
||||
}
|
||||
|
||||
/// Errors that can occur when interacting with override keys
|
||||
pub mod errors {
|
||||
use thiserror::Error;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
lockfile::{DependencyGraph, DependencyGraphNode},
|
||||
manifest::DependencyType,
|
||||
manifest::{overrides::OverrideSpecifier, DependencyType},
|
||||
names::PackageNames,
|
||||
source::{
|
||||
pesde::PesdePackageSource,
|
||||
|
@ -72,9 +72,12 @@ impl Project {
|
|||
.await
|
||||
.map_err(|e| Box::new(e.into()))?;
|
||||
|
||||
let mut all_specifiers = manifest
|
||||
let all_current_dependencies = manifest
|
||||
.all_dependencies()
|
||||
.map_err(|e| Box::new(e.into()))?
|
||||
.map_err(|e| Box::new(e.into()))?;
|
||||
|
||||
let mut all_specifiers = all_current_dependencies
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|(alias, (spec, ty))| ((spec, ty), alias))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
@ -171,7 +174,7 @@ impl Project {
|
|||
spec,
|
||||
ty,
|
||||
None::<(PackageNames, VersionId)>,
|
||||
vec![alias.to_string()],
|
||||
vec![alias],
|
||||
false,
|
||||
manifest.target.kind(),
|
||||
)
|
||||
|
@ -384,7 +387,14 @@ impl Project {
|
|||
}
|
||||
|
||||
queue.push_back((
|
||||
overridden.cloned().unwrap_or(dependency_spec),
|
||||
match overridden {
|
||||
Some(OverrideSpecifier::Specifier(spec)) => spec.clone(),
|
||||
Some(OverrideSpecifier::Alias(alias)) => all_current_dependencies.get(alias)
|
||||
.map(|(spec, _)| spec)
|
||||
.ok_or_else(|| errors::DependencyGraphError::AliasNotFound(alias.clone()))?
|
||||
.clone(),
|
||||
None => dependency_spec,
|
||||
},
|
||||
dependency_ty,
|
||||
Some((name.clone(), target_version_id.clone())),
|
||||
path.iter()
|
||||
|
@ -454,5 +464,9 @@ pub mod errors {
|
|||
/// No matching version was found for a specifier
|
||||
#[error("no matching version found for {0}")]
|
||||
NoMatchingVersion(String),
|
||||
|
||||
/// An alias for an override was not found in the manifest
|
||||
#[error("alias `{0}` not found in manifest")]
|
||||
AliasNotFound(String),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue