From 7bed62ad5cf14e6709d735e29f0f339a0d83853e Mon Sep 17 00:00:00 2001 From: dalance Date: Mon, 20 Jan 2025 12:42:42 +0900 Subject: [PATCH] Support to override dependencies with local path --- crates/metadata/src/lockfile.rs | 91 +++++++++++++++++++++------------ crates/metadata/src/metadata.rs | 3 +- 2 files changed, 59 insertions(+), 35 deletions(-) diff --git a/crates/metadata/src/lockfile.rs b/crates/metadata/src/lockfile.rs index 98b7d32d..c1717f4f 100644 --- a/crates/metadata/src/lockfile.rs +++ b/crates/metadata/src/lockfile.rs @@ -32,6 +32,7 @@ pub struct Lock { pub version: Version, pub url: UrlPath, pub revision: String, + pub path: Option, pub dependencies: Vec, #[serde(skip)] used: bool, @@ -124,9 +125,9 @@ impl Lockfile { for lock in &locks { let add = if let Some(old_locks) = old_table.get(&lock.url) { - !old_locks - .iter() - .any(|x| x.version == lock.version && x.name == lock.name) + !old_locks.iter().any(|x| { + x.version == lock.version && x.name == lock.name && x.path == lock.path + }) } else { true }; @@ -163,7 +164,7 @@ impl Lockfile { for locks in self.lock_table.values() { for lock in locks { - let metadata = self.get_metadata(&lock.url, &lock.revision)?; + let metadata = self.get_metadata(&lock.url, &lock.revision, &lock.path)?; let path = metadata.project_path(); for src in &veryl_path::gather_files_with_extension(&path, "veryl", false)? { @@ -242,8 +243,8 @@ impl Lockfile { // breadth first search because root has top priority of name let mut dependencies_metadata = Vec::new(); for (url, dep) in &metadata.dependencies { - for (release, name) in self.resolve_dependency(url, dep)? { - let metadata = self.get_metadata(url, &release.revision)?; + for (release, name, path) in self.resolve_dependency(url, dep)? { + let metadata = self.get_metadata(url, &release.revision, &path)?; let mut name = name.unwrap_or(metadata.project.name.clone()); // avoid name conflict by adding suffix @@ -265,8 +266,8 @@ impl Lockfile { let mut dependencies = Vec::new(); for (url, dep) in &metadata.dependencies { - for (release, name) in self.resolve_dependency(url, dep)? { - let metadata = self.get_metadata(url, &release.revision)?; + for (release, name, path) in self.resolve_dependency(url, dep)? { + let metadata = self.get_metadata(url, &release.revision, &path)?; let name = name.unwrap_or(metadata.project.name.clone()); // project local name is not required to check name_table @@ -288,6 +289,7 @@ impl Lockfile { version: release.version, url: url.clone(), revision: release.revision, + path, dependencies, used: true, }; @@ -311,21 +313,21 @@ impl Lockfile { &mut self, url: &UrlPath, dep: &Dependency, - ) -> Result)>, MetadataError> { + ) -> Result, Option)>, MetadataError> { Ok(match dep { Dependency::Version(x) => { let release = self.resolve_version(url, x)?; - vec![(release, None)] + vec![(release, None, None)] } Dependency::Single(x) => { let release = self.resolve_version(url, &x.version)?; - vec![(release, Some(x.name.clone()))] + vec![(release, x.name.clone(), x.path.clone())] } Dependency::Multi(x) => { let mut ret = Vec::new(); for x in x { let release = self.resolve_version(url, &x.version)?; - ret.push((release, Some(x.name.clone()))); + ret.push((release, x.name.clone(), x.path.clone())); } ret } @@ -417,39 +419,60 @@ impl Lockfile { Ok(dependencies_dir.join(uuid.simple().encode_lower(&mut Uuid::encode_buffer()))) } - fn get_metadata(&self, url: &UrlPath, revision: &str) -> Result { - let dependencies_dir = veryl_path::cache_path().join("dependencies"); + fn get_metadata( + &self, + url: &UrlPath, + revision: &str, + path: &Option, + ) -> Result { + // Get metadata from local path + let path = path.as_ref().and_then(|x| { + let path = self.metadata_path.parent().unwrap().join(x); + let path = path.join("Veryl.toml"); + if path.exists() { + Some(path) + } else { + None + } + }); - if !dependencies_dir.exists() { - fs::create_dir_all(&dependencies_dir)?; - } + if let Some(path) = path { + let metadata = Metadata::load(path)?; + Ok(metadata) + } else { + let dependencies_dir = veryl_path::cache_path().join("dependencies"); - let path = Self::dependency_path(url, revision)?; - let toml = path.join("Veryl.toml"); + if !dependencies_dir.exists() { + fs::create_dir_all(&dependencies_dir)?; + } - if !path.exists() { - let lock = veryl_path::lock_dir("dependencies")?; - let git = self.git_clone(url, &path)?; - git.fetch()?; - git.checkout(Some(revision))?; - veryl_path::unlock_dir(lock)?; - } else { - let git = Git::open(&path)?; - let ret = git.is_clean().is_ok_and(|x| x); + let path = Self::dependency_path(url, revision)?; + let toml = path.join("Veryl.toml"); - // If the existing path is not git repository, cleanup and re-try - if !ret || !toml.exists() { + if !path.exists() { let lock = veryl_path::lock_dir("dependencies")?; - fs::remove_dir_all(&path)?; let git = self.git_clone(url, &path)?; git.fetch()?; git.checkout(Some(revision))?; veryl_path::unlock_dir(lock)?; + } else { + let git = Git::open(&path)?; + let ret = git.is_clean().is_ok_and(|x| x); + + // If the existing path is not git repository, cleanup and re-try + if !ret || !toml.exists() { + let lock = veryl_path::lock_dir("dependencies")?; + fs::remove_dir_all(&path)?; + let git = self.git_clone(url, &path)?; + git.fetch()?; + git.checkout(Some(revision))?; + veryl_path::unlock_dir(lock)?; + } } - } - let metadata = Metadata::load(toml)?; - Ok(metadata) + let metadata = Metadata::load(toml)?; + Ok(metadata) + } } } diff --git a/crates/metadata/src/metadata.rs b/crates/metadata/src/metadata.rs index 7c2349e9..f9da25f6 100644 --- a/crates/metadata/src/metadata.rs +++ b/crates/metadata/src/metadata.rs @@ -356,6 +356,7 @@ pub enum Dependency { #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct DependencyEntry { - pub name: String, pub version: VersionReq, + pub name: Option, + pub path: Option, }