Compare commits
No commits in common. "b08e6d3898020c855cf74758c50491fd2f90d103" and "da3d605baa8170659401fb27cd3be23f1d939b52" have entirely different histories.
b08e6d3898
...
da3d605baa
@ -17,6 +17,3 @@ regex = "1.8.3"
|
||||
lazy_static = "1.4.0"
|
||||
glob = "0.3.1"
|
||||
chrono = "0.4.26"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
@ -5,10 +5,11 @@ use crate::commands::push::push_factory::{PushFactory, PushState};
|
||||
pub mod push_factory;
|
||||
pub mod new;
|
||||
pub mod new_dir;
|
||||
pub mod rm_dir;
|
||||
pub mod deleted;
|
||||
|
||||
pub fn push() {
|
||||
dbg!(status::get_all_staged());
|
||||
|
||||
let remote = match config::get("remote") {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
@ -21,7 +22,7 @@ pub fn push() {
|
||||
let staged_objs = status::get_all_staged();
|
||||
|
||||
// path that certify that all its children can be push whithout hesistation
|
||||
// (e.g. if remote dir has no changes since last sync all children
|
||||
// (e.g if remote dir has no changes since last sync all children
|
||||
// can be pushed without verification)
|
||||
let mut whitelist: Option<PathBuf> = None;
|
||||
|
||||
|
@ -5,7 +5,6 @@ use crate::store::object;
|
||||
use crate::services::req_props::{ObjProps, ReqProps};
|
||||
use crate::commands::push::new::New;
|
||||
use crate::commands::push::new_dir::NewDir;
|
||||
use crate::commands::push::rm_dir::RmDir;
|
||||
use crate::commands::push::deleted::Deleted;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -104,7 +103,7 @@ impl PushFactory {
|
||||
State::New => Box::new(NewDir { obj }),
|
||||
State::Renamed => todo!(),
|
||||
State::Modified => todo!(),
|
||||
State::Deleted => Box::new(RmDir { obj }),
|
||||
State::Deleted => todo!(),
|
||||
State::Default => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
use std::path::PathBuf;
|
||||
use crate::services::api::ApiError;
|
||||
use crate::services::delete_path::DeletePath;
|
||||
use crate::store::index;
|
||||
use crate::store::object::tree;
|
||||
use crate::commands::status::LocalObj;
|
||||
use crate::commands::push::push_factory::{PushState, PushChange, PushFlowState};
|
||||
|
||||
pub struct RmDir {
|
||||
pub obj: LocalObj
|
||||
}
|
||||
|
||||
impl PushChange for RmDir {
|
||||
fn can_push(&self, whitelist: &mut Option<PathBuf>) -> PushState {
|
||||
match self.flow(&self.obj, whitelist.clone()) {
|
||||
PushFlowState::Whitelisted => PushState::Done,
|
||||
PushFlowState::NotOnRemote => {
|
||||
*whitelist = Some(self.obj.path.clone());
|
||||
PushState::Done
|
||||
},
|
||||
PushFlowState::RemoteIsNewer => PushState::Conflict,
|
||||
PushFlowState::LocalIsNewer => {
|
||||
*whitelist = Some(self.obj.path.clone());
|
||||
PushState::Valid
|
||||
},
|
||||
PushFlowState::Error => PushState::Error,
|
||||
}
|
||||
}
|
||||
|
||||
fn push(&self) {
|
||||
let obj = &self.obj;
|
||||
let res = DeletePath::new()
|
||||
.set_url(obj.path.to_str().unwrap())
|
||||
.send_with_err();
|
||||
|
||||
match res {
|
||||
Err(ApiError::IncorrectRequest(err)) => {
|
||||
eprintln!("fatal: error deleting dir {}: {}", obj.name, err.status());
|
||||
std::process::exit(1);
|
||||
},
|
||||
Err(ApiError::RequestError(_)) => {
|
||||
eprintln!("fatal: request error deleting dir {}", obj.name);
|
||||
std::process::exit(1);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
// update tree
|
||||
tree::rm(&obj.path.clone());
|
||||
// remove index
|
||||
index::rm_line(obj.path.to_str().unwrap());
|
||||
}
|
||||
|
||||
fn conflict(&self) {}
|
||||
}
|
@ -29,21 +29,15 @@ pub enum State {
|
||||
// todo: relative path, filename, get modified
|
||||
// todo: not catch added empty folder
|
||||
pub fn status() {
|
||||
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
||||
let (mut new_objs, mut del_objs) = get_diff();
|
||||
let mut renamed_objs = get_renamed(&mut new_objs, &mut del_objs);
|
||||
// get copy, modified
|
||||
let mut staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
||||
|
||||
let mut objs: Vec<LocalObj> = del_objs_hashes.iter().map(|x| {
|
||||
x.1.clone()
|
||||
}).collect();
|
||||
|
||||
for (_, elt) in new_objs_hashes {
|
||||
objs.push(elt.clone());
|
||||
}
|
||||
|
||||
dbg!(objs.clone());
|
||||
dbg!(staged_objs.clone());
|
||||
let mut objs = new_objs;
|
||||
objs.append(&mut del_objs);
|
||||
objs.append(&mut renamed_objs);
|
||||
let staged_objs = get_staged(&mut objs);
|
||||
print_status(staged_objs, objs);
|
||||
dbg!(get_all_staged());
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -55,63 +49,53 @@ pub struct LocalObj {
|
||||
}
|
||||
|
||||
pub fn get_all_staged() -> Vec<LocalObj> {
|
||||
let (mut new_objs_hashes, mut del_objs_hashes) = get_diff();
|
||||
// get copy, modified
|
||||
let mut staged_objs = get_staged(&mut new_objs_hashes, &mut del_objs_hashes);
|
||||
|
||||
staged_objs.clone()
|
||||
// todo opti getting staged and then finding differences ?
|
||||
// todo opti return folder
|
||||
let (mut new_objs, mut del_objs) = get_diff();
|
||||
let mut renamed_objs = get_renamed(&mut new_objs, &mut del_objs);
|
||||
// todo get copy, modified
|
||||
let mut objs = new_objs;
|
||||
objs.append(&mut del_objs);
|
||||
objs.append(&mut renamed_objs);
|
||||
let staged_objs = get_staged(&mut objs);
|
||||
staged_objs
|
||||
}
|
||||
|
||||
fn get_staged(new_objs_h: &mut HashMap<String, LocalObj>, del_objs_h: &mut HashMap<String, LocalObj>) -> Vec<LocalObj> {
|
||||
let mut lines: Vec<String> = vec![];
|
||||
fn get_renamed(_new_obj: &mut Vec<LocalObj>, _del_obj: &mut Vec<LocalObj>) -> Vec<LocalObj> {
|
||||
// get hash of all new obj, compare to hash of all del
|
||||
let renamed_objs = vec![];
|
||||
renamed_objs
|
||||
}
|
||||
|
||||
fn get_staged(objs: &mut Vec<LocalObj>) -> Vec<LocalObj> {
|
||||
let mut indexes = HashSet::new();
|
||||
let mut staged_objs: Vec<LocalObj> = vec![];
|
||||
|
||||
if let Ok(entries) = index::read_line() {
|
||||
for entry in entries {
|
||||
lines.push(entry.unwrap());
|
||||
indexes.insert(entry.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
dbg!(objs.clone());
|
||||
let mut tree_to_analyse: Vec<LocalObj> = vec![];
|
||||
|
||||
let mut hasher = Sha1::new();
|
||||
let mut staged_objs: Vec<LocalObj> = vec![];
|
||||
|
||||
let ref_p = path::repo_root();
|
||||
for obj in lines {
|
||||
// hash the object
|
||||
hasher.input_str(&obj);
|
||||
let hash = hasher.result_str();
|
||||
hasher.reset();
|
||||
|
||||
// find it on the list of hashes
|
||||
if new_objs_h.contains_key(&hash) {
|
||||
staged_objs.push(new_objs_h.get(&hash).unwrap().clone());
|
||||
new_objs_h.remove(&hash);
|
||||
} else if del_objs_h.contains_key(&hash) {
|
||||
staged_objs.push(del_objs_h.get(&hash).unwrap().clone());
|
||||
del_objs_h.remove(&hash);
|
||||
}else {
|
||||
let mut t_path = ref_p.clone();
|
||||
t_path.push(PathBuf::from(obj.clone()));
|
||||
staged_objs.push(LocalObj {
|
||||
otype: get_otype(t_path.clone()),
|
||||
name: obj.to_string(),
|
||||
path: t_path.clone(),
|
||||
state: {
|
||||
if t_path.exists() {
|
||||
State::New
|
||||
} else {
|
||||
State::Deleted
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
objs.retain(|obj| {
|
||||
if indexes.contains(obj.clone().path.to_str().unwrap()) {
|
||||
if obj.clone().otype == String::from("tree") {
|
||||
tree_to_analyse.push(obj.clone());
|
||||
}
|
||||
staged_objs.push(obj.clone());
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
staged_objs
|
||||
}
|
||||
|
||||
fn get_diff() -> (HashMap<String, LocalObj>, HashMap<String, LocalObj>) {
|
||||
fn get_diff() -> (Vec<LocalObj>, Vec<LocalObj>) {
|
||||
let mut hashes = HashMap::new();
|
||||
let mut objs: Vec<String> = vec![];
|
||||
|
||||
@ -154,31 +138,29 @@ fn get_diff() -> (HashMap<String, LocalObj>, HashMap<String, LocalObj>) {
|
||||
|
||||
}
|
||||
|
||||
for (_, elt) in &mut hashes {
|
||||
elt.state = State::Deleted;
|
||||
}
|
||||
let del_objs: Vec<LocalObj> = hashes.iter().map(|x| {
|
||||
LocalObj {
|
||||
otype: x.1.otype.clone(),
|
||||
name: x.1.name.clone(),
|
||||
path: x.1.path.clone(),
|
||||
state: State::Deleted
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let mut new_objs_hashes = HashMap::new();
|
||||
let mut hasher = Sha1::new();
|
||||
for obj in objs {
|
||||
// hash the object
|
||||
hasher.input_str(&obj);
|
||||
let hash = hasher.result_str();
|
||||
hasher.reset();
|
||||
let p = PathBuf::from(obj.to_string());
|
||||
let new_objs: Vec<LocalObj> = objs.iter().map(|x| {
|
||||
let p = PathBuf::from(x.to_string());
|
||||
// todo name
|
||||
new_objs_hashes.insert(String::from(hash), LocalObj {
|
||||
otype: get_otype(p.clone()),
|
||||
name: obj.to_string(),
|
||||
LocalObj {
|
||||
otype: get_type(p.clone()),
|
||||
name: x.to_string(),
|
||||
path: p,
|
||||
state: State::New
|
||||
});
|
||||
}
|
||||
|
||||
(new_objs_hashes, hashes)
|
||||
}
|
||||
}).collect();
|
||||
(new_objs, del_objs)
|
||||
}
|
||||
|
||||
fn get_otype(p: PathBuf) -> String {
|
||||
fn get_type(p: PathBuf) -> String {
|
||||
if p.is_dir() {
|
||||
String::from("tree")
|
||||
} else {
|
||||
|
@ -3,7 +3,6 @@ use dotenv::dotenv;
|
||||
use reqwest::Client;
|
||||
use reqwest::RequestBuilder;
|
||||
use reqwest::{Response, Error, Method};
|
||||
use reqwest::header::{HeaderValue, CONTENT_TYPE, HeaderMap, IntoHeaderName};
|
||||
use crate::utils::api::ApiProps;
|
||||
use crate::commands::config;
|
||||
use crate::commands::clone::get_url_props;
|
||||
@ -19,7 +18,6 @@ pub enum ApiError {
|
||||
pub struct ApiBuilder {
|
||||
client: Client,
|
||||
request: Option<RequestBuilder>,
|
||||
headers: Option<HeaderMap>
|
||||
}
|
||||
|
||||
impl ApiBuilder {
|
||||
@ -27,7 +25,6 @@ impl ApiBuilder {
|
||||
ApiBuilder {
|
||||
client: Client::new(),
|
||||
request: None,
|
||||
headers: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +40,7 @@ impl ApiBuilder {
|
||||
let mut url = String::from(host);
|
||||
url.push_str("/remote.php/dav/files/");
|
||||
url.push_str(username.unwrap());
|
||||
url.push_str("/");
|
||||
url.push_str(&root);
|
||||
url.push_str("/");
|
||||
url.push_str(path);
|
||||
@ -87,18 +85,11 @@ impl ApiBuilder {
|
||||
},
|
||||
Some(req) => {
|
||||
self.request = Some(req.body(xml_payload));
|
||||
self.set_header(CONTENT_TYPE, HeaderValue::from_static("application/xml"));
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_header<K: IntoHeaderName>(&mut self, key: K, val: HeaderValue) -> &mut ApiBuilder {
|
||||
let map = self.headers.get_or_insert(HeaderMap::new());
|
||||
map.insert(key, val);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_body(&mut self, body: Vec<u8>) -> &mut ApiBuilder {
|
||||
match self.request.take() {
|
||||
None => {
|
||||
@ -120,13 +111,7 @@ impl ApiBuilder {
|
||||
eprintln!("fatal: incorrect request");
|
||||
std::process::exit(1);
|
||||
},
|
||||
Some(req) => {
|
||||
if let Some(headers) = &self.headers {
|
||||
req.headers(headers.clone()).send().await.map_err(Error::from)
|
||||
} else {
|
||||
req.send().await.map_err(Error::from)
|
||||
}
|
||||
},
|
||||
Some(req) => req.send().await.map_err(Error::from),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::io::Cursor;
|
||||
use chrono::{Utc, DateTime};
|
||||
use reqwest::{Method, Response, Error};
|
||||
use xml::reader::{EventReader, XmlEvent};
|
||||
use reqwest::header::HeaderValue;
|
||||
use crate::utils::time::parse_timestamp;
|
||||
use crate::utils::api::{get_relative_s, ApiProps};
|
||||
use crate::services::api::{ApiBuilder, ApiError};
|
||||
@ -103,11 +102,6 @@ impl ReqProps {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_depth(&mut self, depth: &str) -> &mut ReqProps {
|
||||
self.api_builder.set_header("Depth", HeaderValue::from_str(depth).unwrap());
|
||||
self
|
||||
}
|
||||
|
||||
fn validate_xml(&mut self) -> &mut ReqProps {
|
||||
let mut xml = String::from(r#"<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"><d:prop>"#);
|
||||
xml.push_str(&self.xml_payload.clone());
|
||||
@ -144,8 +138,6 @@ impl ReqProps {
|
||||
}
|
||||
|
||||
pub fn send_req_single(&mut self) -> Result<ObjProps, ApiError> {
|
||||
// set depth to 0 as we only need one element
|
||||
self.set_depth("0");
|
||||
match self.send_with_err() {
|
||||
Ok(body) => {
|
||||
let objs = self.parse(body, false);
|
||||
@ -175,8 +167,8 @@ impl ReqProps {
|
||||
} else {
|
||||
// end of balises to get then start over for
|
||||
// next object if want multiple
|
||||
values.push(content.clone());
|
||||
if multiple {
|
||||
values.push(content.clone());
|
||||
iter = self.xml_balises.iter();
|
||||
val = iter.next();
|
||||
content = ObjProps::new();
|
||||
|
@ -45,15 +45,6 @@ fn _object_path(obj: &str) -> PathBuf {
|
||||
root
|
||||
}
|
||||
|
||||
fn rm(hash: &str) -> io::Result<()> {
|
||||
let mut root = path::objects();
|
||||
let (dir, rest) = hash.split_at(2);
|
||||
root.push(dir);
|
||||
root.push(rest);
|
||||
fs::remove_file(root)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rm_node(path: &Path, node: &str) -> io::Result<()> {
|
||||
let mut root = path::objects();
|
||||
let (dir, rest) = hash_obj(path.clone().to_str().unwrap());
|
||||
|
@ -3,7 +3,7 @@ use std::io::{self};
|
||||
use std::path::Path;
|
||||
use crate::utils::{read, path};
|
||||
use crate::store::head;
|
||||
use crate::store::object::{self, parse_path, hash_obj, add_node, create_obj};
|
||||
use crate::store::object::{parse_path, hash_obj, add_node, create_obj};
|
||||
|
||||
pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
||||
let (line, hash, name) = parse_path(path.clone(), false);
|
||||
@ -24,43 +24,6 @@ pub fn add(path: &Path, date: &str) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rm(path: &Path) -> io::Result<()> {
|
||||
let (_, lines) = read(path.to_path_buf().to_str().unwrap().to_string()).unwrap();
|
||||
for line in lines {
|
||||
let (ftype, hash, _) = parse_line(line.unwrap());
|
||||
if ftype == String::from("blob") {
|
||||
object::rm(&hash);
|
||||
} else {
|
||||
rm_hash(hash);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rm_hash(hash: String) {
|
||||
let mut obj_p = path::objects();
|
||||
let (dir, res) = hash.split_at(2);
|
||||
obj_p.push(dir);
|
||||
obj_p.push(res);
|
||||
|
||||
match read::read_lines(obj_p) {
|
||||
Ok(mut reader) => {
|
||||
reader.next();
|
||||
for line in reader {
|
||||
let (ftype, hash, _) = parse_line(line.unwrap());
|
||||
if ftype == String::from("blob") {
|
||||
object::rm(&hash);
|
||||
} else {
|
||||
rm_hash(hash);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("error reading tree: {}", err);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(tree: String) -> Option<(String, io::Lines<io::BufReader<File>>)> {
|
||||
let mut obj_p = path::objects();
|
||||
|
||||
@ -94,4 +57,4 @@ pub fn parse_line(line: String) -> (String, String, String) {
|
||||
let hash = split.next().unwrap();
|
||||
let ftype = split.next().unwrap();
|
||||
(String::from(ftype), String::from(hash), String::from(name))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user