feat!: put links in categories
This required a lot of refatoring, and added a lot of codedepth that have to be repaid soon by a large refactor. Also, it is becoming painfully obvious that testing should be expanded significantly. This, after the refactor, nonetheless. Signed-off-by: Christina Sørensen <christina@cafkafk.com>
This commit is contained in:
parent
c62a0a720f
commit
d5b845508a
5 changed files with 109 additions and 43 deletions
|
@ -1,7 +1,9 @@
|
|||
#+title: Roadmap
|
||||
|
||||
* 0.2.0 (maybe)
|
||||
- [ ] Links in categories?
|
||||
- [-] Links in categories?
|
||||
- [ ] Fix category with no links
|
||||
- [ ] Refactor
|
||||
* 0.1.2
|
||||
- [X] Implement Quiet flag
|
||||
* 0.1.1
|
||||
|
|
62
src/git.rs
62
src/git.rs
|
@ -62,8 +62,6 @@ pub struct Config {
|
|||
///
|
||||
/// Key should conceptually be seen as the name of the category.
|
||||
pub categories: HashMap<String, Category>,
|
||||
/// A vector containing links
|
||||
pub links: Vec<Links>,
|
||||
}
|
||||
|
||||
/// Represents a category of repositories
|
||||
|
@ -73,16 +71,22 @@ pub struct Config {
|
|||
pub struct Category {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub flags: Option<Vec<RepoFlags>>, // FIXME: not implemented
|
||||
/// map of all categories
|
||||
/// map of all repos in category
|
||||
///
|
||||
/// Key should conceptually be seen as the name of the category.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub repos: Option<HashMap<String, GitRepo>>,
|
||||
|
||||
/// map of all links in category
|
||||
///
|
||||
/// Key should conceptually be seen as the name of the category.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub links: Option<HashMap<String, Link>>,
|
||||
}
|
||||
|
||||
/// Contain fields for a single link.
|
||||
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
pub struct Links {
|
||||
pub struct Link {
|
||||
/// The name of the link
|
||||
pub name: String,
|
||||
pub rx: String,
|
||||
|
@ -115,7 +119,7 @@ pub struct SeriesItem<'series> {
|
|||
////////////////////////////////////
|
||||
////////////////////////////////////
|
||||
|
||||
fn handle_file_exists(selff: &Links, tx_path: &Path, rx_path: &Path) {
|
||||
fn handle_file_exists(selff: &Link, tx_path: &Path, rx_path: &Path) -> bool {
|
||||
match rx_path.read_link() {
|
||||
Ok(file)
|
||||
if file.canonicalize().expect("failed to canonicalize file")
|
||||
|
@ -125,22 +129,25 @@ fn handle_file_exists(selff: &Links, tx_path: &Path, rx_path: &Path) {
|
|||
"Linking {} -> {} failed: file already linked",
|
||||
&selff.tx, &selff.rx
|
||||
);
|
||||
false
|
||||
}
|
||||
Ok(file) => {
|
||||
error!(
|
||||
"Linking {} -> {} failed: link to different file exists",
|
||||
&selff.tx, &selff.rx
|
||||
);
|
||||
false
|
||||
}
|
||||
Err(error) => {
|
||||
error!("Linking {} -> {} failed: file exists", &selff.tx, &selff.rx);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Links {
|
||||
impl Link {
|
||||
/// Creates the link from the link struct
|
||||
pub fn link(&self) {
|
||||
pub fn link(&self) -> bool {
|
||||
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() {
|
||||
|
@ -150,14 +157,17 @@ impl Links {
|
|||
"Linking {} -> {} failed: broken symlink",
|
||||
&self.tx, &self.rx
|
||||
);
|
||||
false
|
||||
}
|
||||
Ok(false) => {
|
||||
symlink(&self.tx, &self.rx).expect("failed to create link");
|
||||
true
|
||||
}
|
||||
Err(error) => {
|
||||
error!("Linking {} -> {} failed: {}", &self.tx, &self.rx, error);
|
||||
false
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,6 +373,38 @@ impl Config {
|
|||
}
|
||||
}
|
||||
}
|
||||
/// Runs associated function on all links in config
|
||||
fn on_all_links_spinner<F>(&self, op: &str, f: F)
|
||||
where
|
||||
F: Fn(&Link) -> bool,
|
||||
{
|
||||
for category in self.categories.values() {
|
||||
match category.links.as_ref() {
|
||||
Some(links) => {
|
||||
for (_, link) in links.iter() {
|
||||
if !settings::QUIET.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
let mut sp =
|
||||
Spinner::new(Spinners::Dots10, format!("{}: {}", link.name, op));
|
||||
if f(link) {
|
||||
sp.stop_and_persist(
|
||||
success_str(),
|
||||
format!("{}: {}", link.name, op),
|
||||
);
|
||||
} else {
|
||||
sp.stop_and_persist(
|
||||
failure_str(),
|
||||
format!("{}: {}", link.name, op),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
f(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
None => continue,
|
||||
};
|
||||
}
|
||||
}
|
||||
/// Runs associated function on all repos in config
|
||||
///
|
||||
/// TODO: need to be made over a generic repo type
|
||||
|
@ -558,8 +600,6 @@ impl Config {
|
|||
/// Tries to link all repositories, skips if fail.
|
||||
pub fn link_all(&self) {
|
||||
debug!("exectuting link_all");
|
||||
for link in &self.links {
|
||||
link.link();
|
||||
}
|
||||
self.on_all_links_spinner("link", Link::link);
|
||||
}
|
||||
}
|
||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -116,7 +116,7 @@ fn main() {
|
|||
mod config {
|
||||
use crate::*;
|
||||
use git::RepoFlags::{Clone, Push};
|
||||
use git::{Category, GitRepo};
|
||||
use git::{Category, GitRepo, Link};
|
||||
use relative_path::RelativePath;
|
||||
use std::collections::HashMap;
|
||||
use std::env::current_dir;
|
||||
|
@ -126,7 +126,6 @@ mod config {
|
|||
fn init_config() {
|
||||
let _config = Config {
|
||||
categories: HashMap::new(),
|
||||
links: vec![],
|
||||
};
|
||||
}
|
||||
#[test]
|
||||
|
@ -134,10 +133,10 @@ mod config {
|
|||
let default_category = Category {
|
||||
flags: Some(vec![]),
|
||||
repos: Some(HashMap::new()),
|
||||
links: Some(HashMap::new()),
|
||||
};
|
||||
let mut config = Config {
|
||||
categories: HashMap::new(),
|
||||
links: vec![],
|
||||
};
|
||||
config
|
||||
.categories
|
||||
|
@ -192,6 +191,7 @@ mod config {
|
|||
let test_config = Config::new(&RelativePath::new("./src/test/test.yaml").to_string());
|
||||
assert_eq!(config, test_config);
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
fn get_category<'cat>(config: &'cat Config, name: &'cat str) -> &'cat Category {
|
||||
config.categories.get(name).expect("failed to get category")
|
||||
}
|
||||
|
@ -209,6 +209,20 @@ mod config {
|
|||
.get(repo_name)
|
||||
.expect("failed to get category"))
|
||||
}
|
||||
fn get_link<F>(config: &Config, cat_name: &str, link_name: &str, f: F)
|
||||
where
|
||||
F: FnOnce(&Link),
|
||||
{
|
||||
f(config
|
||||
.categories
|
||||
.get(cat_name)
|
||||
.expect("failed to get category")
|
||||
.links
|
||||
.as_ref()
|
||||
.expect("failed to get repo")
|
||||
.get(link_name)
|
||||
.expect("failed to get category"))
|
||||
}
|
||||
#[test]
|
||||
fn is_config_readable() {
|
||||
let root = current_dir().expect("failed to get current dir");
|
||||
|
@ -220,7 +234,7 @@ mod config {
|
|||
.expect("failed to turnn config into string"),
|
||||
);
|
||||
|
||||
let flags = vec![Clone, Push];
|
||||
let _flags = vec![Clone, Push];
|
||||
// FIXME not very extensive
|
||||
#[allow(clippy::bool_assert_comparison)]
|
||||
{
|
||||
|
@ -228,8 +242,14 @@ mod config {
|
|||
assert_eq!(repo.name, "qmk_firmware");
|
||||
assert_eq!(repo.path, "/home/ces/org/src/git/");
|
||||
assert_eq!(repo.url, "git@github.com:cafkafk/qmk_firmware.git");
|
||||
})
|
||||
});
|
||||
get_link(&config, "stuff", "gg", |link| {
|
||||
assert_eq!(link.name, "gg");
|
||||
assert_eq!(link.tx, "/home/ces/.dots/gg");
|
||||
assert_eq!(link.rx, "/home/ces/.config/gg");
|
||||
});
|
||||
}
|
||||
/*
|
||||
{
|
||||
assert_eq!(config.links[0].name, "gg");
|
||||
assert_eq!(config.links[0].rx, "/home/ces/.config/gg");
|
||||
|
@ -238,7 +258,7 @@ mod config {
|
|||
assert_eq!(config.links[1].rx, "/home/ces/.config/starship.toml");
|
||||
assert_eq!(config.links[1].tx, "/home/ces/.dots/starship.toml");
|
||||
// FIXME doesn't check repoflags
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,12 @@ categories:
|
|||
name: li
|
||||
path: /home/ces/org/src/git/
|
||||
url: git@github.com:cafkafk/li.git
|
||||
links:
|
||||
- name: gg
|
||||
rx: /home/ces/.config/gg
|
||||
tx: /home/ces/.dots/gg
|
||||
- name: starship
|
||||
rx: /home/ces/.config/starship.toml
|
||||
tx: /home/ces/.dots/starship.toml
|
||||
links:
|
||||
gg:
|
||||
name: gg
|
||||
rx: /home/ces/.config/gg
|
||||
tx: /home/ces/.dots/gg
|
||||
starship:
|
||||
name: starship
|
||||
rx: /home/ces/.config/starship.toml
|
||||
tx: /home/ces/.dots/starship.toml
|
||||
|
|
|
@ -2,13 +2,6 @@ categories:
|
|||
config:
|
||||
flags: []
|
||||
repos:
|
||||
starship:
|
||||
name: starship
|
||||
path: /home/ces/org/src/git/
|
||||
url: https://github.com/starship/starship.git
|
||||
flags:
|
||||
- Clone
|
||||
- Push
|
||||
qmk_firmware:
|
||||
name: qmk_firmware
|
||||
path: /home/ces/org/src/git/
|
||||
|
@ -16,17 +9,33 @@ categories:
|
|||
flags:
|
||||
- Clone
|
||||
- Push
|
||||
starship:
|
||||
name: starship
|
||||
path: /home/ces/org/src/git/
|
||||
url: https://github.com/starship/starship.git
|
||||
flags:
|
||||
- Clone
|
||||
- Push
|
||||
stuff:
|
||||
flags: []
|
||||
repos:
|
||||
li:
|
||||
name: li
|
||||
path: /home/ces/org/src/git/
|
||||
url: git@github.com:cafkafk/li.git
|
||||
gg:
|
||||
name: gg
|
||||
path: /home/ces/.dots/
|
||||
url: git@github.com:cafkafk/gg.git
|
||||
li:
|
||||
name: li
|
||||
path: /home/ces/org/src/git/
|
||||
url: git@github.com:cafkafk/li.git
|
||||
links:
|
||||
gg:
|
||||
name: gg
|
||||
rx: /home/ces/.config/gg
|
||||
tx: /home/ces/.dots/gg
|
||||
starship:
|
||||
name: starship
|
||||
rx: /home/ces/.config/starship.toml
|
||||
tx: /home/ces/.dots/starship.toml
|
||||
utils:
|
||||
repos:
|
||||
gg:
|
||||
|
@ -44,10 +53,3 @@ categories:
|
|||
- Clone
|
||||
- Push
|
||||
empty: {}
|
||||
links:
|
||||
- name: gg
|
||||
rx: /home/ces/.config/gg
|
||||
tx: /home/ces/.dots/gg
|
||||
- name: starship
|
||||
rx: /home/ces/.config/starship.toml
|
||||
tx: /home/ces/.dots/starship.toml
|
||||
|
|
Loading…
Reference in a new issue