radicle: canonicalize home path
If a path was passed to `Home` in non-canonical form it would not use the right path for any initialisation or use. The aim is to use the `canonicalize` function for paths. However, this may return an error if none of the paths exist. To ensure that the path exists the `new` constructor for `Home` creates the directory and canonicalizes the path. Since `new` now initialises the home directory, it would be useful if it also initialised all the necessary subdirectories -- which removes the need for the `init` method. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
a7d2fa95cd
commit
8e26e4c046
|
|
@ -71,9 +71,7 @@ impl Environment {
|
|||
/// Create a new profile in this environment.
|
||||
/// This should be used when a running node is not required.
|
||||
pub fn profile(&mut self, name: &str) -> Profile {
|
||||
let home = Home::new(self.tmp().join("home").join(name))
|
||||
.init()
|
||||
.unwrap();
|
||||
let home = Home::new(self.tmp().join("home").join(name)).unwrap();
|
||||
let storage = Storage::open(home.storage()).unwrap();
|
||||
let keystore = Keystore::new(&home.keys());
|
||||
let keypair = KeyPair::from_seed(Seed::from([!(self.users as u8); 32]));
|
||||
|
|
@ -232,7 +230,7 @@ impl Node<MockSigner> {
|
|||
.take(8)
|
||||
.collect::<String>(),
|
||||
);
|
||||
let home = Home::new(home).init().unwrap();
|
||||
let home = Home::new(home).unwrap();
|
||||
let signer = MockSigner::default();
|
||||
let storage = Storage::open(home.storage()).unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ pub struct Profile {
|
|||
|
||||
impl Profile {
|
||||
pub fn init(home: Home, passphrase: impl Into<Passphrase>) -> Result<Self, Error> {
|
||||
let home = home.init()?;
|
||||
let storage = Storage::open(home.storage())?;
|
||||
let keystore = Keystore::new(&home.keys());
|
||||
let public_key = keystore.init("radicle", passphrase)?;
|
||||
|
|
@ -142,9 +141,9 @@ impl Profile {
|
|||
/// Get the path to the radicle home folder.
|
||||
pub fn home() -> Result<Home, io::Error> {
|
||||
if let Some(home) = env::var_os(env::RAD_HOME) {
|
||||
Ok(Home::new(PathBuf::from(home)))
|
||||
Ok(Home::new(PathBuf::from(home))?)
|
||||
} else if let Some(home) = env::var_os("HOME") {
|
||||
Ok(Home::new(PathBuf::from(home).join(".radicle")))
|
||||
Ok(Home::new(PathBuf::from(home).join(".radicle"))?)
|
||||
} else {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
|
|
@ -166,14 +165,33 @@ impl From<PathBuf> for Home {
|
|||
}
|
||||
|
||||
impl Home {
|
||||
pub fn init(self) -> Result<Self, io::Error> {
|
||||
fs::create_dir_all(self.node()).ok();
|
||||
/// Creates the Radicle Home directories.
|
||||
///
|
||||
/// The `home` path is used as the base directory for all
|
||||
/// necessary subdirectories.
|
||||
///
|
||||
/// If `home` does not already exist then it and any
|
||||
/// subdirectories are created using [`fs::create_dir_all`].
|
||||
///
|
||||
/// The `home` path is also canonicalized using [`fs::canonicalize`].
|
||||
///
|
||||
/// All necessary subdirectories are also created.
|
||||
pub fn new(home: impl Into<PathBuf>) -> Result<Self, io::Error> {
|
||||
let path = home.into();
|
||||
if !path.exists() {
|
||||
fs::create_dir_all(path.clone())?;
|
||||
}
|
||||
let home = Self {
|
||||
path: path.canonicalize()?,
|
||||
};
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
for dir in &[home.storage(), home.keys(), home.node()] {
|
||||
if !dir.exists() {
|
||||
fs::create_dir_all(dir)?;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(home: impl Into<PathBuf>) -> Self {
|
||||
Self { path: home.into() }
|
||||
Ok(home)
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
|
|
@ -198,3 +216,33 @@ impl Home {
|
|||
.unwrap_or_else(|| self.node().join(node::DEFAULT_SOCKET_NAME))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::fs;
|
||||
|
||||
use super::Home;
|
||||
|
||||
// Checks that if we have:
|
||||
// '/run/user/1000/.tmpqfK6ih/../.tmpqfK6ih/Radicle/Home'
|
||||
//
|
||||
// that it gets normalized to:
|
||||
// '/run/user/1000/.tmpqfK6ih/Radicle/Home'
|
||||
#[test]
|
||||
fn canonicalize_home() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let path = tmp.path().join("Home").join("Radicle");
|
||||
fs::create_dir_all(path.clone()).unwrap();
|
||||
|
||||
let last = tmp.path().components().last().unwrap();
|
||||
let home = Home::new(
|
||||
tmp.path()
|
||||
.join("..")
|
||||
.join(last)
|
||||
.join("Home")
|
||||
.join("Radicle"),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(home.path, path);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ pub mod setup {
|
|||
let mut rng = fastrand::Rng::new();
|
||||
let signer = MockSigner::new(&mut rng);
|
||||
let home = tmp.path().join("home");
|
||||
let paths = Home::new(home.as_path());
|
||||
let paths = Home::new(home.as_path()).unwrap();
|
||||
let storage = Storage::open(paths.storage()).unwrap();
|
||||
let (id, _, _, _) = fixtures::project(tmp.path().join("copy"), &storage, &signer).unwrap();
|
||||
let project = storage.repository(id).unwrap();
|
||||
|
|
|
|||
Loading…
Reference in New Issue