Skip to content
This repository has been archived by the owner on Sep 21, 2024. It is now read-only.

feat: Do not proactively create directories when creating spheres via CLI. Fixes #599 #643

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions rust/noosphere-cli/src/native/commands/sphere/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use url::Url;
pub async fn sphere_create(owner_key: &str, workspace: &mut Workspace) -> Result<(Did, Mnemonic)> {
workspace.ensure_sphere_uninitialized()?;

let sphere_paths = SpherePaths::initialize(workspace.working_directory()).await?;
let sphere_paths = SpherePaths::new(workspace.working_directory());

let sphere_context_artifacts = SphereContextBuilder::default()
.create_sphere()
Expand Down Expand Up @@ -74,7 +74,7 @@ You will be asked to enter them if you ever need to transfer ownership of the sp
mnemonic
);

workspace.initialize(sphere_paths)?;
workspace.initialize(sphere_paths).await?;

Ok((sphere_identity.clone(), mnemonic.into()))
}
Expand Down Expand Up @@ -124,7 +124,7 @@ Type or paste the code here and press enter:"#
let cid = Cid::from_str(cid_string.trim())
.map_err(|_| anyhow!("Could not parse the authorization identity as a CID"))?;

let sphere_paths = SpherePaths::initialize(workspace.working_directory()).await?;
let sphere_paths = SpherePaths::new(workspace.working_directory());

{
let mut sphere_context = Arc::new(Mutex::new(
Expand All @@ -150,7 +150,7 @@ Type or paste the code here and press enter:"#
sphere_context.sync().await?;
}

workspace.initialize(sphere_paths)?;
workspace.initialize(sphere_paths).await?;
workspace.render(render_depth, true).await?;

// TODO(#103): Recovery path if the auth needs to change for some reason
Expand Down
25 changes: 12 additions & 13 deletions rust/noosphere-cli/src/native/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ impl SpherePaths {
path.is_absolute() && path.join(SPHERE_DIRECTORY).is_dir()
}

// Root is the path that contains the .sphere folder
fn new(root: &Path) -> Self {
/// Construct a new [SpherePaths] given a `root` path, a directory
/// that will contain a `.sphere` directory.
pub fn new(root: &Path) -> Self {
let sphere = root.join(SPHERE_DIRECTORY);

Self {
Expand All @@ -90,25 +91,23 @@ impl SpherePaths {
}
}

/// Initialize [SpherePaths] for a given root path. This has the effect of
/// Initialize [SpherePaths] given its root path. This has the effect of
/// creating the "private" directory hierarchy (starting from
/// [SPHERE_DIRECTORY] inside the root).
pub async fn initialize(root: &Path) -> Result<Self> {
if !root.is_absolute() {
pub async fn initialize(&self) -> Result<()> {
if !self.root.is_absolute() {
return Err(anyhow!(
"Must use an absolute path to initialize sphere directories; got {:?}",
root
self.root
));
}

let paths = Self::new(root);
std::fs::create_dir_all(&self.storage)?;
std::fs::create_dir_all(&self.content)?;
std::fs::create_dir_all(&self.peers)?;
std::fs::create_dir_all(&self.slugs)?;

std::fs::create_dir_all(&paths.storage)?;
std::fs::create_dir_all(&paths.content)?;
std::fs::create_dir_all(&paths.peers)?;
std::fs::create_dir_all(&paths.slugs)?;

Ok(paths)
Ok(())
}

/// Attempt to discover an existing workspace root by traversing ancestor
Expand Down
8 changes: 4 additions & 4 deletions rust/noosphere-cli/src/native/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl Workspace {
}
}

/// Asserts that a local sphere has been intiialized
/// Asserts that a local sphere has been initialized
pub fn ensure_sphere_initialized(&self) -> Result<()> {
let sphere_paths = self.require_sphere_paths()?;
if !sphere_paths.sphere().exists() {
Expand All @@ -150,7 +150,7 @@ impl Workspace {
Ok(())
}

/// Asserts that a local sphere has _not_ been intiialized
/// Asserts that a local sphere has _not_ been initialized
pub fn ensure_sphere_uninitialized(&self) -> Result<()> {
if let Some(sphere_paths) = self.sphere_paths() {
match sphere_paths.sphere().exists() {
Expand Down Expand Up @@ -291,11 +291,11 @@ impl Workspace {
}

/// Initialize a [Workspace] in place with a given set of [SpherePaths].
pub fn initialize(&mut self, sphere_paths: SpherePaths) -> Result<()> {
pub async fn initialize(&mut self, sphere_paths: SpherePaths) -> Result<()> {
self.ensure_sphere_uninitialized()?;

sphere_paths.initialize().await?;
self.sphere_paths = Some(Arc::new(sphere_paths));

Ok(())
}

Expand Down
22 changes: 22 additions & 0 deletions rust/noosphere/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ async fn orb_sphere_create_initializes_a_sphere() -> Result<()> {
Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn orb_sphere_create_failure_cleans_directory() -> Result<()> {
initialize_tracing(None);
let client = CliSimulator::new()?;

client.orb(&["key", "create", "foobar"]).await?;
if client
.orb(&["sphere", "create", "--owner-key", "not-foo"])
.await
.is_ok()
{
panic!("Unexpected success.");
}

assert!(client
.orb(&["sphere", "create", "--owner-key", "foobar"])
.await
.is_ok());

Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn orb_can_enable_multiple_replicas_to_synchronize() -> Result<()> {
initialize_tracing(None);
Expand Down