mirror of
https://github.com/pesde-pkg/pesde.git
synced 2024-12-12 11:00:36 +00:00
feat: support adding workspace packages
This commit is contained in:
parent
5236be53fd
commit
71eacb8673
6 changed files with 168 additions and 99 deletions
|
@ -4,7 +4,7 @@ use anyhow::Context;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use semver::VersionReq;
|
use semver::VersionReq;
|
||||||
|
|
||||||
use crate::cli::{config::read_config, NamedVersionable, VersionedPackageName};
|
use crate::cli::{config::read_config, AnyPackageIdentifier, VersionedPackageName};
|
||||||
use pesde::{
|
use pesde::{
|
||||||
manifest::target::TargetKind,
|
manifest::target::TargetKind,
|
||||||
names::PackageNames,
|
names::PackageNames,
|
||||||
|
@ -13,6 +13,7 @@ use pesde::{
|
||||||
pesde::{specifier::PesdeDependencySpecifier, PesdePackageSource},
|
pesde::{specifier::PesdeDependencySpecifier, PesdePackageSource},
|
||||||
specifiers::DependencySpecifiers,
|
specifiers::DependencySpecifiers,
|
||||||
traits::PackageSource,
|
traits::PackageSource,
|
||||||
|
workspace::WorkspacePackageSource,
|
||||||
PackageSources,
|
PackageSources,
|
||||||
},
|
},
|
||||||
Project, DEFAULT_INDEX_NAME,
|
Project, DEFAULT_INDEX_NAME,
|
||||||
|
@ -22,7 +23,7 @@ use pesde::{
|
||||||
pub struct AddCommand {
|
pub struct AddCommand {
|
||||||
/// The package name to add
|
/// The package name to add
|
||||||
#[arg(index = 1)]
|
#[arg(index = 1)]
|
||||||
name: NamedVersionable<VersionReq>,
|
name: AnyPackageIdentifier<VersionReq>,
|
||||||
|
|
||||||
/// The index in which to search for the package
|
/// The index in which to search for the package
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
|
@ -52,7 +53,7 @@ impl AddCommand {
|
||||||
.context("failed to read manifest")?;
|
.context("failed to read manifest")?;
|
||||||
|
|
||||||
let (source, specifier) = match &self.name {
|
let (source, specifier) = match &self.name {
|
||||||
NamedVersionable::PackageName(versioned) => match &versioned {
|
AnyPackageIdentifier::PackageName(versioned) => match &versioned {
|
||||||
VersionedPackageName(PackageNames::Pesde(name), version) => {
|
VersionedPackageName(PackageNames::Pesde(name), version) => {
|
||||||
let index = manifest
|
let index = manifest
|
||||||
.indices
|
.indices
|
||||||
|
@ -103,7 +104,7 @@ impl AddCommand {
|
||||||
(source, specifier)
|
(source, specifier)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NamedVersionable::Url((url, rev)) => (
|
AnyPackageIdentifier::Url((url, rev)) => (
|
||||||
PackageSources::Git(GitPackageSource::new(url.clone())),
|
PackageSources::Git(GitPackageSource::new(url.clone())),
|
||||||
DependencySpecifiers::Git(GitDependencySpecifier {
|
DependencySpecifiers::Git(GitDependencySpecifier {
|
||||||
repo: url.clone(),
|
repo: url.clone(),
|
||||||
|
@ -111,6 +112,15 @@ impl AddCommand {
|
||||||
path: None,
|
path: None,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
AnyPackageIdentifier::Workspace(VersionedPackageName(name, version)) => (
|
||||||
|
PackageSources::Workspace(WorkspacePackageSource),
|
||||||
|
DependencySpecifiers::Workspace(
|
||||||
|
pesde::source::workspace::specifier::WorkspaceDependencySpecifier {
|
||||||
|
name: name.clone(),
|
||||||
|
version_type: version.unwrap_or_default(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
};
|
};
|
||||||
source
|
source
|
||||||
.refresh(&project)
|
.refresh(&project)
|
||||||
|
@ -141,15 +151,16 @@ impl AddCommand {
|
||||||
"dependencies"
|
"dependencies"
|
||||||
};
|
};
|
||||||
|
|
||||||
let alias = self.alias.unwrap_or_else(|| match self.name {
|
let alias = self.alias.unwrap_or_else(|| match self.name.clone() {
|
||||||
NamedVersionable::PackageName(versioned) => versioned.0.as_str().1.to_string(),
|
AnyPackageIdentifier::PackageName(versioned) => versioned.0.as_str().1.to_string(),
|
||||||
NamedVersionable::Url((url, _)) => url
|
AnyPackageIdentifier::Url((url, _)) => url
|
||||||
.path
|
.path
|
||||||
.to_string()
|
.to_string()
|
||||||
.split('/')
|
.split('/')
|
||||||
.last()
|
.last()
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.unwrap_or(url.path.to_string()),
|
.unwrap_or(url.path.to_string()),
|
||||||
|
AnyPackageIdentifier::Workspace(versioned) => versioned.0.as_str().1.to_string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let field = &mut manifest[dependency_key]
|
let field = &mut manifest[dependency_key]
|
||||||
|
@ -198,7 +209,19 @@ impl AddCommand {
|
||||||
|
|
||||||
println!("added git {}#{} to {}", spec.repo, spec.rev, dependency_key);
|
println!("added git {}#{} to {}", spec.repo, spec.rev, dependency_key);
|
||||||
}
|
}
|
||||||
DependencySpecifiers::Workspace(_) => todo!(),
|
DependencySpecifiers::Workspace(spec) => {
|
||||||
|
field["workspace"] = toml_edit::value(spec.name.clone().to_string());
|
||||||
|
if let AnyPackageIdentifier::Workspace(versioned) = self.name {
|
||||||
|
if let Some(version) = versioned.1 {
|
||||||
|
field["version"] = toml_edit::value(version.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"added workspace {}@{} to {}",
|
||||||
|
spec.name, spec.version_type, dependency_key
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::cli::{bin_dir, files::make_executable, IsUpToDate};
|
use crate::cli::{bin_dir, files::make_executable};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
|
use colored::{ColoredString, Colorize};
|
||||||
use indicatif::MultiProgress;
|
use indicatif::MultiProgress;
|
||||||
use pesde::{lockfile::Lockfile, manifest::target::TargetKind, Project, MANIFEST_FILE_NAME};
|
use pesde::{lockfile::Lockfile, manifest::target::TargetKind, Project, MANIFEST_FILE_NAME};
|
||||||
use relative_path::RelativePathBuf;
|
use relative_path::RelativePathBuf;
|
||||||
|
@ -70,6 +71,15 @@ end
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "patches")]
|
||||||
|
const JOBS: u8 = 6;
|
||||||
|
#[cfg(not(feature = "patches"))]
|
||||||
|
const JOBS: u8 = 5;
|
||||||
|
|
||||||
|
fn job(n: u8) -> ColoredString {
|
||||||
|
format!("[{n}/{JOBS}]").dimmed().bold()
|
||||||
|
}
|
||||||
|
|
||||||
impl InstallCommand {
|
impl InstallCommand {
|
||||||
pub fn run(
|
pub fn run(
|
||||||
self,
|
self,
|
||||||
|
@ -85,12 +95,19 @@ impl InstallCommand {
|
||||||
|
|
||||||
let lockfile = if self.unlocked {
|
let lockfile = if self.unlocked {
|
||||||
None
|
None
|
||||||
} else if project
|
} else {
|
||||||
.is_up_to_date(false)
|
|
||||||
.context("failed to check if project is up to date")?
|
|
||||||
{
|
|
||||||
match project.deser_lockfile() {
|
match project.deser_lockfile() {
|
||||||
Ok(lockfile) => Some(lockfile),
|
Ok(lockfile) => {
|
||||||
|
if lockfile.overrides != manifest.overrides {
|
||||||
|
log::debug!("overrides are different");
|
||||||
|
None
|
||||||
|
} else if lockfile.target != manifest.target.kind() {
|
||||||
|
log::debug!("target kind is different");
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(lockfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(pesde::errors::LockfileReadError::Io(e))
|
Err(pesde::errors::LockfileReadError::Io(e))
|
||||||
if e.kind() == std::io::ErrorKind::NotFound =>
|
if e.kind() == std::io::ErrorKind::NotFound =>
|
||||||
{
|
{
|
||||||
|
@ -98,10 +115,17 @@ impl InstallCommand {
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"\n{}\n",
|
||||||
|
format!("[now installing {}]", manifest.name)
|
||||||
|
.bold()
|
||||||
|
.on_bright_black()
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("{} ❌ removing current package folders", job(1));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut deleted_folders = HashSet::new();
|
let mut deleted_folders = HashSet::new();
|
||||||
|
|
||||||
|
@ -137,6 +161,8 @@ impl InstallCommand {
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
println!("{} 📦 building dependency graph", job(2));
|
||||||
|
|
||||||
let graph = project
|
let graph = project
|
||||||
.dependency_graph(old_graph.as_ref(), &mut refreshed_sources)
|
.dependency_graph(old_graph.as_ref(), &mut refreshed_sources)
|
||||||
.context("failed to build dependency graph")?;
|
.context("failed to build dependency graph")?;
|
||||||
|
@ -148,7 +174,7 @@ impl InstallCommand {
|
||||||
"{msg} {bar:40.208/166} {pos}/{len} {percent}% {elapsed_precise}",
|
"{msg} {bar:40.208/166} {pos}/{len} {percent}% {elapsed_precise}",
|
||||||
)?,
|
)?,
|
||||||
)
|
)
|
||||||
.with_message(format!("downloading dependencies of {}", manifest.name)),
|
.with_message(format!("{} 📥 downloading dependencies", job(3))),
|
||||||
);
|
);
|
||||||
bar.enable_steady_tick(Duration::from_millis(100));
|
bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
|
||||||
|
@ -170,25 +196,19 @@ impl InstallCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bar.finish_with_message(format!(
|
bar.finish_with_message(format!("{} 📥 downloaded dependencies", job(3),));
|
||||||
"finished downloading dependencies of {}",
|
|
||||||
manifest.name
|
|
||||||
));
|
|
||||||
|
|
||||||
let downloaded_graph = Arc::into_inner(downloaded_graph)
|
let downloaded_graph = Arc::into_inner(downloaded_graph)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
println!("{} 🗺️ linking dependencies", job(4));
|
||||||
|
|
||||||
project
|
project
|
||||||
.link_dependencies(&downloaded_graph)
|
.link_dependencies(&downloaded_graph)
|
||||||
.context("failed to link dependencies")?;
|
.context("failed to link dependencies")?;
|
||||||
|
|
||||||
#[cfg(feature = "patches")]
|
|
||||||
project
|
|
||||||
.apply_patches(&downloaded_graph)
|
|
||||||
.context("failed to apply patches")?;
|
|
||||||
|
|
||||||
let bin_folder = bin_dir()?;
|
let bin_folder = bin_dir()?;
|
||||||
|
|
||||||
for versions in downloaded_graph.values() {
|
for versions in downloaded_graph.values() {
|
||||||
|
@ -224,6 +244,17 @@ impl InstallCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "patches")]
|
||||||
|
{
|
||||||
|
println!("{} 🩹 applying patches", job(5));
|
||||||
|
|
||||||
|
project
|
||||||
|
.apply_patches(&downloaded_graph)
|
||||||
|
.context("failed to apply patches")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{} 🧹 finishing up", job(JOBS));
|
||||||
|
|
||||||
project
|
project
|
||||||
.write_lockfile(Lockfile {
|
.write_lockfile(Lockfile {
|
||||||
name: manifest.name,
|
name: manifest.name,
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use crate::cli::{IsUpToDate, VersionedPackageName};
|
use crate::cli::{up_to_date_lockfile, VersionedPackageName};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use pesde::{
|
use pesde::{
|
||||||
patches::setup_patches_repo,
|
patches::setup_patches_repo,
|
||||||
source::traits::{PackageRef, PackageSource},
|
source::{
|
||||||
|
refs::PackageRefs,
|
||||||
|
traits::{PackageRef, PackageSource},
|
||||||
|
},
|
||||||
Project, MANIFEST_FILE_NAME,
|
Project, MANIFEST_FILE_NAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,8 +20,8 @@ pub struct PatchCommand {
|
||||||
|
|
||||||
impl PatchCommand {
|
impl PatchCommand {
|
||||||
pub fn run(self, project: Project, reqwest: reqwest::blocking::Client) -> anyhow::Result<()> {
|
pub fn run(self, project: Project, reqwest: reqwest::blocking::Client) -> anyhow::Result<()> {
|
||||||
let graph = if project.is_up_to_date(true)? {
|
let graph = if let Some(lockfile) = up_to_date_lockfile(&project)? {
|
||||||
project.deser_lockfile()?.graph
|
lockfile.graph
|
||||||
} else {
|
} else {
|
||||||
anyhow::bail!("outdated lockfile, please run the install command first")
|
anyhow::bail!("outdated lockfile, please run the install command first")
|
||||||
};
|
};
|
||||||
|
@ -29,6 +32,11 @@ impl PatchCommand {
|
||||||
.get(&name)
|
.get(&name)
|
||||||
.and_then(|versions| versions.get(&version_id))
|
.and_then(|versions| versions.get(&version_id))
|
||||||
.context("package not found in graph")?;
|
.context("package not found in graph")?;
|
||||||
|
|
||||||
|
if matches!(node.node.pkg_ref, PackageRefs::Workspace(_)) {
|
||||||
|
anyhow::bail!("cannot patch a workspace package")
|
||||||
|
}
|
||||||
|
|
||||||
let source = node.node.pkg_ref.source();
|
let source = node.node.pkg_ref.source();
|
||||||
|
|
||||||
let directory = project
|
let directory = project
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::cli::IsUpToDate;
|
use crate::cli::up_to_date_lockfile;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use pesde::{names::PackageNames, patches::create_patch, source::version_id::VersionId, Project};
|
use pesde::{names::PackageNames, patches::create_patch, source::version_id::VersionId, Project};
|
||||||
|
@ -13,8 +13,8 @@ pub struct PatchCommitCommand {
|
||||||
|
|
||||||
impl PatchCommitCommand {
|
impl PatchCommitCommand {
|
||||||
pub fn run(self, project: Project) -> anyhow::Result<()> {
|
pub fn run(self, project: Project) -> anyhow::Result<()> {
|
||||||
let graph = if project.is_up_to_date(true)? {
|
let graph = if let Some(lockfile) = up_to_date_lockfile(&project)? {
|
||||||
project.deser_lockfile()?.graph
|
lockfile.graph
|
||||||
} else {
|
} else {
|
||||||
anyhow::bail!("outdated lockfile, please run the install command first")
|
anyhow::bail!("outdated lockfile, please run the install command first")
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Context;
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use relative_path::RelativePathBuf;
|
use relative_path::RelativePathBuf;
|
||||||
|
|
||||||
use crate::cli::IsUpToDate;
|
use crate::cli::up_to_date_lockfile;
|
||||||
use pesde::{
|
use pesde::{
|
||||||
names::{PackageName, PackageNames},
|
names::{PackageName, PackageNames},
|
||||||
source::traits::PackageRef,
|
source::traits::PackageRef,
|
||||||
|
@ -49,8 +49,8 @@ impl RunCommand {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(pkg_name) = package_or_script.parse::<PackageName>() {
|
if let Ok(pkg_name) = package_or_script.parse::<PackageName>() {
|
||||||
let graph = if project.is_up_to_date(true)? {
|
let graph = if let Some(lockfile) = up_to_date_lockfile(&project)? {
|
||||||
project.deser_lockfile()?.graph
|
lockfile.graph
|
||||||
} else {
|
} else {
|
||||||
anyhow::bail!("outdated lockfile, please run the install command first")
|
anyhow::bail!("outdated lockfile, please run the install command first")
|
||||||
};
|
};
|
||||||
|
|
133
src/cli/mod.rs
133
src/cli/mod.rs
|
@ -1,7 +1,11 @@
|
||||||
|
use crate::cli::auth::get_token;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use gix::bstr::BStr;
|
use gix::bstr::BStr;
|
||||||
use pesde::{
|
use pesde::{
|
||||||
lockfile::DownloadedGraph, names::PackageNames, source::version_id::VersionId, Project,
|
lockfile::{DownloadedGraph, Lockfile},
|
||||||
|
names::{PackageName, PackageNames},
|
||||||
|
source::{version_id::VersionId, workspace::specifier::VersionType},
|
||||||
|
Project,
|
||||||
};
|
};
|
||||||
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serializer};
|
use serde::{ser::SerializeMap, Deserialize, Deserializer, Serializer};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -10,8 +14,6 @@ use std::{
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::cli::auth::get_token;
|
|
||||||
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
@ -33,62 +35,58 @@ pub fn bin_dir() -> anyhow::Result<std::path::PathBuf> {
|
||||||
Ok(bin_dir)
|
Ok(bin_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IsUpToDate {
|
pub fn up_to_date_lockfile(project: &Project) -> anyhow::Result<Option<Lockfile>> {
|
||||||
fn is_up_to_date(&self, strict: bool) -> anyhow::Result<bool>;
|
let manifest = project.deser_manifest()?;
|
||||||
}
|
let lockfile = match project.deser_lockfile() {
|
||||||
|
Ok(lockfile) => lockfile,
|
||||||
impl IsUpToDate for Project {
|
Err(pesde::errors::LockfileReadError::Io(e))
|
||||||
fn is_up_to_date(&self, strict: bool) -> anyhow::Result<bool> {
|
if e.kind() == std::io::ErrorKind::NotFound =>
|
||||||
let manifest = self.deser_manifest()?;
|
{
|
||||||
let lockfile = match self.deser_lockfile() {
|
return Ok(None);
|
||||||
Ok(lockfile) => lockfile,
|
|
||||||
Err(pesde::errors::LockfileReadError::Io(e))
|
|
||||||
if e.kind() == std::io::ErrorKind::NotFound =>
|
|
||||||
{
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
Err(e) => return Err(e.into()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if manifest.overrides != lockfile.overrides {
|
|
||||||
log::debug!("overrides are different");
|
|
||||||
return Ok(false);
|
|
||||||
}
|
}
|
||||||
|
Err(e) => return Err(e.into()),
|
||||||
|
};
|
||||||
|
|
||||||
if manifest.target.kind() != lockfile.target {
|
if manifest.overrides != lockfile.overrides {
|
||||||
log::debug!("target kind is different");
|
log::debug!("overrides are different");
|
||||||
return Ok(false);
|
return Ok(None);
|
||||||
}
|
|
||||||
|
|
||||||
if !strict {
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if manifest.name != lockfile.name || manifest.version != lockfile.version {
|
|
||||||
log::debug!("name or version is different");
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
let specs = lockfile
|
|
||||||
.graph
|
|
||||||
.into_iter()
|
|
||||||
.flat_map(|(_, versions)| versions)
|
|
||||||
.filter_map(|(_, node)| match node.node.direct {
|
|
||||||
Some((_, spec)) => Some((spec, node.node.ty)),
|
|
||||||
None => None,
|
|
||||||
})
|
|
||||||
.collect::<HashSet<_>>();
|
|
||||||
|
|
||||||
let same_dependencies = manifest
|
|
||||||
.all_dependencies()
|
|
||||||
.context("failed to get all dependencies")?
|
|
||||||
.iter()
|
|
||||||
.all(|(_, (spec, ty))| specs.contains(&(spec.clone(), *ty)));
|
|
||||||
|
|
||||||
log::debug!("dependencies are the same: {same_dependencies}");
|
|
||||||
|
|
||||||
Ok(same_dependencies)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if manifest.target.kind() != lockfile.target {
|
||||||
|
log::debug!("target kind is different");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if manifest.name != lockfile.name || manifest.version != lockfile.version {
|
||||||
|
log::debug!("name or version is different");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let specs = lockfile
|
||||||
|
.graph
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, versions)| versions)
|
||||||
|
.filter_map(|(_, node)| {
|
||||||
|
node.node
|
||||||
|
.direct
|
||||||
|
.as_ref()
|
||||||
|
.map(|(_, spec)| (spec, node.node.ty))
|
||||||
|
})
|
||||||
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
|
let same_dependencies = manifest
|
||||||
|
.all_dependencies()
|
||||||
|
.context("failed to get all dependencies")?
|
||||||
|
.iter()
|
||||||
|
.all(|(_, (spec, ty))| specs.contains(&(spec, *ty)));
|
||||||
|
|
||||||
|
log::debug!("dependencies are the same: {same_dependencies}");
|
||||||
|
|
||||||
|
Ok(if same_dependencies {
|
||||||
|
Some(lockfile)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -143,28 +141,37 @@ impl VersionedPackageName {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum NamedVersionable<V: FromStr = VersionId, N: FromStr = PackageNames> {
|
enum AnyPackageIdentifier<V: FromStr = VersionId, N: FromStr = PackageNames> {
|
||||||
PackageName(VersionedPackageName<V, N>),
|
PackageName(VersionedPackageName<V, N>),
|
||||||
Url((gix::Url, String)),
|
Url((gix::Url, String)),
|
||||||
|
Workspace(VersionedPackageName<VersionType, PackageName>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: FromStr<Err = E>, E: Into<anyhow::Error>, N: FromStr<Err = F>, F: Into<anyhow::Error>>
|
impl<V: FromStr<Err = E>, E: Into<anyhow::Error>, N: FromStr<Err = F>, F: Into<anyhow::Error>>
|
||||||
FromStr for NamedVersionable<V, N>
|
FromStr for AnyPackageIdentifier<V, N>
|
||||||
{
|
{
|
||||||
type Err = anyhow::Error;
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
if s.contains("gh#") {
|
if let Some(s) = s.strip_prefix("gh#") {
|
||||||
let s = s.replacen("gh#", "https://github.com/", 1);
|
let s = format!("https://github.com/{s}");
|
||||||
let (repo, rev) = s.split_once('#').unwrap();
|
let (repo, rev) = s.split_once('#').unwrap();
|
||||||
|
|
||||||
Ok(NamedVersionable::Url((repo.try_into()?, rev.to_string())))
|
Ok(AnyPackageIdentifier::Url((
|
||||||
|
repo.try_into()?,
|
||||||
|
rev.to_string(),
|
||||||
|
)))
|
||||||
|
} else if let Some(rest) = s.strip_prefix("workspace:") {
|
||||||
|
Ok(AnyPackageIdentifier::Workspace(rest.parse()?))
|
||||||
} else if s.contains(':') {
|
} else if s.contains(':') {
|
||||||
let (url, rev) = s.split_once('#').unwrap();
|
let (url, rev) = s.split_once('#').unwrap();
|
||||||
|
|
||||||
Ok(NamedVersionable::Url((url.try_into()?, rev.to_string())))
|
Ok(AnyPackageIdentifier::Url((
|
||||||
|
url.try_into()?,
|
||||||
|
rev.to_string(),
|
||||||
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(NamedVersionable::PackageName(s.parse()?))
|
Ok(AnyPackageIdentifier::PackageName(s.parse()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue