mirror of
https://github.com/denisidoro/navi.git
synced 2026-01-23 02:14:19 +00:00
Adds a basic sync function + cargo fmt + cargo clippy compliance + minor refactors
Signed-off-by: alexis-opolka <53085471+alexis-opolka@users.noreply.github.com>
This commit is contained in:
parent
9b2d001195
commit
d279f8fc55
5 changed files with 111 additions and 49 deletions
|
|
@ -1,54 +1,8 @@
|
|||
use crate::common::git;
|
||||
use crate::config::CONFIG;
|
||||
use crate::filesystem::{all_cheat_files, default_cheat_pathbuf};
|
||||
use crate::filesystem::local_cheatsheet_repositories;
|
||||
use crate::libs::terminal::hyperlink;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn main() {
|
||||
let mut cheats_repos: Vec<String> = Vec::new();
|
||||
let cheats = CONFIG.path().unwrap_or_else(|| {
|
||||
// if we don't have a path, use the default value
|
||||
let mut _cheats = default_cheat_pathbuf().unwrap();
|
||||
_cheats.push("navi");
|
||||
_cheats.push("cheats");
|
||||
|
||||
_cheats.to_string()
|
||||
});
|
||||
|
||||
// We're checking each given paths possible
|
||||
for cheat_path in cheats.split(':') {
|
||||
// If the path doesn't exist, continue to the next one
|
||||
if !std::fs::exists(cheat_path).unwrap() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let curr_dir = std::fs::read_dir(cheat_path).unwrap();
|
||||
|
||||
// We're checking subfolders -> they should contain at least one .cheat files
|
||||
for entry in curr_dir {
|
||||
let entry = entry.unwrap();
|
||||
|
||||
if entry.file_type().unwrap().is_dir() {
|
||||
// If the directory doesn't have at least one cheat file -> ignore it and continue
|
||||
if all_cheat_files(&entry.path()).is_empty() {
|
||||
continue;
|
||||
};
|
||||
|
||||
// If the directory have at least one cheat file -> add it to the list
|
||||
// Note: for the list, we are registering the git remote name and not the
|
||||
// folder name since we modify it internally.
|
||||
let git_path = format!("{}/{}", &entry.path().display(), ".git");
|
||||
|
||||
if std::fs::exists(&git_path).unwrap() {
|
||||
let remote_uri = git::get_remote(&entry.path().to_string()).unwrap();
|
||||
|
||||
cheats_repos.push(remote_uri);
|
||||
} else {
|
||||
cheats_repos.push(entry.path().display().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let (cheats_repos, _) = local_cheatsheet_repositories();
|
||||
|
||||
// Now that we have our list of cheatsheet repositories, we loop through them
|
||||
// Two behaviours:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,35 @@
|
|||
use crate::common::git;
|
||||
use crate::filesystem;
|
||||
use crate::filesystem::local_cheatsheet_repositories;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn main(name: Option<String>) -> Result<()> {
|
||||
let (cheats_repo_uris, cheats_repo_paths) = local_cheatsheet_repositories();
|
||||
|
||||
if name.clone().is_some() {
|
||||
let name = name.clone().unwrap();
|
||||
|
||||
// We have been given a repository uri to check
|
||||
if cheats_repo_uris.contains(&name) {
|
||||
let folder_index = cheats_repo_uris.iter().position(|r| r == &name).unwrap();
|
||||
let repo_path = cheats_repo_paths[folder_index].clone();
|
||||
|
||||
git::pull(&repo_path)?;
|
||||
} else {
|
||||
eprintln!("I don't find {} locally, are you sure you downloaded it?", &name);
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// We haven't been given a name -> We synchronize every cheatsheet repository we've found
|
||||
for cheat_repo in cheats_repo_paths {
|
||||
eprintln!("Pulling the latest version of {}", cheat_repo);
|
||||
|
||||
git::pull(&cheat_repo)?;
|
||||
}
|
||||
|
||||
// TODO: Sanitize the cheatsheet folder of any file that is not a cheat file
|
||||
// Ref: https://github.com/denisidoro/navi/issues/733
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ pub fn meta(uri: &str) -> (String, String, String) {
|
|||
(actual_uri, user.to_string(), repo)
|
||||
}
|
||||
|
||||
/// Retrieves the remote URI of a git repository
|
||||
/// Works best with a repository containing only one remote.
|
||||
pub fn get_remote(uri: &str) -> Result<String> {
|
||||
// We consider the repository having only one remote
|
||||
// In case of multiple occurrences, we return the first one and discard the others
|
||||
|
|
@ -63,6 +65,17 @@ pub fn get_remote(uri: &str) -> Result<String> {
|
|||
Ok(remotes_uri[0].clone())
|
||||
}
|
||||
|
||||
/// Pulls the latest version of a git repository
|
||||
pub fn pull(uri: &str) -> Result<()> {
|
||||
Command::new("git")
|
||||
.current_dir(uri)
|
||||
.args(["pull", "origin"])
|
||||
.spawn()?
|
||||
.wait()
|
||||
.expect("Unable to git pull");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -26,3 +26,11 @@ impl EnvConfig {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A default implementation for EnvConfig
|
||||
/// to satisfy cargo clippy.
|
||||
impl Default for EnvConfig {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use regex::Regex;
|
|||
use std::cell::RefCell;
|
||||
use std::path::MAIN_SEPARATOR;
|
||||
|
||||
use crate::common::git;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
/// Multiple paths are joint by a platform-specific separator.
|
||||
|
|
@ -114,6 +115,16 @@ pub fn cheat_paths(path: Option<String>) -> Result<String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the cheats path defined at run time
|
||||
pub fn running_cheats_path() -> String {
|
||||
CONFIG.path().unwrap_or_else(|| {
|
||||
// if we don't have a path, use the default value
|
||||
let _cheats = default_cheat_pathbuf().unwrap();
|
||||
|
||||
_cheats.to_string()
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Here are other functions, unrelated to CLI commands (or at least not directly related)
|
||||
|
|
@ -150,6 +161,54 @@ fn get_config_dir_by_platform() -> Result<PathBuf> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Goes through the cheats path(s) defined within the configuration
|
||||
/// and sends back any cheatsheet repository remote URI it finds.
|
||||
pub fn local_cheatsheet_repositories() -> (Vec<String>, Vec<String>) {
|
||||
let mut cheats_repos_uri: Vec<String> = Vec::new();
|
||||
let mut cheats_repos_paths: Vec<String> = Vec::new();
|
||||
let cheats = running_cheats_path();
|
||||
|
||||
// We're checking each given paths possible
|
||||
for cheat_path in cheats.split(':') {
|
||||
// If the path doesn't exist, continue to the next one
|
||||
if !std::fs::exists(cheat_path).unwrap() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let curr_dir = std::fs::read_dir(cheat_path).unwrap();
|
||||
|
||||
// We're checking subfolders -> they should contain at least one .cheat files
|
||||
for entry in curr_dir {
|
||||
let entry = entry.unwrap();
|
||||
|
||||
if entry.file_type().unwrap().is_dir() {
|
||||
// If the directory doesn't have at least one cheat file -> ignore it and continue
|
||||
if all_cheat_files(&entry.path()).is_empty() {
|
||||
continue;
|
||||
};
|
||||
|
||||
// If the directory have at least one cheat file -> add it to the list
|
||||
// Note: for the list, we are registering the git remote name and not the
|
||||
// folder name since we modify it internally.
|
||||
let git_path = format!("{}/{}", &entry.path().display(), ".git");
|
||||
let folder_path = entry.path().display().to_string();
|
||||
|
||||
if std::fs::exists(&git_path).unwrap() {
|
||||
let remote_uri = git::get_remote(&entry.path().to_string()).unwrap();
|
||||
|
||||
cheats_repos_uri.push(remote_uri);
|
||||
} else {
|
||||
cheats_repos_uri.push(folder_path.clone());
|
||||
}
|
||||
|
||||
cheats_repos_paths.push(folder_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(cheats_repos_uri, cheats_repos_paths)
|
||||
}
|
||||
|
||||
pub fn tmp_pathbuf() -> Result<PathBuf> {
|
||||
let mut root = default_cheat_pathbuf()?;
|
||||
root.push("tmp");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue