Skip to content

Commit 273114c

Browse files
author
Eric Swanson
committed
refactor: ProjectDirectory, NetworkDirectory
These encapsulate operations on files or directories within a project or network, respectively. ProjectDirectoryStructure and NetworkDirectoryStructure continue to provide only paths.
1 parent 7742917 commit 273114c

File tree

8 files changed

+110
-47
lines changed

8 files changed

+110
-47
lines changed

bin/icp-cli/src/commands/network/run.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::commands::network::run::RunNetworkCommandError::ProjectStructureNotFound;
2-
use crate::project::structure::ProjectDirectoryStructure;
1+
use crate::commands::network::run::RunNetworkCommandError::ProjectNotFound;
2+
use crate::project::directory::ProjectDirectory;
33
use clap::Parser;
44
use icp_network::{ManagedNetworkModel, RunNetworkError, run_network};
55
use snafu::Snafu;
@@ -10,21 +10,21 @@ pub struct Cmd {}
1010

1111
pub async fn exec(_cmd: Cmd) -> Result<(), RunNetworkCommandError> {
1212
let config = ManagedNetworkModel::default();
13-
let pds = ProjectDirectoryStructure::find().ok_or(ProjectStructureNotFound)?;
14-
let nds = pds.network("local");
13+
let pd = ProjectDirectory::find().ok_or(ProjectNotFound)?;
14+
let nd = pd.network("local");
1515

16-
eprintln!("Project root: {}", pds.root().display());
17-
eprintln!("Network root: {}", nds.network_root().display());
16+
eprintln!("Project root: {}", pd.structure().root().display());
17+
eprintln!("Network root: {}", nd.structure().network_root().display());
1818

19-
run_network(config, nds).await?;
19+
run_network(config, nd).await?;
2020

2121
Ok(())
2222
}
2323

