Compare commits

...

2 Commits

Author SHA1 Message Date
grimhilt
29def4967c normalize path in add and check if path correspond to deleted object 2023-07-24 00:49:08 +02:00
grimhilt
2775c77c55 improve status and minor fixes 2023-07-24 00:48:22 +02:00
6 changed files with 104 additions and 13 deletions

View File

@ -1,9 +1,10 @@
use std::io::Write;
use std::path::{Path, PathBuf};
use clap::Values;
use crate::store;
use crate::utils::{self};
use crate::store::{self, object::Object};
use crate::utils;
use crate::utils::nextsyncignore::{self, ignore_file};
use crate::utils::path::{normalize_relative, repo_root};
pub struct AddArgs<'a> {
pub files: Values<'a>,
@ -12,33 +13,48 @@ pub struct AddArgs<'a> {
// todo match deleted files
// todo match weird reg expression
// todo normalize path
pub fn add(args: AddArgs) {
let mut index_file = store::index::open();
let mut added_files: Vec<String> = vec![];
let rules = match nextsyncignore::read_lines() {
Ok(r) => r,
Err(_) => vec![],
};
let mut ignored_f = vec![];
let file_vec: Vec<&str> = args.files.collect();
for file in file_vec {
if !args.force && ignore_file(&file.to_string(), rules.clone(), &mut ignored_f) {
let f = match normalize_relative(file) {
Ok(f) => f,
Err(err) => {
eprintln!("err: {} {}", file, err);
continue;
}
let path = Path::new(file);
};
if !args.force && ignore_file(&f, rules.clone(), &mut ignored_f) {
continue;
}
let path = repo_root().join(Path::new(&f));
match path.exists() {
true => {
if path.is_dir() {
added_files.push(String::from(path.to_str().unwrap()));
added_files.push(f);
add_folder_content(path.to_path_buf(), &mut added_files);
} else {
added_files.push(String::from(path.to_str().unwrap()));
}
},
false => {
// todo deleted file/folder verif if exists
added_files.push(String::from(path.to_str().unwrap()));
if Object::new(path.to_str().unwrap()).exists() {
added_files.push(String::from(f));
} else {
eprintln!("err: {} is not something you can add.", path.to_str().unwrap());
}
}
}
}

View File

@ -9,6 +9,7 @@ pub mod rm_dir;
pub mod deleted;
pub fn push() {
// todo err when pushing new folder
// todo
let _remote = match config::get("remote") {
Some(r) => r,

View File

@ -6,6 +6,7 @@ use crypto::digest::Digest;
use crypto::sha1::Sha1;
use colored::Colorize;
use crate::utils::path;
use crate::store::head;
use crate::utils::read::{read_folder, read_lines};
use crate::store::object::tree;
use crate::store::index;
@ -116,11 +117,11 @@ fn get_diff() -> (HashMap<String, LocalObj>, HashMap<String, LocalObj>) {
let root = path::repo_root();
let nextsync_path = path::nextsync();
let current_p = path::current().unwrap();
// todo use repo_root instead of current
let dist_path = current_p.strip_prefix(root.clone()).unwrap().to_path_buf();
if let Ok(lines) = read_head(nextsync_path.clone()) {
if let Ok(lines) = read_lines(head::path()) {
add_to_hashmap(lines, &mut hashes, dist_path.clone());
}
@ -164,10 +165,12 @@ fn get_diff() -> (HashMap<String, LocalObj>, HashMap<String, LocalObj>) {
hasher.input_str(&obj);
let hash = hasher.result_str();
hasher.reset();
let p = PathBuf::from(obj.to_string());
let abs_p = path::repo_root().join(p.clone());
// todo name
new_objs_hashes.insert(String::from(hash), LocalObj {
otype: get_otype(p.clone()),
otype: get_otype(abs_p),
name: obj.to_string(),
path: p,
state: State::New

View File

@ -4,7 +4,6 @@ use std::fs::{self, OpenOptions};
use crypto::sha1::Sha1;
use crypto::digest::Digest;
use std::io::{Seek, SeekFrom, Read};
use crate::utils::time::parse_timestamp;
use crate::store::head;
use crate::utils::{read, path};

View File

@ -1,3 +1,5 @@
use crate::commands::{clone::get_url_props, config};
#[derive(Debug)]
pub struct ApiProps {
pub host: String, // nextcloud.example.com
@ -15,6 +17,23 @@ impl Clone for ApiProps {
}
}
pub fn get_api_props() -> ApiProps {
let remote = match config::get("remote") {
Some(r) => r,
None => {
eprintln!("fatal: unable to find a remote");
std::process::exit(1);
}
};
let (host, username, root) = get_url_props(&remote);
ApiProps {
host,
username: username.unwrap().to_owned(),
root: root.to_owned(),
}
}
pub fn get_relative_s(p: String, api_props: &ApiProps) -> String {
let mut final_p = p.clone();
final_p = final_p.strip_prefix("/remote.php/dav/files/").unwrap().to_string();

View File

@ -1,8 +1,61 @@
use std::env;
use std::fs::canonicalize;
use std::path::{PathBuf, Path};
use std::path::{PathBuf, Path, Component};
use crate::global::global::DIR_PATH;
/// Improve the path to try remove and solve .. token.
/// Taken from https://stackoverflow.com/questions/68231306/stdfscanonicalize-for-files-that-dont-exist
///
/// This assumes that `a/b/../c` is `a/c` which might be different from
/// what the OS would have chosen when b is a link. This is OK
/// for broot verb arguments but can't be generally used elsewhere
///
/// 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 mut normalized = PathBuf::new();
for component in path.as_ref().components() {
match &component {
Component::ParentDir => {
if !normalized.pop() {
normalized.push(component);
}
}
_ => {
normalized.push(component);
}
}
}
if ends_with_slash {
normalized.push("");
}
normalized
}
pub fn normalize_relative(file: &str) -> Result<String, String> {
let current = match current() {
Some(p) => p,
None => {
return Err("cannot find current location".to_owned());
}
};
let p = {
let tmp_p = current.join(PathBuf::from(file));
normalize_path(tmp_p)
};
let relative_p = match p.strip_prefix(repo_root()) {
Ok(p) => p,
Err(_) => return Err("is not in a nextsync repo or doesn't exist".to_owned()),
};
Ok(relative_p.to_str().unwrap().to_owned())
}
pub fn current() -> Option<PathBuf> {
let d = DIR_PATH.lock().unwrap();