Compare commits
No commits in common. "e66dc8d408472d1125fb3c2c10627dbc9d816f53" and "1df9c3fba55f0e7347d975272f05075c779b0f23" have entirely different histories.
e66dc8d408
...
1df9c3fba5
@ -1,4 +1,3 @@
|
|||||||
pub mod add;
|
pub mod add;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
pub mod reset;
|
|
||||||
|
@ -3,10 +3,7 @@ use crate::store::{
|
|||||||
ignorer::Ignorer,
|
ignorer::Ignorer,
|
||||||
indexer::Indexer,
|
indexer::Indexer,
|
||||||
nsobject::{self, NsObject},
|
nsobject::{self, NsObject},
|
||||||
structs::{self, to_obj_path},
|
|
||||||
};
|
};
|
||||||
use crate::utils::path::to_repo_relative;
|
|
||||||
use colored::Colorize;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
// use glob::glob;
|
// use glob::glob;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -21,8 +18,6 @@ pub struct AddArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(args: AddArgs, config: Config) {
|
pub fn exec(args: AddArgs, config: Config) {
|
||||||
structs::init(config.get_root());
|
|
||||||
|
|
||||||
// Init ignorer
|
// Init ignorer
|
||||||
let mut ignorer = Ignorer::new(config.get_root_unsafe());
|
let mut ignorer = Ignorer::new(config.get_root_unsafe());
|
||||||
ignorer.active_nsignore(!args.force);
|
ignorer.active_nsignore(!args.force);
|
||||||
@ -31,6 +26,8 @@ pub fn exec(args: AddArgs, config: Config) {
|
|||||||
let mut indexer = Indexer::new(config.get_root_unsafe());
|
let mut indexer = Indexer::new(config.get_root_unsafe());
|
||||||
let _ = indexer.load();
|
let _ = indexer.load();
|
||||||
|
|
||||||
|
nsobject::init(config.get_root_unsafe());
|
||||||
|
|
||||||
if args.all {
|
if args.all {
|
||||||
return add_dir(config.get_root_unsafe(), &mut ignorer, &mut indexer);
|
return add_dir(config.get_root_unsafe(), &mut ignorer, &mut indexer);
|
||||||
}
|
}
|
||||||
@ -40,18 +37,13 @@ pub fn exec(args: AddArgs, config: Config) {
|
|||||||
path_to_add.push(PathBuf::from(obj_to_add));
|
path_to_add.push(PathBuf::from(obj_to_add));
|
||||||
|
|
||||||
if path_to_add.exists() {
|
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() {
|
if path_to_add.is_dir() {
|
||||||
indexer.index_dir(path_to_add.clone());
|
indexer.index_dir(path_to_add.clone());
|
||||||
add_dir(&path_to_add, &mut ignorer, &mut indexer);
|
add_dir(&path_to_add, &mut ignorer, &mut indexer);
|
||||||
} else {
|
} else {
|
||||||
indexer.index_file(path_to_add);
|
indexer.index_file(path_to_add);
|
||||||
}
|
}
|
||||||
} else if NsObject::from_local_path(&to_obj_path(&path_to_add)).exists() {
|
} else if NsObject::from_local_path(&path_to_add).exists() {
|
||||||
indexer.index_file(path_to_add);
|
indexer.index_file(path_to_add);
|
||||||
} else {
|
} else {
|
||||||
// try globbing
|
// try globbing
|
||||||
@ -61,20 +53,6 @@ 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());
|
dbg!(indexer.save());
|
||||||
/*
|
/*
|
||||||
for all files
|
for all files
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
@ -3,8 +3,6 @@ use crate::store::{
|
|||||||
indexer::Indexer,
|
indexer::Indexer,
|
||||||
nsobject::NsObject,
|
nsobject::NsObject,
|
||||||
object::{Obj, ObjStatus, ObjType},
|
object::{Obj, ObjStatus, ObjType},
|
||||||
structs,
|
|
||||||
structs::to_obj_path,
|
|
||||||
};
|
};
|
||||||
use crate::utils::path;
|
use crate::utils::path;
|
||||||
use colored::{ColoredString, Colorize};
|
use colored::{ColoredString, Colorize};
|
||||||
@ -110,8 +108,6 @@ pub fn exec(args: StatusArgs, config: Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj_changes(args: &StatusArgs, config: &Config) -> ObjStaged {
|
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
|
// use root of repo if no custom path has been set by the command
|
||||||
let root = if config.is_custom_execution_path {
|
let root = if config.is_custom_execution_path {
|
||||||
config.execution_path.clone()
|
config.execution_path.clone()
|
||||||
@ -239,13 +235,14 @@ fn compare_dir(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let repo_relative_entry = path::to_repo_relative(&entry.path(), root_path);
|
||||||
|
let local_obj = Obj::from_local_path(&repo_relative_entry);
|
||||||
|
|
||||||
|
if entry.path().is_dir() {
|
||||||
if entry.path().ends_with(".nextsync") {
|
if entry.path().ends_with(".nextsync") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_obj = Obj::from_local_path(&entry.path().into());
|
|
||||||
|
|
||||||
if entry.path().is_dir() {
|
|
||||||
if local_obj.is_new() {
|
if local_obj.is_new() {
|
||||||
// TODO: opti move files in new directory
|
// TODO: opti move files in new directory
|
||||||
if indexer.is_staged_parent(&local_obj) {
|
if indexer.is_staged_parent(&local_obj) {
|
||||||
@ -283,7 +280,7 @@ fn compare_dir(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read ns objects to find deleted
|
// Read ns objects to find deleted
|
||||||
let entries = NsObject::from_local_path(&to_obj_path(&path));
|
let entries = NsObject::from_local_path(&path);
|
||||||
for entry in entries.iter() {
|
for entry in entries.iter() {
|
||||||
if entry.is_file() {
|
if entry.is_file() {
|
||||||
match local_files.get(entry.get_obj_path().to_str().unwrap()) {
|
match local_files.get(entry.get_obj_path().to_str().unwrap()) {
|
||||||
@ -327,7 +324,8 @@ fn add_childs(root_path: &PathBuf, path: &PathBuf, res: Arc<ObjStatuses>) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let local_obj = Obj::from_local_path(&entry.path().into());
|
let repo_relative_entry = path::to_repo_relative(&entry.path(), root_path);
|
||||||
|
let local_obj = Obj::from_local_path(&repo_relative_entry);
|
||||||
if entry.path().is_dir() {
|
if entry.path().is_dir() {
|
||||||
if entry.path().ends_with(".nextsync") {
|
if entry.path().ends_with(".nextsync") {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use crate::store::structs;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
|
@ -15,7 +15,6 @@ fn main() {
|
|||||||
subcommands::init::create(),
|
subcommands::init::create(),
|
||||||
subcommands::add::create(),
|
subcommands::add::create(),
|
||||||
subcommands::status::create(),
|
subcommands::status::create(),
|
||||||
subcommands::reset::create(),
|
|
||||||
]);
|
]);
|
||||||
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
// .setting(clap::AppSettings::SubcommandRequiredElseHelp);
|
||||||
|
|
||||||
@ -25,7 +24,6 @@ fn main() {
|
|||||||
Some(("init", args)) => subcommands::init::handler(args),
|
Some(("init", args)) => subcommands::init::handler(args),
|
||||||
Some(("add", args)) => subcommands::add::handler(args),
|
Some(("add", args)) => subcommands::add::handler(args),
|
||||||
Some(("status", args)) => subcommands::status::handler(args),
|
Some(("status", args)) => subcommands::status::handler(args),
|
||||||
Some(("reset", args)) => subcommands::reset::handler(args),
|
|
||||||
Some((_, _)) => {}
|
Some((_, _)) => {}
|
||||||
None => {}
|
None => {}
|
||||||
};
|
};
|
||||||
|
@ -3,4 +3,3 @@ pub mod indexer;
|
|||||||
pub mod nsignore;
|
pub mod nsignore;
|
||||||
pub mod nsobject;
|
pub mod nsobject;
|
||||||
pub mod object;
|
pub mod object;
|
||||||
pub mod structs;
|
|
||||||
|
@ -9,8 +9,6 @@ pub struct Ignorer {
|
|||||||
use_nsignore: bool,
|
use_nsignore: bool,
|
||||||
/// Nsignore's rules
|
/// Nsignore's rules
|
||||||
rules: OnceLock<Vec<String>>,
|
rules: OnceLock<Vec<String>>,
|
||||||
/// Path that have been ignored by should_ignore function
|
|
||||||
pub ignored_paths: Vec<PathBuf>,
|
|
||||||
childs: Option<Vec<Box<Ignorer>>>,
|
childs: Option<Vec<Box<Ignorer>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +18,6 @@ impl Ignorer {
|
|||||||
path: path.to_path_buf(),
|
path: path.to_path_buf(),
|
||||||
use_nsignore: true,
|
use_nsignore: true,
|
||||||
rules: OnceLock::new(),
|
rules: OnceLock::new(),
|
||||||
ignored_paths: Vec::new(),
|
|
||||||
childs: None,
|
childs: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,11 +52,6 @@ impl Ignorer {
|
|||||||
///
|
///
|
||||||
/// * `path`:
|
/// * `path`:
|
||||||
pub fn should_ignore(&mut self, path: &PathBuf) -> bool {
|
pub fn should_ignore(&mut self, path: &PathBuf) -> bool {
|
||||||
let should = self.is_config_file(path) || (self.use_nsignore && self.is_ignored(path));
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct IndexedObj {
|
struct IndexedObj {
|
||||||
obj_type: ObjType,
|
obj_type: ObjType,
|
||||||
pub path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Indexer {
|
pub struct Indexer {
|
||||||
@ -76,14 +76,6 @@ impl Indexer {
|
|||||||
dbg!(&self.indexed_objs);
|
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 {
|
fn is_indexed(&self, obj: &IndexedObj) -> bool {
|
||||||
self.indexed_objs
|
self.indexed_objs
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1,28 +1,66 @@
|
|||||||
use crate::store::{
|
use crate::store::object::{Obj, ObjMetadata, ObjType};
|
||||||
object::{Obj, ObjMetadata, ObjType},
|
use crypto::digest::Digest;
|
||||||
structs::{NsObjPath, ObjPath},
|
use crypto::sha1::Sha1;
|
||||||
};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
pub static REPO_ROOT: OnceLock<PathBuf> = OnceLock::new();
|
||||||
|
|
||||||
|
pub fn init(repo_root: &PathBuf) {
|
||||||
|
REPO_ROOT.set(repo_root.clone());
|
||||||
|
}
|
||||||
|
|
||||||
type NsObjectChilds = Vec<Box<NsObject>>;
|
type NsObjectChilds = Vec<Box<NsObject>>;
|
||||||
|
|
||||||
|
struct NsObjectPath {
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for NsObjectPath {
|
||||||
|
fn from(hash: &str) -> Self {
|
||||||
|
let (dir, res) = hash.split_at(2);
|
||||||
|
|
||||||
|
let mut ns_obj_path = match REPO_ROOT.get() {
|
||||||
|
Some(path) => path.clone(),
|
||||||
|
None => {
|
||||||
|
panic!("fatal: 'REPO_ROOT' not set, you must initialize nsobject before using it!")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ns_obj_path.push(dir);
|
||||||
|
ns_obj_path.push(res);
|
||||||
|
|
||||||
|
NsObjectPath { path: ns_obj_path }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&PathBuf> for NsObjectPath {
|
||||||
|
fn from(obj_path: &PathBuf) -> Self {
|
||||||
|
let mut hasher = Sha1::new();
|
||||||
|
hasher.input_str(
|
||||||
|
obj_path
|
||||||
|
.to_str()
|
||||||
|
.expect("Cannot contains non UTF-8 char in path"),
|
||||||
|
);
|
||||||
|
NsObjectPath::from(hasher.result_str().as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct NsObject {
|
pub struct NsObject {
|
||||||
pub obj_type: ObjType,
|
pub obj_type: ObjType,
|
||||||
/// path of the obj in the repo
|
obj_path: OnceLock<PathBuf>,
|
||||||
obj_path: OnceLock<ObjPath>,
|
nsobj_path: OnceLock<PathBuf>,
|
||||||
/// path of the nsobj file in the store
|
|
||||||
nsobj_path: OnceLock<NsObjPath>,
|
|
||||||
childs: OnceLock<NsObjectChilds>,
|
childs: OnceLock<NsObjectChilds>,
|
||||||
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NsObject {
|
impl NsObject {
|
||||||
pub fn from_local_path(path: &ObjPath) -> Self {
|
pub fn from_local_path(path: &PathBuf) -> Self {
|
||||||
NsObject {
|
NsObject {
|
||||||
obj_type: ObjType::Obj,
|
obj_type: ObjType::Obj,
|
||||||
obj_path: OnceLock::from(path.clone()),
|
obj_path: OnceLock::from(path.to_path_buf()),
|
||||||
nsobj_path: OnceLock::new(),
|
nsobj_path: OnceLock::new(),
|
||||||
childs: OnceLock::new(),
|
childs: OnceLock::new(),
|
||||||
|
index: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,18 +68,19 @@ impl NsObject {
|
|||||||
NsObject {
|
NsObject {
|
||||||
obj_type: ObjType::Obj,
|
obj_type: ObjType::Obj,
|
||||||
obj_path: OnceLock::new(),
|
obj_path: OnceLock::new(),
|
||||||
nsobj_path: OnceLock::from(NsObjPath::from(hash)),
|
nsobj_path: OnceLock::from(NsObjectPath::from(hash).path),
|
||||||
childs: OnceLock::new(),
|
childs: OnceLock::new(),
|
||||||
|
index: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj_path(&self) -> &ObjPath {
|
pub fn get_obj_path(&self) -> &PathBuf {
|
||||||
self.obj_path.get_or_init(|| todo!())
|
self.obj_path.get_or_init(|| todo!())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_nsobj_path(&self) -> &NsObjPath {
|
fn get_nsobj_path(&self) -> &PathBuf {
|
||||||
self.nsobj_path
|
self.nsobj_path
|
||||||
.get_or_init(|| NsObjPath::from(self.get_obj_path()))
|
.get_or_init(|| NsObjectPath::from(self.get_obj_path()).path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the existence of the nsobj in the store
|
/// Return the existence of the nsobj in the store
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::store::{structs::ObjPath, nsobject::NsObject};
|
use crate::store::nsobject::NsObject;
|
||||||
use crate::utils::path;
|
use crate::utils::path;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -55,16 +55,16 @@ pub struct Obj {
|
|||||||
obj_type: ObjType,
|
obj_type: ObjType,
|
||||||
status: OnceLock<ObjStatus>,
|
status: OnceLock<ObjStatus>,
|
||||||
/// path of the object from root
|
/// path of the object from root
|
||||||
obj_path: ObjPath,
|
obj_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Obj {
|
impl Obj {
|
||||||
pub fn from_local_path(path: &ObjPath) -> Self {
|
pub fn from_local_path(path: &PathBuf) -> Self {
|
||||||
// todo set state
|
// todo set state
|
||||||
Obj {
|
Obj {
|
||||||
obj_type: ObjType::Obj,
|
obj_type: ObjType::Obj,
|
||||||
status: OnceLock::new(),
|
status: OnceLock::new(),
|
||||||
obj_path: path.clone(),
|
obj_path: path.to_path_buf(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ impl Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_metadata(&self) -> Option<ObjMetadata> {
|
pub fn get_metadata(&self) -> Option<ObjMetadata> {
|
||||||
let metadata = match fs::metadata(&*self.obj_path) {
|
let metadata = match fs::metadata(&self.obj_path) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
use crate::utils::{path, tests};
|
|
||||||
use crypto::digest::Digest;
|
|
||||||
use crypto::sha1::Sha1;
|
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for ObjPath {
|
|
||||||
type Target = PathBuf;
|
|
||||||
fn deref(&self) -> &PathBuf {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for ObjPath {
|
|
||||||
fn deref_mut(&mut self) -> &mut PathBuf {
|
|
||||||
&mut self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_obj_path(path: &PathBuf) -> ObjPath {
|
|
||||||
ObjPath { path: path.clone() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ObjPath> for &PathBuf {
|
|
||||||
fn into(self) -> ObjPath {
|
|
||||||
ObjPath {
|
|
||||||
path: path::to_repo_relative(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ObjPath> for PathBuf {
|
|
||||||
fn into(self) -> ObjPath {
|
|
||||||
ObjPath {
|
|
||||||
path: path::to_repo_relative(&self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
pub struct NsObjPath {
|
|
||||||
path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for NsObjPath {
|
|
||||||
type Target = PathBuf;
|
|
||||||
fn deref(&self) -> &PathBuf {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DerefMut for NsObjPath {
|
|
||||||
fn deref_mut(&mut self) -> &mut PathBuf {
|
|
||||||
&mut self.path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for NsObjPath {
|
|
||||||
fn from(hash: &str) -> Self {
|
|
||||||
let (dir, res) = hash.split_at(2);
|
|
||||||
|
|
||||||
let mut ns_obj_path = get_repo_root();
|
|
||||||
ns_obj_path.push(dir);
|
|
||||||
ns_obj_path.push(res);
|
|
||||||
|
|
||||||
NsObjPath { path: ns_obj_path }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&ObjPath> for NsObjPath {
|
|
||||||
fn from(obj_path: &ObjPath) -> Self {
|
|
||||||
let mut hasher = Sha1::new();
|
|
||||||
hasher.input_str(
|
|
||||||
obj_path
|
|
||||||
.to_str()
|
|
||||||
.expect("Cannot contains non UTF-8 char in path"),
|
|
||||||
);
|
|
||||||
NsObjPath::from(hasher.result_str().as_str())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,3 @@
|
|||||||
pub mod add;
|
pub mod add;
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod reset;
|
|
||||||
pub mod status;
|
pub mod status;
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
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,2 +1 @@
|
|||||||
pub mod path;
|
pub mod path;
|
||||||
pub mod tests;
|
|
||||||
|
@ -1,15 +1,7 @@
|
|||||||
use std::path::{Component, Path, PathBuf};
|
use std::path::{Path, PathBuf, Component};
|
||||||
use crate::store::structs;
|
|
||||||
|
|
||||||
pub fn to_repo_relative(path: &PathBuf) -> PathBuf {
|
pub fn to_repo_relative(path: &PathBuf, root: &PathBuf) -> PathBuf {
|
||||||
let root = structs::get_repo_root();
|
path.strip_prefix(root).unwrap().to_path_buf()
|
||||||
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 {
|
pub fn to_string(path: &PathBuf) -> String {
|
||||||
@ -26,7 +18,9 @@ pub fn to_string(path: &PathBuf) -> String {
|
|||||||
/// This function ensures a given path ending with '/' still
|
/// This function ensures a given path ending with '/' still
|
||||||
/// ends with '/' after normalization.
|
/// ends with '/' after normalization.
|
||||||
pub fn normalize_path<P: AsRef<Path>>(path: P) -> PathBuf {
|
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();
|
let mut normalized = PathBuf::new();
|
||||||
for component in path.as_ref().components() {
|
for component in path.as_ref().components() {
|
||||||
match &component {
|
match &component {
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
mod common;
|
|
||||||
|
|
||||||
use common::client::ClientTest;
|
|
||||||
use nextsync::store::indexer::Indexer;
|
|
||||||
use nextsync::commands::status::{get_obj_changes, StatusArgs};
|
|
||||||
use nextsync::config::config::Config;
|
|
||||||
use std::io;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
const DEFAULT_STATUS_ARG: StatusArgs = StatusArgs { nostyle: false };
|
|
||||||
|
|
||||||
fn indexed_expected(indexer: &Indexer, expected: Vec<&str>) {
|
|
||||||
let objs = indexer.get_indexed_objs();
|
|
||||||
|
|
||||||
assert_eq!(objs.len(), expected.len());
|
|
||||||
|
|
||||||
for obj in expected {
|
|
||||||
assert!(objs
|
|
||||||
.iter()
|
|
||||||
.position(|e| { e.path == PathBuf::from(obj) })
|
|
||||||
.is_some());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn add_ignored_file() -> io::Result<()> {
|
|
||||||
let mut client = ClientTest::new("add__simple_file").init();
|
|
||||||
client.add_ignore_rule("foo");
|
|
||||||
client.add_file("foo", "foo")?;
|
|
||||||
|
|
||||||
let mut indexer = Indexer::new(client.get_config().get_root_unsafe());
|
|
||||||
|
|
||||||
client.exec_ok("add foo");
|
|
||||||
let _ = indexer.load();
|
|
||||||
indexed_expected(&indexer, vec![]);
|
|
||||||
|
|
||||||
client.exec_ok("add foo -f");
|
|
||||||
let _ = indexer.load();
|
|
||||||
indexed_expected(&indexer, vec!["foo"]);
|
|
||||||
|
|
||||||
client.ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
// add double globbing
|
|
||||||
// add all
|
|
||||||
// add folders
|
|
||||||
// add part of folders
|
|
||||||
// add all folder
|
|
||||||
// add automatic ignored if is tracked
|
|
@ -1,5 +1,4 @@
|
|||||||
use nextsync::config::config::Config;
|
use nextsync::config::config::Config;
|
||||||
use std::fs::OpenOptions;
|
|
||||||
use rand::{distributions::Alphanumeric, Rng};
|
use rand::{distributions::Alphanumeric, Rng};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
@ -126,18 +125,6 @@ impl ClientTest {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_ignore_rule(&self, rule: &str) {
|
|
||||||
let mut nsignore_path = self.volume.clone();
|
|
||||||
nsignore_path.push_str("/.nsignore");
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.create(true)
|
|
||||||
.append(true)
|
|
||||||
.open(nsignore_path).unwrap();
|
|
||||||
|
|
||||||
let _ = writeln!(file, "{rule}").unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn has_file(&mut self, file: &str, content: &str) -> bool {
|
// pub fn has_file(&mut self, file: &str, content: &str) -> bool {
|
||||||
// let full_path = PathBuf::from(self.volume.clone()).join(file);
|
// let full_path = PathBuf::from(self.volume.clone()).join(file);
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
// reset all
|
|
||||||
// reset file
|
|
||||||
// reset folder
|
|
||||||
// reset unknown
|
|
@ -8,7 +8,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
const DEFAULT_STATUS_ARG: StatusArgs = StatusArgs { nostyle: false };
|
const DEFAULT_STATUS_ARG: StatusArgs = StatusArgs { nostyle: false };
|
||||||
|
|
||||||
fn status_expected(config: &Config, staged: Vec<&str>, not_staged: Vec<&str>) {
|
fn status_exepected(config: &Config, staged: Vec<&str>, not_staged: Vec<&str>) {
|
||||||
let res = get_obj_changes(&DEFAULT_STATUS_ARG, config);
|
let res = get_obj_changes(&DEFAULT_STATUS_ARG, config);
|
||||||
|
|
||||||
assert_eq!(res.staged.len(), staged.len());
|
assert_eq!(res.staged.len(), staged.len());
|
||||||
@ -36,15 +36,16 @@ fn simple_file() -> io::Result<()> {
|
|||||||
let mut client = ClientTest::new("status__simple_file").init();
|
let mut client = ClientTest::new("status__simple_file").init();
|
||||||
|
|
||||||
client.add_file("foo", "foo")?;
|
client.add_file("foo", "foo")?;
|
||||||
status_expected(&client.get_config(), vec![], vec!["foo"]);
|
status_exepected(&client.get_config(), vec![], vec!["foo"]);
|
||||||
|
|
||||||
client.exec_ok("add foo");
|
client.exec_ok("add foo");
|
||||||
status_expected(&client.get_config(), vec!["foo"], vec![]);
|
status_exepected(&client.get_config(), vec!["foo"], vec![]);
|
||||||
|
|
||||||
client.ok()
|
client.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore]
|
||||||
fn all_folder() -> io::Result<()> {
|
fn all_folder() -> io::Result<()> {
|
||||||
let mut client = ClientTest::new("status__all_folder").init();
|
let mut client = ClientTest::new("status__all_folder").init();
|
||||||
|
|
||||||
@ -52,10 +53,10 @@ fn all_folder() -> io::Result<()> {
|
|||||||
client.add_file("dir/foo", "foo")?;
|
client.add_file("dir/foo", "foo")?;
|
||||||
client.add_file("dir/bar", "bar")?;
|
client.add_file("dir/bar", "bar")?;
|
||||||
client.add_file("foo", "foo")?;
|
client.add_file("foo", "foo")?;
|
||||||
status_expected(&client.get_config(), vec![], vec!["foo", "dir"]);
|
status_exepected(&client.get_config(), vec![], vec!["foo", "dir"]);
|
||||||
|
|
||||||
client.exec_ok("add dir");
|
client.exec_ok("add dir");
|
||||||
status_expected(&client.get_config(), vec!["dir/foo", "dir/bar"], vec!["foo"]);
|
status_exepected(&client.get_config(), vec!["dir"], vec!["foo"]);
|
||||||
|
|
||||||
client.ok()
|
client.ok()
|
||||||
}
|
}
|
||||||
@ -69,10 +70,10 @@ fn all_folder_current() -> io::Result<()> {
|
|||||||
client.add_file("dir/foo", "foo")?;
|
client.add_file("dir/foo", "foo")?;
|
||||||
client.add_file("dir/bar", "bar")?;
|
client.add_file("dir/bar", "bar")?;
|
||||||
client.add_file("foor", "foor")?;
|
client.add_file("foor", "foor")?;
|
||||||
status_expected(&client.get_config(), vec![], vec!["foor", "dir"]);
|
status_exepected(&client.get_config(), vec![], vec!["foor", "dir"]);
|
||||||
|
|
||||||
client.exec_ok("add dir");
|
client.exec_ok("add dir");
|
||||||
status_expected(
|
status_exepected(
|
||||||
&Config::from(Some(&String::from("./dir"))),
|
&Config::from(Some(&String::from("./dir"))),
|
||||||
vec!["foor", "bar"],
|
vec!["foor", "bar"],
|
||||||
vec!["../foo"],
|
vec!["../foo"],
|
||||||
@ -89,10 +90,10 @@ fn part_of_folder() -> io::Result<()> {
|
|||||||
client.add_file("dir/foo", "foo")?;
|
client.add_file("dir/foo", "foo")?;
|
||||||
client.add_file("dir/bar", "bar")?;
|
client.add_file("dir/bar", "bar")?;
|
||||||
client.add_file("foor", "foor")?;
|
client.add_file("foor", "foor")?;
|
||||||
status_expected(&client.get_config(), vec![], vec!["foor", "dir"]);
|
status_exepected(&client.get_config(), vec![], vec!["foor", "dir"]);
|
||||||
|
|
||||||
client.exec_ok("add dir/foo");
|
client.exec_ok("add dir/foo");
|
||||||
status_expected(
|
status_exepected(
|
||||||
&client.get_config(),
|
&client.get_config(),
|
||||||
vec!["dir/foo"],
|
vec!["dir/foo"],
|
||||||
vec!["foor", "dir/bar"],
|
vec!["foor", "dir/bar"],
|
||||||
@ -102,6 +103,3 @@ fn part_of_folder() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ../folder/file add
|
// ../folder/file add
|
||||||
// force add ignored file
|
|
||||||
// status without ignored file
|
|
||||||
// all folder without ignored file
|
|
||||||
|
Loading…
Reference in New Issue
Block a user