Skip to content

Commit

Permalink
Support to override dependencies with local path
Browse files Browse the repository at this point in the history
  • Loading branch information
dalance committed Jan 20, 2025
1 parent 908103f commit 7bed62a
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 35 deletions.
91 changes: 57 additions & 34 deletions crates/metadata/src/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct Lock {
pub version: Version,
pub url: UrlPath,
pub revision: String,
pub path: Option<PathBuf>,
pub dependencies: Vec<LockDependency>,
#[serde(skip)]
used: bool,
Expand Down Expand Up @@ -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
};
Expand Down Expand Up @@ -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)? {
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -288,6 +289,7 @@ impl Lockfile {
version: release.version,
url: url.clone(),
revision: release.revision,
path,
dependencies,
used: true,
};
Expand All @@ -311,21 +313,21 @@ impl Lockfile {
&mut self,
url: &UrlPath,
dep: &Dependency,
) -> Result<Vec<(Release, Option<String>)>, MetadataError> {
) -> Result<Vec<(Release, Option<String>, Option<PathBuf>)>, 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
}
Expand Down Expand Up @@ -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<Metadata, MetadataError> {
let dependencies_dir = veryl_path::cache_path().join("dependencies");
fn get_metadata(
&self,
url: &UrlPath,
revision: &str,
path: &Option<PathBuf>,
) -> Result<Metadata, MetadataError> {
// 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)
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/metadata/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>,
pub path: Option<PathBuf>,
}

0 comments on commit 7bed62a

Please sign in to comment.