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
|
#+title: Roadmap
|
||||||
|
|
||||||
* 0.2.0 (maybe)
|
* 0.2.0 (maybe)
|
||||||
- [ ] Links in categories?
|
- [-] Links in categories?
|
||||||
|
- [ ] Fix category with no links
|
||||||
|
- [ ] Refactor
|
||||||
* 0.1.2
|
* 0.1.2
|
||||||
- [X] Implement Quiet flag
|
- [X] Implement Quiet flag
|
||||||
* 0.1.1
|
* 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.
|
/// Key should conceptually be seen as the name of the category.
|
||||||
pub categories: HashMap<String, Category>,
|
pub categories: HashMap<String, Category>,
|
||||||
/// A vector containing links
|
|
||||||
pub links: Vec<Links>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a category of repositories
|
/// Represents a category of repositories
|
||||||
|
@ -73,16 +71,22 @@ pub struct Config {
|
||||||
pub struct Category {
|
pub struct Category {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub flags: Option<Vec<RepoFlags>>, // FIXME: not implemented
|
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.
|
/// Key should conceptually be seen as the name of the category.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub repos: Option<HashMap<String, GitRepo>>,
|
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.
|
/// Contain fields for a single link.
|
||||||
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
pub struct Links {
|
pub struct Link {
|
||||||
/// The name of the link
|
/// The name of the link
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub rx: 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() {
|
match rx_path.read_link() {
|
||||||
Ok(file)
|
Ok(file)
|
||||||
if file.canonicalize().expect("failed to canonicalize 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",
|
"Linking {} -> {} failed: file already linked",
|
||||||
&selff.tx, &selff.rx
|
&selff.tx, &selff.rx
|
||||||
);
|
);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
Ok(file) => {
|
Ok(file) => {
|
||||||
error!(
|
error!(
|
||||||
"Linking {} -> {} failed: link to different file exists",
|
"Linking {} -> {} failed: link to different file exists",
|
||||||
&selff.tx, &selff.rx
|
&selff.tx, &selff.rx
|
||||||
);
|
);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!("Linking {} -> {} failed: file exists", &selff.tx, &selff.rx);
|
error!("Linking {} -> {} failed: file exists", &selff.tx, &selff.rx);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Links {
|
impl Link {
|
||||||
/// Creates the link from the link struct
|
/// 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 tx_path: &Path = std::path::Path::new(&self.tx);
|
||||||
let rx_path: &Path = std::path::Path::new(&self.rx);
|
let rx_path: &Path = std::path::Path::new(&self.rx);
|
||||||
match rx_path.try_exists() {
|
match rx_path.try_exists() {
|
||||||
|
@ -150,14 +157,17 @@ impl Links {
|
||||||
"Linking {} -> {} failed: broken symlink",
|
"Linking {} -> {} failed: broken symlink",
|
||||||
&self.tx, &self.rx
|
&self.tx, &self.rx
|
||||||
);
|
);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
Ok(false) => {
|
Ok(false) => {
|
||||||
symlink(&self.tx, &self.rx).expect("failed to create link");
|
symlink(&self.tx, &self.rx).expect("failed to create link");
|
||||||
|
true
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!("Linking {} -> {} failed: {}", &self.tx, &self.rx, 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
|
/// Runs associated function on all repos in config
|
||||||
///
|
///
|
||||||
/// TODO: need to be made over a generic repo type
|
/// TODO: need to be made over a generic repo type
|
||||||
|
@ -558,8 +600,6 @@ impl Config {
|
||||||
/// Tries to link all repositories, skips if fail.
|
/// Tries to link all repositories, skips if fail.
|
||||||
pub fn link_all(&self) {
|
pub fn link_all(&self) {
|
||||||
debug!("exectuting link_all");
|
debug!("exectuting link_all");
|
||||||
for link in &self.links {
|
self.on_all_links_spinner("link", Link::link);
|
||||||
link.link();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -116,7 +116,7 @@ fn main() {
|
||||||
mod config {
|
mod config {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use git::RepoFlags::{Clone, Push};
|
use git::RepoFlags::{Clone, Push};
|
||||||
use git::{Category, GitRepo};
|
use git::{Category, GitRepo, Link};
|
||||||
use relative_path::RelativePath;
|
use relative_path::RelativePath;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
|
@ -126,7 +126,6 @@ mod config {
|
||||||
fn init_config() {
|
fn init_config() {
|
||||||
let _config = Config {
|
let _config = Config {
|
||||||
categories: HashMap::new(),
|
categories: HashMap::new(),
|
||||||
links: vec![],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -134,10 +133,10 @@ mod config {
|
||||||
let default_category = Category {
|
let default_category = Category {
|
||||||
flags: Some(vec![]),
|
flags: Some(vec![]),
|
||||||
repos: Some(HashMap::new()),
|
repos: Some(HashMap::new()),
|
||||||
|
links: Some(HashMap::new()),
|
||||||
};
|
};
|
||||||
let mut config = Config {
|
let mut config = Config {
|
||||||
categories: HashMap::new(),
|
categories: HashMap::new(),
|
||||||
links: vec![],
|
|
||||||
};
|
};
|
||||||
config
|
config
|
||||||
.categories
|
.categories
|
||||||
|
@ -192,6 +191,7 @@ mod config {
|
||||||
let test_config = Config::new(&RelativePath::new("./src/test/test.yaml").to_string());
|
let test_config = Config::new(&RelativePath::new("./src/test/test.yaml").to_string());
|
||||||
assert_eq!(config, test_config);
|
assert_eq!(config, test_config);
|
||||||
}
|
}
|
||||||
|
#[allow(dead_code)]
|
||||||
fn get_category<'cat>(config: &'cat Config, name: &'cat str) -> &'cat Category {
|
fn get_category<'cat>(config: &'cat Config, name: &'cat str) -> &'cat Category {
|
||||||
config.categories.get(name).expect("failed to get category")
|
config.categories.get(name).expect("failed to get category")
|
||||||
}
|
}
|
||||||
|
@ -209,6 +209,20 @@ mod config {
|
||||||
.get(repo_name)
|
.get(repo_name)
|
||||||
.expect("failed to get category"))
|
.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]
|
#[test]
|
||||||
fn is_config_readable() {
|
fn is_config_readable() {
|
||||||
let root = current_dir().expect("failed to get current dir");
|
let root = current_dir().expect("failed to get current dir");
|
||||||
|
@ -220,7 +234,7 @@ mod config {
|
||||||
.expect("failed to turnn config into string"),
|
.expect("failed to turnn config into string"),
|
||||||
);
|
);
|
||||||
|
|
||||||
let flags = vec![Clone, Push];
|
let _flags = vec![Clone, Push];
|
||||||
// FIXME not very extensive
|
// FIXME not very extensive
|
||||||
#[allow(clippy::bool_assert_comparison)]
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
{
|
{
|
||||||
|
@ -228,8 +242,14 @@ mod config {
|
||||||
assert_eq!(repo.name, "qmk_firmware");
|
assert_eq!(repo.name, "qmk_firmware");
|
||||||
assert_eq!(repo.path, "/home/ces/org/src/git/");
|
assert_eq!(repo.path, "/home/ces/org/src/git/");
|
||||||
assert_eq!(repo.url, "git@github.com:cafkafk/qmk_firmware.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].name, "gg");
|
||||||
assert_eq!(config.links[0].rx, "/home/ces/.config/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].rx, "/home/ces/.config/starship.toml");
|
||||||
assert_eq!(config.links[1].tx, "/home/ces/.dots/starship.toml");
|
assert_eq!(config.links[1].tx, "/home/ces/.dots/starship.toml");
|
||||||
// FIXME doesn't check repoflags
|
// FIXME doesn't check repoflags
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,11 @@ categories:
|
||||||
path: /home/ces/org/src/git/
|
path: /home/ces/org/src/git/
|
||||||
url: git@github.com:cafkafk/li.git
|
url: git@github.com:cafkafk/li.git
|
||||||
links:
|
links:
|
||||||
- name: gg
|
gg:
|
||||||
|
name: gg
|
||||||
rx: /home/ces/.config/gg
|
rx: /home/ces/.config/gg
|
||||||
tx: /home/ces/.dots/gg
|
tx: /home/ces/.dots/gg
|
||||||
- name: starship
|
starship:
|
||||||
|
name: starship
|
||||||
rx: /home/ces/.config/starship.toml
|
rx: /home/ces/.config/starship.toml
|
||||||
tx: /home/ces/.dots/starship.toml
|
tx: /home/ces/.dots/starship.toml
|
||||||
|
|
|
@ -2,13 +2,6 @@ categories:
|
||||||
config:
|
config:
|
||||||
flags: []
|
flags: []
|
||||||
repos:
|
repos:
|
||||||
starship:
|
|
||||||
name: starship
|
|
||||||
path: /home/ces/org/src/git/
|
|
||||||
url: https://github.com/starship/starship.git
|
|
||||||
flags:
|
|
||||||
- Clone
|
|
||||||
- Push
|
|
||||||
qmk_firmware:
|
qmk_firmware:
|
||||||
name: qmk_firmware
|
name: qmk_firmware
|
||||||
path: /home/ces/org/src/git/
|
path: /home/ces/org/src/git/
|
||||||
|
@ -16,17 +9,33 @@ categories:
|
||||||
flags:
|
flags:
|
||||||
- Clone
|
- Clone
|
||||||
- Push
|
- Push
|
||||||
|
starship:
|
||||||
|
name: starship
|
||||||
|
path: /home/ces/org/src/git/
|
||||||
|
url: https://github.com/starship/starship.git
|
||||||
|
flags:
|
||||||
|
- Clone
|
||||||
|
- Push
|
||||||
stuff:
|
stuff:
|
||||||
flags: []
|
flags: []
|
||||||
repos:
|
repos:
|
||||||
li:
|
|
||||||
name: li
|
|
||||||
path: /home/ces/org/src/git/
|
|
||||||
url: git@github.com:cafkafk/li.git
|
|
||||||
gg:
|
gg:
|
||||||
name: gg
|
name: gg
|
||||||
path: /home/ces/.dots/
|
path: /home/ces/.dots/
|
||||||
url: git@github.com:cafkafk/gg.git
|
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:
|
utils:
|
||||||
repos:
|
repos:
|
||||||
gg:
|
gg:
|
||||||
|
@ -44,10 +53,3 @@ categories:
|
||||||
- Clone
|
- Clone
|
||||||
- Push
|
- Push
|
||||||
empty: {}
|
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