Merge pull request #2 from cafkafk/dev
Refactored Links::link implementation to be able to deal with several possible scenarios: file already linked (happy case) link to different file exists non link file exists broken symlink exists no file exists (happy case) generic failure Also attempted to make the code more readable than previous attempt. Admittedly, still needs some work.
This commit is contained in:
commit
9182d4f236
1 changed files with 36 additions and 42 deletions
78
src/git.rs
78
src/git.rs
|
@ -16,7 +16,9 @@
|
|||
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::canonicalize;
|
||||
use std::os::unix::fs::symlink;
|
||||
use std::path::Path;
|
||||
use std::{fs, process::Command};
|
||||
|
||||
/// Represents the config.toml file.
|
||||
|
@ -43,54 +45,46 @@ pub struct GitRepo {
|
|||
pub clone: bool,
|
||||
}
|
||||
|
||||
fn handle_file_exists(selff: &Links, tx_path: &Path, rx_path: &Path) {
|
||||
match rx_path.read_link() {
|
||||
Ok(file) if file.canonicalize().unwrap() == tx_path.canonicalize().unwrap() => {
|
||||
debug!(
|
||||
"Linking {} -> {} failed: file already linked",
|
||||
&selff.tx, &selff.rx
|
||||
);
|
||||
}
|
||||
Ok(file) => {
|
||||
error!(
|
||||
"Linking {} -> {} failed: link to different file exists",
|
||||
&selff.tx, &selff.rx
|
||||
);
|
||||
}
|
||||
Err(error) => {
|
||||
error!("Linking {} -> {} failed: file exists", &selff.tx, &selff.rx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Links {
|
||||
/// Creates a link from a file
|
||||
fn link(&self) {
|
||||
let rx_exists: bool = std::path::Path::new(&self.rx).exists();
|
||||
let tx_exists: bool = std::path::Path::new(&self.tx).exists();
|
||||
// NOTE If the file exists
|
||||
// NOTE And is not a link
|
||||
// NOTE We avoid using fs::read_link by returning early
|
||||
// FIXME This should be refactored
|
||||
if rx_exists {
|
||||
let rx_link = fs::read_link(&self.rx);
|
||||
match rx_link {
|
||||
Ok(_) => (),
|
||||
Err(error) => {
|
||||
error!("Linking {} -> {} failed: {}", &self.tx, &self.rx, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
match (tx_exists, rx_exists) {
|
||||
(true, false) => symlink(&self.tx, &self.rx).expect("failed to create link"),
|
||||
(true, true)
|
||||
if fs::read_link(&self.rx)
|
||||
.expect("failed to read link")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
!= &self.tx =>
|
||||
{
|
||||
let tx_path: &Path = std::path::Path::new(&self.tx);
|
||||
let rx_path: &Path = std::path::Path::new(&self.rx);
|
||||
match rx_path.try_exists() {
|
||||
Ok(true) => handle_file_exists(&self, &tx_path, &rx_path),
|
||||
Ok(false) if rx_path.is_symlink() => {
|
||||
error!(
|
||||
"link {}: can't link rx {}, file already exists",
|
||||
&self.name, &self.rx
|
||||
)
|
||||
"Linking {} -> {} failed: broken symlink",
|
||||
&self.tx, &self.rx
|
||||
);
|
||||
}
|
||||
(true, true)
|
||||
if fs::read_link(&self.rx)
|
||||
.expect("failed to read link")
|
||||
.to_str()
|
||||
.unwrap()
|
||||
== &self.tx =>
|
||||
{
|
||||
warn!(
|
||||
"link {}: can't link rx {}, file already exists",
|
||||
&self.name, &self.rx
|
||||
)
|
||||
Ok(false) => {
|
||||
symlink(&self.tx, &self.rx).expect("failed to create link");
|
||||
}
|
||||
(false, _) => error!("link {}: could not find tx at {}", &self.name, &self.rx),
|
||||
(_, _) => unreachable!("Should never happen!"),
|
||||
}
|
||||
Err(error) => {
|
||||
error!("Linking {} -> {} failed: {}", &self.tx, &self.rx, error);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue