Refactored Links::link implementation
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. Signed-off-by: Christina Sørensen <christina@cafkafk.com>
This commit is contained in:
parent
696eacf8d7
commit
4a04b45b7b
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