Refactored Links::link implementation #2
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 log::{debug, error, info, trace, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fs::canonicalize;
|
||||||
use std::os::unix::fs::symlink;
|
use std::os::unix::fs::symlink;
|
||||||
|
use std::path::Path;
|
||||||
use std::{fs, process::Command};
|
use std::{fs, process::Command};
|
||||||
|
|
||||||
/// Represents the config.toml file.
|
/// Represents the config.toml file.
|
||||||
|
@ -43,54 +45,46 @@ pub struct GitRepo {
|
||||||
pub clone: bool,
|
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 {
|
impl Links {
|
||||||
/// Creates a link from a file
|
/// Creates a link from a file
|
||||||
fn link(&self) {
|
fn link(&self) {
|
||||||
let rx_exists: bool = std::path::Path::new(&self.rx).exists();
|
let tx_path: &Path = std::path::Path::new(&self.tx);
|
||||||
let tx_exists: bool = std::path::Path::new(&self.tx).exists();
|
let rx_path: &Path = std::path::Path::new(&self.rx);
|
||||||
// NOTE If the file exists
|
match rx_path.try_exists() {
|
||||||
// NOTE And is not a link
|
Ok(true) => handle_file_exists(&self, &tx_path, &rx_path),
|
||||||
// NOTE We avoid using fs::read_link by returning early
|
Ok(false) if rx_path.is_symlink() => {
|
||||||
// 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 =>
|
|
||||||
{
|
|
||||||
error!(
|
error!(
|
||||||
"link {}: can't link rx {}, file already exists",
|
"Linking {} -> {} failed: broken symlink",
|
||||||
&self.name, &self.rx
|
&self.tx, &self.rx
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
(true, true)
|
Ok(false) => {
|
||||||
if fs::read_link(&self.rx)
|
symlink(&self.tx, &self.rx).expect("failed to create link");
|
||||||
.expect("failed to read link")
|
|
||||||
.to_str()
|
|
||||||
.unwrap()
|
|
||||||
== &self.tx =>
|
|
||||||
{
|
|
||||||
warn!(
|
|
||||||
"link {}: can't link rx {}, file already exists",
|
|
||||||
&self.name, &self.rx
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
(false, _) => error!("link {}: could not find tx at {}", &self.name, &self.rx),
|
Err(error) => {
|
||||||
(_, _) => unreachable!("Should never happen!"),
|
error!("Linking {} -> {} failed: {}", &self.tx, &self.rx, error);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue