Skip to content

Commit

Permalink
Add Filesystem::into_child method for easier chaining (#782)
Browse files Browse the repository at this point in the history
**Stack**:
- #783
- #767
- #782⚠️ *Part of a stack created by [spr](https://github.com/ejoffe/spr). Do
not merge manually using the UI - doing so may have unexpected results.*
  • Loading branch information
mkaput authored Oct 11, 2023
1 parent 7e9d5c1 commit 675b504
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 16 deletions.
9 changes: 9 additions & 0 deletions scarb/src/flock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ impl<'a> Filesystem<'a> {
}
}

/// Like [`Utf8Path::join`], creates a new [`Filesystem`] rooted at a subdirectory of this one.
///
/// Unlike [`Filesystem::child`], this method consumes the current [`Filesystem`].
pub fn into_child(self, path: impl AsRef<Utf8Path>) -> Filesystem<'a> {
Filesystem {
root: self.root.into_child(path),
}
}

/// Get path to this [`Filesystem`] root without ensuring the path exists.
pub fn path_unchecked(&self) -> &Utf8Path {
self.root.as_unchecked()
Expand Down
40 changes: 34 additions & 6 deletions scarb/src/internal/lazy_directory_creator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ops::Deref;
use std::{fmt, path};

use anyhow::Result;
use camino::{Utf8Path, Utf8PathBuf};
use once_cell::sync::OnceCell;
use tracing::trace;
Expand All @@ -9,7 +11,7 @@ use crate::internal::fsx;
pub struct LazyDirectoryCreator<'p> {
path: Utf8PathBuf,
creation_lock: OnceCell<()>,
parent: Option<&'p LazyDirectoryCreator<'p>>,
parent: Option<Calf<'p, LazyDirectoryCreator<'p>>>,
is_output_dir: bool,
}

Expand All @@ -34,7 +36,16 @@ impl<'p> LazyDirectoryCreator<'p> {
Self {
path: self.path.join(path),
creation_lock: OnceCell::new(),
parent: Some(self),
parent: Some(Calf::Borrowed(self)),
is_output_dir: false,
}
}

pub fn into_child(self, path: impl AsRef<Utf8Path>) -> Self {
Self {
path: self.path.join(path),
creation_lock: OnceCell::new(),
parent: Some(Calf::Owned(Box::new(self))),
is_output_dir: false,
}
}
Expand All @@ -43,7 +54,7 @@ impl<'p> LazyDirectoryCreator<'p> {
&self.path
}

pub fn as_existent(&self) -> anyhow::Result<&Utf8Path> {
pub fn as_existent(&self) -> Result<&Utf8Path> {
self.ensure_created()?;
Ok(&self.path)
}
Expand All @@ -52,8 +63,8 @@ impl<'p> LazyDirectoryCreator<'p> {
self.is_output_dir
}

fn ensure_created(&self) -> anyhow::Result<()> {
if let Some(parent) = self.parent {
fn ensure_created(&self) -> Result<()> {
if let Some(parent) = &self.parent {
parent.ensure_created()?;
}

Expand Down Expand Up @@ -85,13 +96,14 @@ impl<'p> fmt::Debug for LazyDirectoryCreator<'p> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let base = self
.parent
.as_deref()
.map(|p| p.path.as_path())
.unwrap_or_else(|| Utf8Path::new(""));
if let Ok(stem) = self.path.strip_prefix(base) {
write!(f, "<{base}>{}{stem}", path::MAIN_SEPARATOR)?;
} else {
write!(f, "{}", self.path)?;
if let Some(parent) = self.parent {
if let Some(parent) = &self.parent {
write!(f, r#", parent: "{}""#, parent.path)?;
}
}
Expand All @@ -107,3 +119,19 @@ impl<'p> fmt::Debug for LazyDirectoryCreator<'p> {
Ok(())
}
}

enum Calf<'a, T> {
Borrowed(&'a T),
Owned(Box<T>),
}

impl<'a, T: 'a> Deref for Calf<'a, T> {
type Target = T;

fn deref(&self) -> &Self::Target {
match self {
Calf::Borrowed(t) => t,
Calf::Owned(t) => t,
}
}
}
17 changes: 10 additions & 7 deletions scarb/src/sources/git/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ impl<'c> GitSource<'c> {
) -> Result<InnerState<'_>> {
let remote_ident = remote.ident();

let registry_fs = config.dirs().registry_dir();
let git_fs = registry_fs.child("git");
let all_db_fs = git_fs.child("db");
let git_fs = config.dirs().registry_dir().into_child("git");

let db_fs = git_fs
.child("db")
.into_child(&format!("{remote_ident}.git"));

let db_fs = all_db_fs.child(&format!("{remote_ident}.git"));
let db = GitDatabase::open(&remote, &db_fs).ok();
let (db, actual_rev) = match (db, locked_rev) {
// If we have a locked revision, and we have a preexisting database
Expand Down Expand Up @@ -133,9 +134,11 @@ impl<'c> GitSource<'c> {
}
};

let all_checkouts_fs = git_fs.child("checkouts");
let db_checkouts_fs = all_checkouts_fs.child(&remote_ident);
let checkout_fs = db_checkouts_fs.child(db.short_id_of(actual_rev)?);
let checkout_fs = git_fs
.child("checkouts")
.into_child(&remote_ident)
.into_child(db.short_id_of(actual_rev)?);

let checkout = db.copy_to(&checkout_fs, actual_rev, config)?;
let source_id = source_id.with_precise(actual_rev.to_string())?;

Expand Down
10 changes: 7 additions & 3 deletions scarb/src/sources/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@ impl<'c> StandardLibSource<'c> {

let tag = core_version_tag();

let registry_fs = self.config.dirs().registry_dir();
let std_fs = registry_fs.child("std");
let tag_fs = std_fs.child(&tag);
let tag_fs = self
.config
.dirs()
.registry_dir()
.into_child("std")
.into_child(&tag);

let tag_path = tag_fs.path_existent()?;

// The following sequence of if statements & advisory locks implements a file system-based
Expand Down

0 comments on commit 675b504

Please sign in to comment.