feat(reset): introduce reset and fix ROOT_PATH
This commit is contained in:
parent
bc6a23b76b
commit
baeef1a33a
@ -1,3 +1,4 @@
|
||||
pub mod add;
|
||||
pub mod init;
|
||||
pub mod status;
|
||||
pub mod reset;
|
||||
|
@ -1,10 +1,12 @@
|
||||
use crate::config::config::Config;
|
||||
use crate::store::{
|
||||
structs::to_obj_path,
|
||||
ignorer::Ignorer,
|
||||
indexer::Indexer,
|
||||
nsobject::{self, NsObject},
|
||||
structs::{self, to_obj_path},
|
||||
};
|
||||
use crate::utils::path::to_repo_relative;
|
||||
use colored::Colorize;
|
||||
use std::fs;
|
||||
// use glob::glob;
|
||||
use std::path::PathBuf;
|
||||
@ -19,6 +21,8 @@ pub struct AddArgs {
|
||||
}
|
||||
|
||||
pub fn exec(args: AddArgs, config: Config) {
|
||||
structs::init(config.get_root());
|
||||
|
||||
// Init ignorer
|
||||
let mut ignorer = Ignorer::new(config.get_root_unsafe());
|
||||
ignorer.active_nsignore(!args.force);
|
||||
@ -27,8 +31,6 @@ pub fn exec(args: AddArgs, config: Config) {
|
||||
let mut indexer = Indexer::new(config.get_root_unsafe());
|
||||
let _ = indexer.load();
|
||||
|
||||
nsobject::init(config.get_root_unsafe());
|
||||
|
||||
if args.all {
|
||||
return add_dir(config.get_root_unsafe(), &mut ignorer, &mut indexer);
|
||||
}
|
||||
@ -38,6 +40,11 @@ pub fn exec(args: AddArgs, config: Config) {
|
||||
path_to_add.push(PathBuf::from(obj_to_add));
|
||||
|
||||
if path_to_add.exists() {
|
||||
// ignore object if it is ns config file or nsignored
|
||||
if ignorer.should_ignore(&path_to_add) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if path_to_add.is_dir() {
|
||||
indexer.index_dir(path_to_add.clone());
|
||||
add_dir(&path_to_add, &mut ignorer, &mut indexer);
|
||||
@ -54,17 +61,31 @@ pub fn exec(args: AddArgs, config: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
// print all path ignored
|
||||
if ignorer.ignored_paths.len() > 0 {
|
||||
println!("The following paths are ignored by one of your .nsignore files:");
|
||||
for ignored_path in ignorer.ignored_paths {
|
||||
println!("{}", to_repo_relative(&ignored_path).display());
|
||||
}
|
||||
println!(
|
||||
"{}",
|
||||
"hint: Use -f if you really want to add them.".bright_red()
|
||||
);
|
||||
// hint: Turn this message off by running
|
||||
// hint: "git config advice.addIgnoredFile false"
|
||||
}
|
||||
|
||||
dbg!(indexer.save());
|
||||
/*
|
||||
for all files
|
||||
if globbing
|
||||
take all match glob nextsyncignore
|
||||
else
|
||||
if dir
|
||||
add dir
|
||||
add all childs with nextsyncignore
|
||||
else
|
||||
add files
|
||||
for all files
|
||||
if globbing
|
||||
take all match glob nextsyncignore
|
||||
else
|
||||
if dir
|
||||
add dir
|
||||
add all childs with nextsyncignore
|
||||
else
|
||||
add files
|
||||
*/
|
||||
}
|
||||
|
||||
|
11
src/commands/reset.rs
Normal file
11
src/commands/reset.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use crate::config::config::Config;
|
||||
use crate::store::indexer::Indexer;
|
||||
|
||||
pub struct ResetArgs {
|
||||
}
|
||||
|
||||
pub fn exec(args: ResetArgs, config: Config) {
|
||||
// Init ignorer
|
||||
let indexer = Indexer::new(config.get_root_unsafe());
|
||||
let _ = indexer.save();
|
||||
}
|
@ -1,9 +1,10 @@
|
||||
use crate::config::config::Config;
|
||||
use crate::store::{
|
||||
structs::to_obj_path,
|
||||
indexer::Indexer,
|
||||
nsobject::NsObject,
|
||||
object::{Obj, ObjStatus, ObjType},
|
||||
structs,
|
||||
structs::to_obj_path,
|
||||
};
|
||||
use crate::utils::path;
|
||||
use colored::{ColoredString, Colorize};
|
||||
@ -109,6 +110,8 @@ pub fn exec(args: StatusArgs, config: Config) {
|
||||
}
|
||||
|
||||
pub fn get_obj_changes(args: &StatusArgs, config: &Config) -> ObjStaged {
|
||||
structs::init(config.get_root());
|
||||
|
||||
// use root of repo if no custom path has been set by the command
|
||||
let root = if config.is_custom_execution_path {
|
||||
config.execution_path.clone()
|
||||
@ -236,13 +239,13 @@ fn compare_dir(
|
||||
}
|
||||
};
|
||||
|
||||
if entry.path().ends_with(".nextsync") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let local_obj = Obj::from_local_path(&entry.path().into());
|
||||
|
||||
if entry.path().is_dir() {
|
||||
if entry.path().ends_with(".nextsync") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if local_obj.is_new() {
|
||||
// TODO: opti move files in new directory
|
||||
if indexer.is_staged_parent(&local_obj) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::OnceLock;
|
||||
use crate::store::structs;
|
||||
|
||||
///
|
||||
/// # Parameters
|
||||
|
@ -15,6 +15,7 @@ fn main() {
|
||||
subcommands::init::create(),
|
||||
subcommands::add::create(),
|
||||
subcommands::status::create(),
|
||||
subcommands::reset::create(),
|
||||
]);
|
||||
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||
|
||||
@ -24,6 +25,7 @@ fn main() {
|
||||
Some(("init", args)) => subcommands::init::handler(args),
|
||||
Some(("add", args)) => subcommands::add::handler(args),
|
||||
Some(("status", args)) => subcommands::status::handler(args),
|
||||
Some(("reset", args)) => subcommands::reset::handler(args),
|
||||
Some((_, _)) => {}
|
||||
None => {}
|
||||
};
|
||||
|
@ -9,6 +9,8 @@ pub struct Ignorer {
|
||||
use_nsignore: bool,
|
||||
/// Nsignore's rules
|
||||
rules: OnceLock<Vec<String>>,
|
||||
/// Path that have been ignored by should_ignore function
|
||||
pub ignored_paths: Vec<PathBuf>,
|
||||
childs: Option<Vec<Box<Ignorer>>>,
|
||||
}
|
||||
|
||||
@ -18,6 +20,7 @@ impl Ignorer {
|
||||
path: path.to_path_buf(),
|
||||
use_nsignore: true,
|
||||
rules: OnceLock::new(),
|
||||
ignored_paths: Vec::new(),
|
||||
childs: None,
|
||||
}
|
||||
}
|
||||
@ -52,6 +55,11 @@ impl Ignorer {
|
||||
///
|
||||
/// * `path`:
|
||||
pub fn should_ignore(&mut self, path: &PathBuf) -> bool {
|
||||
self.is_config_file(path) || (self.use_nsignore && self.is_ignored(path))
|
||||
let should = self.is_config_file(path) || (self.use_nsignore && self.is_ignored(path));
|
||||
|
||||
if should {
|
||||
self.ignored_paths.push(path.clone());
|
||||
}
|
||||
should
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,9 @@ fn sort_paths_hierarchically(paths: &mut Vec<PathBuf>) {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct IndexedObj {
|
||||
pub struct IndexedObj {
|
||||
obj_type: ObjType,
|
||||
path: PathBuf,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
pub struct Indexer {
|
||||
@ -76,6 +76,14 @@ impl Indexer {
|
||||
dbg!(&self.indexed_objs);
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.indexed_objs.clear();
|
||||
}
|
||||
|
||||
pub fn get_indexed_objs(&self) -> &Vec<IndexedObj> {
|
||||
&self.indexed_objs
|
||||
}
|
||||
|
||||
fn is_indexed(&self, obj: &IndexedObj) -> bool {
|
||||
self.indexed_objs
|
||||
.iter()
|
||||
|
@ -5,21 +5,6 @@ use crate::store::{
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
pub static REPO_ROOT: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
pub fn init(repo_root: &PathBuf) {
|
||||
let _ = REPO_ROOT.set(repo_root.clone());
|
||||
}
|
||||
|
||||
pub fn get_repo_root() -> PathBuf {
|
||||
match REPO_ROOT.get() {
|
||||
Some(path) => path.clone(),
|
||||
None => {
|
||||
panic!("fatal: 'REPO_ROOT' not set, you must initialize nsobject before using it!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type NsObjectChilds = Vec<Box<NsObject>>;
|
||||
|
||||
pub struct NsObject {
|
||||
|
@ -1,22 +1,60 @@
|
||||
use crate::store::nsobject::get_repo_root;
|
||||
use std::path::PathBuf;
|
||||
use crate::utils::{path, tests};
|
||||
use crypto::digest::Digest;
|
||||
use crypto::sha1::Sha1;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use crate::utils::path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{LazyLock, Mutex, OnceLock};
|
||||
|
||||
// for tests only as it is mutable
|
||||
static REPO_ROOT_DEV: LazyLock<Mutex<Vec<PathBuf>>> =
|
||||
LazyLock::new(|| Mutex::new(vec![PathBuf::new()]));
|
||||
|
||||
static REPO_ROOT: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
pub fn init(repo_root: &Option<PathBuf>) {
|
||||
if tests::is_var_setup() {
|
||||
REPO_ROOT_DEV.lock().unwrap()[0] = repo_root.clone().unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(repo_root) = repo_root {
|
||||
if REPO_ROOT.get().is_none() {
|
||||
let _ = REPO_ROOT.set(repo_root.clone());
|
||||
}
|
||||
} else {
|
||||
eprintln!("REPO_ROOT failed to initialize");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_repo_root() -> PathBuf {
|
||||
if tests::is_var_setup() {
|
||||
return REPO_ROOT_DEV.lock().unwrap()[0].clone();
|
||||
}
|
||||
|
||||
match REPO_ROOT.get() {
|
||||
Some(path) => path.clone(),
|
||||
None => {
|
||||
panic!("fatal: 'REPO_ROOT' not set, you must initialize nsobject before using it!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct ObjPath {
|
||||
path: PathBuf
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl Deref for ObjPath {
|
||||
type Target = PathBuf;
|
||||
fn deref(&self) -> &PathBuf { &self.path }
|
||||
fn deref(&self) -> &PathBuf {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ObjPath {
|
||||
fn deref_mut(&mut self) -> &mut PathBuf { &mut self.path }
|
||||
fn deref_mut(&mut self) -> &mut PathBuf {
|
||||
&mut self.path
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_obj_path(path: &PathBuf) -> ObjPath {
|
||||
@ -25,28 +63,36 @@ pub fn to_obj_path(path: &PathBuf) -> ObjPath {
|
||||
|
||||
impl Into<ObjPath> for &PathBuf {
|
||||
fn into(self) -> ObjPath {
|
||||
ObjPath { path: path::to_repo_relative(self, &get_repo_root())}
|
||||
ObjPath {
|
||||
path: path::to_repo_relative(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ObjPath> for PathBuf {
|
||||
fn into(self) -> ObjPath {
|
||||
ObjPath { path: path::to_repo_relative(&self, &get_repo_root())}
|
||||
ObjPath {
|
||||
path: path::to_repo_relative(&self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct NsObjPath {
|
||||
path: PathBuf
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl Deref for NsObjPath {
|
||||
type Target = PathBuf;
|
||||
fn deref(&self) -> &PathBuf { &self.path }
|
||||
fn deref(&self) -> &PathBuf {
|
||||
&self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for NsObjPath {
|
||||
fn deref_mut(&mut self) -> &mut PathBuf { &mut self.path }
|
||||
fn deref_mut(&mut self) -> &mut PathBuf {
|
||||
&mut self.path
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for NsObjPath {
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod add;
|
||||
pub mod init;
|
||||
pub mod reset;
|
||||
pub mod status;
|
||||
|
17
src/subcommands/reset.rs
Normal file
17
src/subcommands/reset.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||
|
||||
use crate::commands;
|
||||
use crate::commands::reset::ResetArgs;
|
||||
use crate::config::config::Config;
|
||||
|
||||
pub fn create() -> Command {
|
||||
Command::new("reset")
|
||||
.about("Clear the index")
|
||||
}
|
||||
|
||||
pub fn handler(args: &ArgMatches) {
|
||||
commands::reset::exec(
|
||||
ResetArgs {},
|
||||
Config::new(),
|
||||
);
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod path;
|
||||
pub mod tests;
|
||||
|
@ -1,7 +1,15 @@
|
||||
use std::path::{Path, PathBuf, Component};
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use crate::store::structs;
|
||||
|
||||
pub fn to_repo_relative(path: &PathBuf, root: &PathBuf) -> PathBuf {
|
||||
path.strip_prefix(root).unwrap().to_path_buf()
|
||||
pub fn to_repo_relative(path: &PathBuf) -> PathBuf {
|
||||
let root = structs::get_repo_root();
|
||||
path.strip_prefix(&root)
|
||||
.expect(&format!(
|
||||
"Expect '{}' to be in the repo '{}'",
|
||||
path.display(),
|
||||
root.display()
|
||||
))
|
||||
.to_path_buf()
|
||||
}
|
||||
|
||||
pub fn to_string(path: &PathBuf) -> String {
|
||||
@ -18,9 +26,7 @@ pub fn to_string(path: &PathBuf) -> String {
|
||||
/// This function ensures a given path ending with '/' still
|
||||
/// ends with '/' after normalization.
|
||||
pub fn normalize_path<P: AsRef<Path>>(path: P) -> PathBuf {
|
||||
let ends_with_slash = path.as_ref()
|
||||
.to_str()
|
||||
.map_or(false, |s| s.ends_with('/'));
|
||||
let ends_with_slash = path.as_ref().to_str().map_or(false, |s| s.ends_with('/'));
|
||||
let mut normalized = PathBuf::new();
|
||||
for component in path.as_ref().components() {
|
||||
match &component {
|
||||
|
15
src/utils/tests.rs
Normal file
15
src/utils/tests.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::env;
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn is_running() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
pub fn is_running() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn is_var_setup() -> bool {
|
||||
env::var("RUNNING_TESTS").is_ok()
|
||||
}
|
Loading…
Reference in New Issue
Block a user