chore(version): bump to v0.2.0 #10
12 changed files with 434 additions and 145 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
||||||
/target
|
/target
|
||||||
/tst/test
|
/src/test/test
|
||||||
/tst/test.yaml
|
/src/test/test.yaml
|
||||||
|
|
31
CHANGELOG.md
31
CHANGELOG.md
|
@ -2,12 +2,40 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.2.0] - 2023-07-07
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Made categories with only links possible
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- [**breaking**] Put links in categories
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Filled out Cargo.toml
|
||||||
|
- Added test.yaml to gitignore
|
||||||
|
- Fixed up code, roadmap for bump
|
||||||
|
|
||||||
|
### Refactor
|
||||||
|
|
||||||
|
- Simple code quality changes
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- Refactored testing, added tests dir
|
||||||
|
|
||||||
## [0.1.2] - 2023-07-03
|
## [0.1.2] - 2023-07-03
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- Implemented quiet flag
|
- Implemented quiet flag
|
||||||
|
|
||||||
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Bump to v0.1.2
|
||||||
|
|
||||||
## [0.1.1] - 2023-07-03
|
## [0.1.1] - 2023-07-03
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
@ -24,6 +52,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Miscellaneous Tasks
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Bump v0.1.0, housekeeping, #8 from cafkafk/dev
|
||||||
- Bump to v0.1.1
|
- Bump to v0.1.1
|
||||||
|
|
||||||
## [0.1.0] - 2023-07-03
|
## [0.1.0] - 2023-07-03
|
||||||
|
@ -42,6 +71,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
### Miscellaneous Tasks
|
### Miscellaneous Tasks
|
||||||
|
|
||||||
|
- Bump to 0.0.7 #7 from cafkafk/dev
|
||||||
- Bump v0.1.0, housekeeping
|
- Bump v0.1.0, housekeeping
|
||||||
|
|
||||||
### Refactor
|
### Refactor
|
||||||
|
@ -95,6 +125,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Version bump to v0.0.3
|
- Version bump to v0.0.3
|
||||||
- Moved install scripts to ./bin
|
- Moved install scripts to ./bin
|
||||||
- Merge 0.0.6
|
- Merge 0.0.6
|
||||||
|
- Merge 0.0.6 #6 from cafkafk/dev
|
||||||
- Bump to 0.0.7
|
- Bump to 0.0.7
|
||||||
|
|
||||||
### Refactor
|
### Refactor
|
||||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -179,7 +179,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gg"
|
name = "gg"
|
||||||
version = "0.1.2"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
|
|
24
Cargo.toml
24
Cargo.toml
|
@ -1,10 +1,30 @@
|
||||||
[package]
|
[package]
|
||||||
name = "gg"
|
name = "gg"
|
||||||
version = "0.1.2"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
|
||||||
authors = ["Christina Sørensen"]
|
authors = ["Christina Sørensen"]
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.72.0"
|
||||||
|
description = "A Rust GitOps/symlinkfarm orchestrator inspired by GNU Stow."
|
||||||
|
documentation = "https://github.com/cafkafk/gg"
|
||||||
|
readme = "./README.org"
|
||||||
|
homepage = "https://github.com/cafkafk/gg"
|
||||||
repository = "https://github.com/cafkafk/gg"
|
repository = "https://github.com/cafkafk/gg"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
keywords = ["git", "declarative", "cli", "devops", "terminal"]
|
||||||
|
categories = ["command-line-interface", "command-line-utilities"]
|
||||||
|
# workspace = "idk, I have no idea how to use this"
|
||||||
|
# build = "build.rs"
|
||||||
|
# links = "git2"
|
||||||
|
# exclude = "./vacation_photos"
|
||||||
|
# include = "./gg_memes"
|
||||||
|
publish = false
|
||||||
|
# metadata
|
||||||
|
# deafult-run
|
||||||
|
# autobins
|
||||||
|
# autoexamples
|
||||||
|
# autotests
|
||||||
|
# autobenches
|
||||||
|
# resolver
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#+title: Roadmap
|
#+title: Roadmap
|
||||||
|
|
||||||
* 0.2.0 (maybe)
|
* 0.2.0 (maybe)
|
||||||
- [ ] Links in categories?
|
- [X] Links in categories?
|
||||||
|
- [X] 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
|
||||||
|
|
163
src/git.rs
163
src/git.rs
|
@ -54,16 +54,12 @@ pub enum RepoFlags {
|
||||||
/// Represents the config.toml file.
|
/// Represents the config.toml file.
|
||||||
///
|
///
|
||||||
/// For diagrams of the underlying architecture, consult ARCHITECHTURE.md
|
/// For diagrams of the underlying architecture, consult ARCHITECHTURE.md
|
||||||
///
|
|
||||||
///
|
|
||||||
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// map of all categories
|
/// map of all categories
|
||||||
///
|
///
|
||||||
/// 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 +69,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 +117,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 +127,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 +155,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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +313,6 @@ impl GitRepo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/* GIT RELATED */
|
|
||||||
/// Loads the configuration toml from a path in to the Config struct.
|
/// Loads the configuration toml from a path in to the Config struct.
|
||||||
pub fn new(path: &String) -> Self {
|
pub fn new(path: &String) -> Self {
|
||||||
debug!("initializing new Config struct");
|
debug!("initializing new Config struct");
|
||||||
|
@ -320,15 +327,9 @@ impl Config {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
/// 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
|
|
||||||
///
|
|
||||||
/// NOTE: currently unused
|
/// NOTE: currently unused
|
||||||
///
|
|
||||||
fn on_all<F>(&self, f: F)
|
fn on_all<F>(&self, f: F)
|
||||||
where
|
where
|
||||||
F: Fn(&GitRepo),
|
F: Fn(&GitRepo),
|
||||||
|
@ -339,29 +340,89 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// /// Runs associated function on all repos in config
|
||||||
|
// fn on_all_spinner<F>(&self, op: &str, f: F)
|
||||||
|
// where
|
||||||
|
// F: Fn(&GitRepo) -> bool,
|
||||||
|
// {
|
||||||
|
// for category in self.categories.values() {
|
||||||
|
// for (_, repo) in category.repos.as_ref().expect("failed to get repos").iter() {
|
||||||
|
// if !settings::QUIET.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
|
// let mut sp = Spinner::new(Spinners::Dots10, format!("{}: {}", repo.name, op));
|
||||||
|
// if f(repo) {
|
||||||
|
// sp.stop_and_persist(success_str(), format!("{}: {}", repo.name, op));
|
||||||
|
// } else {
|
||||||
|
// sp.stop_and_persist(failure_str(), format!("{}: {}", repo.name, op));
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// f(repo);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
/// Runs associated function on all repos in config
|
/// Runs associated function on all repos in config
|
||||||
///
|
fn on_all_repos_spinner<F>(&self, op: &str, f: F)
|
||||||
/// TODO: need to be made over a generic repo type
|
|
||||||
///
|
|
||||||
///
|
|
||||||
fn on_all_spinner<F>(&self, op: &str, f: F)
|
|
||||||
where
|
where
|
||||||
F: Fn(&GitRepo) -> bool,
|
F: Fn(&GitRepo) -> bool,
|
||||||
{
|
{
|
||||||
for category in self.categories.values() {
|
for category in self.categories.values() {
|
||||||
for (_, repo) in category.repos.as_ref().expect("failed to get repos").iter() {
|
match category.repos.as_ref() {
|
||||||
|
Some(repos) => {
|
||||||
|
for repo in repos.values() {
|
||||||
if !settings::QUIET.load(std::sync::atomic::Ordering::Relaxed) {
|
if !settings::QUIET.load(std::sync::atomic::Ordering::Relaxed) {
|
||||||
let mut sp = Spinner::new(Spinners::Dots10, format!("{}: {}", repo.name, op));
|
let mut sp =
|
||||||
|
Spinner::new(Spinners::Dots10, format!("{}: {}", repo.name, op));
|
||||||
if f(repo) {
|
if f(repo) {
|
||||||
sp.stop_and_persist(success_str(), format!("{}: {}", repo.name, op));
|
sp.stop_and_persist(
|
||||||
|
success_str(),
|
||||||
|
format!("{}: {}", repo.name, op),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
sp.stop_and_persist(failure_str(), format!("{}: {}", repo.name, op));
|
sp.stop_and_persist(
|
||||||
|
failure_str(),
|
||||||
|
format!("{}: {}", repo.name, op),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
f(repo);
|
f(repo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// 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.values() {
|
||||||
|
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
|
||||||
///
|
///
|
||||||
|
@ -476,33 +537,61 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn get_repo<F>(&self, cat_name: &str, repo_name: &str, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&GitRepo),
|
||||||
|
{
|
||||||
|
f(&self
|
||||||
|
.categories
|
||||||
|
.get(cat_name)
|
||||||
|
.expect("failed to get category")
|
||||||
|
.repos
|
||||||
|
.as_ref()
|
||||||
|
.expect("failed to get repo")
|
||||||
|
.get(repo_name)
|
||||||
|
.expect("failed to get category"))
|
||||||
|
}
|
||||||
|
pub fn get_link<F>(&self, cat_name: &str, link_name: &str, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&Link),
|
||||||
|
{
|
||||||
|
f(&self
|
||||||
|
.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"))
|
||||||
|
}
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
/// Tries to pull all repositories, skips if fail.
|
/// Tries to pull all repositories, skips if fail.
|
||||||
pub fn pull_all(&self) {
|
pub fn pull_all(&self) {
|
||||||
debug!("exectuting pull_all");
|
debug!("exectuting pull_all");
|
||||||
self.on_all_spinner("pull", GitRepo::pull);
|
self.on_all_repos_spinner("pull", GitRepo::pull);
|
||||||
}
|
}
|
||||||
/// Tries to clone all repositories, skips if fail.
|
/// Tries to clone all repossitories, skips if fail.
|
||||||
pub fn clone_all(&self) {
|
pub fn clone_all(&self) {
|
||||||
debug!("exectuting clone_all");
|
debug!("exectuting clone_all");
|
||||||
self.on_all_spinner("clone", GitRepo::clone);
|
self.on_all_repos_spinner("clone", GitRepo::clone);
|
||||||
}
|
}
|
||||||
/// Tries to add all work in all repositories, skips if fail.
|
/// Tries to add all work in all repossitories, skips if fail.
|
||||||
pub fn add_all(&self) {
|
pub fn add_all(&self) {
|
||||||
debug!("exectuting clone_all");
|
debug!("exectuting clone_all");
|
||||||
self.on_all_spinner("add", GitRepo::add_all);
|
self.on_all_repos_spinner("add", GitRepo::add_all);
|
||||||
}
|
}
|
||||||
/// Tries to commit all repositories one at a time, skips if fail.
|
/// Tries to commit all repossitories one at a time, skips if fail.
|
||||||
pub fn commit_all(&self) {
|
pub fn commit_all(&self) {
|
||||||
debug!("exectuting clone_all");
|
debug!("exectuting clone_all");
|
||||||
self.on_all_spinner("commit", GitRepo::commit);
|
self.on_all_repos_spinner("commit", GitRepo::commit);
|
||||||
}
|
}
|
||||||
/// Tries to commit all repositories with msg, skips if fail.
|
/// Tries to commit all repossitories with msg, skips if fail.
|
||||||
pub fn commit_all_msg(&self, msg: &str) {
|
pub fn commit_all_msg(&self, msg: &str) {
|
||||||
debug!("exectuting clone_all");
|
debug!("exectuting clone_all");
|
||||||
self.on_all_spinner("commit", |repo| repo.commit_with_msg(msg));
|
self.on_all_repos_spinner("commit", |repo| repo.commit_with_msg(msg));
|
||||||
}
|
}
|
||||||
/// Tries to pull, add all, commit with msg "quick commit", and push all
|
/// Tries to pull, add all, commit with msg "quick commit", and push all
|
||||||
/// repositories, skips if fail.
|
/// repositories, skips if fail.
|
||||||
|
@ -558,8 +647,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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
src/lib.rs
Normal file
6
src/lib.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// #[allow(unused)]
|
||||||
|
// pub mod git;
|
||||||
|
// #[allow(unused)]
|
||||||
|
// mod settings;
|
||||||
|
// #[allow(unused)]
|
||||||
|
// mod utils;
|
40
src/main.rs
40
src/main.rs
|
@ -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,23 +191,10 @@ 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")
|
||||||
}
|
}
|
||||||
fn get_repo<F>(config: &Config, cat_name: &str, repo_name: &str, f: F)
|
|
||||||
where
|
|
||||||
F: FnOnce(&GitRepo),
|
|
||||||
{
|
|
||||||
f(config
|
|
||||||
.categories
|
|
||||||
.get(cat_name)
|
|
||||||
.expect("failed to get category")
|
|
||||||
.repos
|
|
||||||
.as_ref()
|
|
||||||
.expect("failed to get repo")
|
|
||||||
.get(repo_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,24 +206,20 @@ 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
|
// NOTE not very extensive
|
||||||
#[allow(clippy::bool_assert_comparison)]
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
{
|
{
|
||||||
get_repo(&config, "config", "qmk_firmware", |repo| {
|
(&config).get_repo("config", "qmk_firmware", |repo| {
|
||||||
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");
|
||||||
})
|
});
|
||||||
}
|
(&config).get_link("stuff", "gg", |link| {
|
||||||
{
|
assert_eq!(link.name, "gg");
|
||||||
assert_eq!(config.links[0].name, "gg");
|
assert_eq!(link.tx, "/home/ces/.dots/gg");
|
||||||
assert_eq!(config.links[0].rx, "/home/ces/.config/gg");
|
assert_eq!(link.rx, "/home/ces/.config/gg");
|
||||||
assert_eq!(config.links[0].tx, "/home/ces/.dots/gg");
|
});
|
||||||
assert_eq!(config.links[1].name, "starship");
|
|
||||||
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,23 @@ categories:
|
||||||
name: li
|
name: li
|
||||||
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
|
||||||
|
tx: /home/ces/.dots/starship.toml
|
||||||
|
fluff:
|
||||||
|
flags: []
|
||||||
|
links:
|
||||||
|
gg:
|
||||||
|
name: gg
|
||||||
|
rx: /home/ces/.config/gg
|
||||||
|
tx: /home/ces/.dots/gg
|
||||||
|
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
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
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/
|
|
||||||
url: git@github.com:cafkafk/qmk_firmware.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
|
|
||||||
utils:
|
|
||||||
repos:
|
|
||||||
gg:
|
|
||||||
name: gg
|
|
||||||
path: /home/ces/.dots/
|
|
||||||
url: git@github.com:cafkafk/gg.git
|
|
||||||
flags:
|
|
||||||
- Clone
|
|
||||||
- Push
|
|
||||||
li:
|
|
||||||
name: li
|
|
||||||
path: /home/ces/org/src/git/
|
|
||||||
url: git@github.com:cafkafk/li.git
|
|
||||||
flags:
|
|
||||||
- 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
|
|
|
@ -77,17 +77,17 @@ pub const SUCCESS_STRING: &str = "SUCC";
|
||||||
pub const FAILURE_STRING: &str = "FAIL";
|
pub const FAILURE_STRING: &str = "FAIL";
|
||||||
|
|
||||||
pub fn success_str() -> &'static str {
|
pub fn success_str() -> &'static str {
|
||||||
if !settings::EMOJIS.load(Ordering::Relaxed) {
|
if settings::EMOJIS.load(Ordering::Relaxed) {
|
||||||
SUCCESS_EMOJI
|
|
||||||
} else {
|
|
||||||
SUCCESS_STRING
|
SUCCESS_STRING
|
||||||
|
} else {
|
||||||
|
SUCCESS_EMOJI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn failure_str() -> &'static str {
|
pub fn failure_str() -> &'static str {
|
||||||
if !settings::EMOJIS.load(Ordering::Relaxed) {
|
if settings::EMOJIS.load(Ordering::Relaxed) {
|
||||||
FAILURE_EMOJI
|
|
||||||
} else {
|
|
||||||
FAILURE_STRING
|
FAILURE_STRING
|
||||||
|
} else {
|
||||||
|
FAILURE_EMOJI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
201
tests/main.rs
Normal file
201
tests/main.rs
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
#[test]
|
||||||
|
fn main() {
|
||||||
|
assert!(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
mod config {
|
||||||
|
use gg::git::RepoFlags::{Clone, Push};
|
||||||
|
use gg::git::{Category, Config, GitRepo, Link};
|
||||||
|
use relative_path::RelativePath;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::env::current_dir;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
#[test]
|
||||||
|
fn init_config() {
|
||||||
|
let _config = Config {
|
||||||
|
categories: HashMap::new(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn init_config_populate() {
|
||||||
|
let default_category = Category {
|
||||||
|
flags: Some(vec![]),
|
||||||
|
repos: Some(HashMap::new()),
|
||||||
|
links: Some(HashMap::new()),
|
||||||
|
};
|
||||||
|
let mut config = Config {
|
||||||
|
categories: HashMap::new(),
|
||||||
|
};
|
||||||
|
config
|
||||||
|
.categories
|
||||||
|
.insert(format!("{}", 0).to_string(), default_category);
|
||||||
|
for i in 0..=5 {
|
||||||
|
config
|
||||||
|
.categories
|
||||||
|
.get_mut(&format!("{}", 0).to_string())
|
||||||
|
.expect("category not found")
|
||||||
|
.repos
|
||||||
|
.as_mut()
|
||||||
|
.expect("failed to get repo")
|
||||||
|
.insert(
|
||||||
|
format!("{}", i).to_string(),
|
||||||
|
GitRepo {
|
||||||
|
name: "test repo".to_string(),
|
||||||
|
path: "/tmp".to_string(),
|
||||||
|
url: "https://github.com/cafkafk/gg".to_string(),
|
||||||
|
flags: Some(vec![Clone, Push]),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn read_config_populate() {
|
||||||
|
let _config = Config::new(&RelativePath::new("./src/test/config.yaml").to_string());
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn write_config() {
|
||||||
|
let root = current_dir().expect("failed to get current dir");
|
||||||
|
let config = Config::new(
|
||||||
|
&RelativePath::new("./src/test/config.yaml")
|
||||||
|
.to_logical_path(&root)
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.expect("failed to turn config into string"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut test_file = File::create(
|
||||||
|
RelativePath::new("./src/test/test.yaml")
|
||||||
|
.to_logical_path(&root)
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.expect("failed to turn config into string"),
|
||||||
|
)
|
||||||
|
.expect("failed to create test file");
|
||||||
|
let contents = serde_yaml::to_string(&config).expect("failed to turn config into string");
|
||||||
|
test_file
|
||||||
|
.write_all(contents.as_bytes())
|
||||||
|
.expect("failed to write contents of config into file");
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
fn get_repo<F>(config: &Config, cat_name: &str, repo_name: &str, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&GitRepo),
|
||||||
|
{
|
||||||
|
f(config
|
||||||
|
.categories
|
||||||
|
.get(cat_name)
|
||||||
|
.expect("failed to get category")
|
||||||
|
.repos
|
||||||
|
.as_ref()
|
||||||
|
.expect("failed to get repo")
|
||||||
|
.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");
|
||||||
|
let config = Config::new(
|
||||||
|
&RelativePath::new("./src/test/config.yaml")
|
||||||
|
.to_logical_path(root)
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.expect("failed to turnn config into string"),
|
||||||
|
);
|
||||||
|
|
||||||
|
let _flags = vec![Clone, Push];
|
||||||
|
// FIXME not very extensive
|
||||||
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
|
{
|
||||||
|
get_repo(&config, "config", "qmk_firmware", |repo| {
|
||||||
|
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");
|
||||||
|
assert_eq!(config.links[0].tx, "/home/ces/.dots/gg");
|
||||||
|
assert_eq!(config.links[1].name, "starship");
|
||||||
|
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
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
mod repo_actions {
|
||||||
|
use gg::git::GitRepo;
|
||||||
|
use gg::relative_path::RelativePath;
|
||||||
|
use gg::std::env::current_dir;
|
||||||
|
use gg::std::process::Command;
|
||||||
|
#[test]
|
||||||
|
#[allow(clippy::redundant_clone)]
|
||||||
|
fn test_repo_actions() {
|
||||||
|
let test_repo_name: String = "test".to_string();
|
||||||
|
let root = current_dir().unwrap();
|
||||||
|
let test_repo_dir: String = RelativePath::new("./src/test")
|
||||||
|
.to_logical_path(&root)
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.unwrap();
|
||||||
|
let test_repo_url: String = "git@github.com:cafkafk/test.git".to_string();
|
||||||
|
println!("{}", test_repo_dir);
|
||||||
|
let mut config = Config {
|
||||||
|
repos: vec![],
|
||||||
|
links: vec![],
|
||||||
|
};
|
||||||
|
let repo = GitRepo {
|
||||||
|
name: test_repo_name.to_owned(),
|
||||||
|
path: test_repo_dir.to_owned(),
|
||||||
|
url: test_repo_url.to_owned(),
|
||||||
|
clone: true,
|
||||||
|
};
|
||||||
|
config.repos.push(repo);
|
||||||
|
// BUG FIXME can't do this in flake
|
||||||
|
// should have a good alternative
|
||||||
|
// config.clone_all();
|
||||||
|
// config.pull_all();
|
||||||
|
for r in config.repos.iter() {
|
||||||
|
Command::new("touch")
|
||||||
|
.current_dir(&(r.path.to_owned() + &r.name))
|
||||||
|
.arg("test")
|
||||||
|
.status()
|
||||||
|
.expect("failed to create test file");
|
||||||
|
}
|
||||||
|
config.add_all();
|
||||||
|
config.commit_all_msg(&"test".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
Loading…
Reference in a new issue