2424
#[derive(Debug, Snafu)]
2525
pub enum RunNetworkCommandError {
2626
#[snafu(display("no project (icp.yaml) found in current directory or its parents"))]
27-
ProjectStructureNotFound,
27+
ProjectNotFound,
2828

2929
#[snafu(transparent)]
3030
NetworkExecutionFailed { source: RunNetworkError },

bin/icp-cli/src/project.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
pub mod directory;
12
pub mod structure;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use crate::project::structure::ProjectDirectoryStructure;
2+
use icp_network::NetworkDirectory;
3+
4+
pub struct ProjectDirectory {
5+
structure: ProjectDirectoryStructure,
6+
}
7+
8+
impl ProjectDirectory {
9+
pub fn find() -> Option<Self> {
10+
let current_dir = std::env::current_dir().ok()?;
11+
let mut path = current_dir.clone();
12+
loop {
13+
let structure = ProjectDirectoryStructure::new(&path);
14+
15+
if structure.project_yaml_path().exists() {
16+
break Some(Self { structure });
17+
}
18+
if !path.pop() {
19+
break None;
20+
}
21+
}
22+
}
23+
24+
pub fn structure(&self) -> &ProjectDirectoryStructure {
25+
&self.structure
26+
}
27+
28+
pub fn network(&self, network_name: &str) -> NetworkDirectory {
29+
let network_root = self.structure.network_root(network_name);
30+
NetworkDirectory::new(&network_root)
31+
}
32+
}
Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,23 @@
1-
use icp_network::structure::NetworkDirectoryStructure;
2-
use std::path::PathBuf;
1+
use std::path::{Path, PathBuf};
32

43
pub struct ProjectDirectoryStructure {
54
root: PathBuf,
65
}
76

87
impl ProjectDirectoryStructure {
9-
pub fn find() -> Option<Self> {
10-
let current_dir = std::env::current_dir().ok()?;
11-
let mut path = current_dir.clone();
12-
loop {
13-
if path.join("icp.yaml").exists() {
14-
break Some(Self { root: path });
15-
}
16-
if !path.pop() {
17-
break None;
18-
}
19-
}
8+
pub fn new(root: &Path) -> Self {
9+
let root = root.to_path_buf();
10+
Self { root }
2011
}
2112

2213
pub fn root(&self) -> &PathBuf {
2314
&self.root
2415
}
2516

17+
pub fn project_yaml_path(&self) -> PathBuf {
18+
self.root.join("icp.yaml")
19+
}
20+
2621
#[allow(dead_code)]
2722
pub fn network_config_path(&self, name: &str) -> PathBuf {
2823
self.root.join("networks").join(format!("{name}.yaml"))
@@ -32,9 +27,7 @@ impl ProjectDirectoryStructure {
3227
self.root.join(".icp")
3328
}
3429

35-
pub fn network(&self, network_name: &str) -> NetworkDirectoryStructure {
36-
let network_root = self.work_dir().join("networks").join(network_name);
37-
38-
NetworkDirectoryStructure::new(&network_root)
30+
pub fn network_root(&self, network_name: &str) -> PathBuf {
31+
self.work_dir().join("networks").join(network_name)
3932
}
4033
}

lib/icp-network/src/directory.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::structure::NetworkDirectoryStructure;
2+
use fd_lock::RwLock;
3+
use icp_fs::fs::{CreateDirAllError, create_dir_all};
4+
use snafu::prelude::*;
5+
use std::fs::{File, OpenOptions};
6+
use std::path::{Path, PathBuf};
7+
8+
pub struct NetworkDirectory {
9+
structure: NetworkDirectoryStructure,
10+
}
11+
12+
impl NetworkDirectory {
13+
pub fn new(network_root: &Path) -> Self {
14+
let structure = NetworkDirectoryStructure::new(network_root);
15+
Self { structure }
16+
}
17+
18+
pub fn structure(&self) -> &NetworkDirectoryStructure {
19+
&self.structure
20+
}
21+
22+
pub fn ensure_exists(&self) -> Result<(), CreateDirAllError> {
23+
create_dir_all(self.structure.network_root())
24+
}
25+
26+
pub fn open_lock_file(&self) -> Result<RwLock<File>, OpenLockFileError> {
27+
let path = self.structure.lock_path();
28+
let rwlock = RwLock::new(
29+
OpenOptions::new()
30+
.create(true)
31+
.write(true)
32+
.read(true)
33+
.truncate(true)
34+
.open(&path)
35+
.context(OpenLockFileSnafu { path })?,
36+
);
37+
Ok(rwlock)
38+
}
39+
}
40+
41+
#[derive(Debug, Snafu)]
42+
#[snafu(display("failed to open lock file at {}", path.display(),))]
43+
pub struct OpenLockFileError {
44+
source: std::io::Error,
45+
path: PathBuf,
46+
}

lib/icp-network/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
pub mod config;
2+
mod directory;
23
mod managed;
34
pub mod status;
45
pub mod structure;
56

67
pub use config::model::managed::ManagedNetworkModel;
78
pub use config::model::network_config::NetworkConfig;
9+
pub use directory::NetworkDirectory;
810
pub use managed::run::RunNetworkError;
911
pub use managed::run::run_network;

lib/icp-network/src/managed/run.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use crate::RunNetworkError::NoPocketIcPath;
22
use crate::config::model::managed::ManagedNetworkModel;
33
use crate::config::model::network_descriptor::NetworkDescriptorModel;
4+
use crate::directory::OpenLockFileError;
45
use crate::managed::pocketic::admin::{
56
CreateHttpGatewayError, CreateInstanceError, PocketIcAdminInterface,
67
};
78
use crate::managed::pocketic::instance::PocketIcInstance;
89
use crate::managed::pocketic::native::spawn_pocketic;
910
use crate::managed::run::InitializePocketicError::NoRootKey;
10-
use crate::status;
1111
use crate::structure::NetworkDirectoryStructure;
12-
use fd_lock::RwLock;
12+
use crate::{NetworkDirectory, status};
1313
use icp_fs::fs::{
1414
CreateDirAllError, RemoveDirAllError, RemoveFileError, create_dir_all, remove_dir_all,
1515
remove_file,
@@ -19,7 +19,7 @@ use pocket_ic::common::rest::HttpGatewayBackend;
1919
use reqwest::Url;
2020
use snafu::prelude::*;
2121
use std::env::var_os;
22-
use std::fs::{OpenOptions, read_to_string};
22+
use std::fs::read_to_string;
2323
use std::path::{Path, PathBuf};
2424
use std::process::ExitStatus;
2525
use std::time::Duration;
@@ -31,27 +31,18 @@ use uuid::Uuid;
3131

3232
pub async fn run_network(
3333
config: ManagedNetworkModel,
34-
nds: NetworkDirectoryStructure,
34+
nd: NetworkDirectory,
3535
) -> Result<(), RunNetworkError> {
3636
let pocketic_path = PathBuf::from(var_os("ICP_POCKET_IC_PATH").ok_or(NoPocketIcPath)?);
3737

38-
create_dir_all(nds.network_root())?;
38+
nd.ensure_exists()?;
3939

40-
let mut file = RwLock::new(
41-
OpenOptions::new()
42-
.create(true)
43-
.write(true)
44-
.read(true)
45-
.truncate(true)
46-
.open(nds.lock_path())
47-
.map_err(|source| RunNetworkError::OpenLockFile { source })?,
48-
);
40+
let mut file = nd.open_lock_file()?;
4941
let _guard = file
5042
.try_write()
5143
.map_err(|_| RunNetworkError::AlreadyRunningThisProject)?;
52-
eprintln!("Holding lock on {}", nds.lock_path().display());
5344

54-
run_pocketic(&pocketic_path, config, nds).await?;
45+
run_pocketic(&pocketic_path, config, nd.structure()).await?;
5546
Ok(())
5647
}
5748

@@ -66,17 +57,17 @@ pub enum RunNetworkError {
6657
#[snafu(display("ICP_POCKET_IC_PATH environment variable is not set"))]
6758
NoPocketIcPath,
6859

69-
#[snafu(display("failed to open lock file"))]
70-
OpenLockFile { source: std::io::Error },
60+
#[snafu(transparent)]
61+
OpenLockFile { source: OpenLockFileError },
7162

7263
#[snafu(transparent)]
73-
RunPocketIcError { source: RunPocketIcError },
64+
RunPocketIc { source: RunPocketIcError },
7465
}
7566

7667
async fn run_pocketic(
7768
pocketic_path: &Path,
7869
_config: ManagedNetworkModel,
79-
nds: NetworkDirectoryStructure,
70+
nds: &NetworkDirectoryStructure,
8071
) -> Result<(), RunPocketIcError> {
8172
eprintln!("PocketIC path: {}", pocketic_path.display());
8273

lib/icp-network/src/structure.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ pub struct NetworkDirectoryStructure {
44
pub network_root: PathBuf,
55
}
66

7-
impl NetworkDirectoryStructure {}
8-
97
impl NetworkDirectoryStructure {
108
pub fn new(network_root: &Path) -> Self {
119
let network_root = network_root.to_path_buf();

0 commit comments

Comments
 (0)