mirror of
https://github.com/pesde-pkg/pesde.git
synced 2025-04-06 03:40:59 +01:00
129 lines
4.6 KiB
Rust
129 lines
4.6 KiB
Rust
use crate::cli::up_to_date_lockfile;
|
|
use anyhow::Context;
|
|
use clap::Args;
|
|
use futures::future::try_join_all;
|
|
use pesde::{
|
|
refresh_sources,
|
|
source::{
|
|
refs::PackageRefs,
|
|
specifiers::DependencySpecifiers,
|
|
traits::{PackageRef, PackageSource},
|
|
},
|
|
Project,
|
|
};
|
|
use semver::VersionReq;
|
|
use std::{collections::HashSet, sync::Arc};
|
|
use tokio::sync::Mutex;
|
|
|
|
#[derive(Debug, Args)]
|
|
pub struct OutdatedCommand {
|
|
/// Whether to check within version requirements
|
|
#[arg(short, long)]
|
|
strict: bool,
|
|
}
|
|
|
|
impl OutdatedCommand {
|
|
pub async fn run(self, project: Project) -> anyhow::Result<()> {
|
|
let graph = match up_to_date_lockfile(&project).await? {
|
|
Some(file) => file.graph,
|
|
None => {
|
|
anyhow::bail!(
|
|
"lockfile is out of sync, run `{} install` to update it",
|
|
env!("CARGO_BIN_NAME")
|
|
);
|
|
}
|
|
};
|
|
|
|
let manifest = project
|
|
.deser_manifest()
|
|
.await
|
|
.context("failed to read manifest")?;
|
|
let manifest_target_kind = manifest.target.kind();
|
|
|
|
let mut refreshed_sources = HashSet::new();
|
|
|
|
refresh_sources(
|
|
&project,
|
|
graph
|
|
.iter()
|
|
.flat_map(|(_, versions)| versions.iter())
|
|
.map(|(_, node)| node.node.pkg_ref.source()),
|
|
&mut refreshed_sources,
|
|
)
|
|
.await?;
|
|
|
|
let refreshed_sources = Arc::new(Mutex::new(refreshed_sources));
|
|
|
|
try_join_all(
|
|
graph
|
|
.into_iter()
|
|
.flat_map(|(_, versions)| versions.into_iter())
|
|
.map(|(current_version_id, node)| {
|
|
let project = project.clone();
|
|
let refreshed_sources = refreshed_sources.clone();
|
|
async move {
|
|
let Some((alias, mut specifier, _)) = node.node.direct else {
|
|
return Ok::<(), anyhow::Error>(());
|
|
};
|
|
|
|
if matches!(
|
|
specifier,
|
|
DependencySpecifiers::Git(_) | DependencySpecifiers::Workspace(_)
|
|
) {
|
|
return Ok(());
|
|
}
|
|
|
|
let source = node.node.pkg_ref.source();
|
|
|
|
if !self.strict {
|
|
match specifier {
|
|
DependencySpecifiers::Pesde(ref mut spec) => {
|
|
spec.version = VersionReq::STAR;
|
|
}
|
|
#[cfg(feature = "wally-compat")]
|
|
DependencySpecifiers::Wally(ref mut spec) => {
|
|
spec.version = VersionReq::STAR;
|
|
}
|
|
DependencySpecifiers::Git(_) => {}
|
|
DependencySpecifiers::Workspace(_) => {}
|
|
};
|
|
}
|
|
|
|
let version_id = source
|
|
.resolve(
|
|
&specifier,
|
|
&project,
|
|
manifest_target_kind,
|
|
&mut *refreshed_sources.lock().await,
|
|
)
|
|
.await
|
|
.context("failed to resolve package versions")?
|
|
.1
|
|
.pop_last()
|
|
.map(|(v_id, _)| v_id)
|
|
.context(format!("no versions of {specifier} found"))?;
|
|
|
|
if version_id != current_version_id {
|
|
println!(
|
|
"{} {} ({alias}) {} -> {}",
|
|
match node.node.pkg_ref {
|
|
PackageRefs::Pesde(pkg_ref) => pkg_ref.name.to_string(),
|
|
#[cfg(feature = "wally-compat")]
|
|
PackageRefs::Wally(pkg_ref) => pkg_ref.name.to_string(),
|
|
_ => unreachable!(),
|
|
},
|
|
current_version_id.target(),
|
|
current_version_id.version(),
|
|
version_id.version()
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}),
|
|
)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|