Compare commits
5 Commits
fix-update
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
4533b9a72d | ||
|
980d2d9a5d | ||
|
939b6f2fe3 | ||
|
4504b98112 | ||
|
e8c8ab9dfe |
@ -42,10 +42,13 @@ pub fn add(args: AddArgs) {
|
|||||||
let path = repo_root().join(Path::new(&f));
|
let path = repo_root().join(Path::new(&f));
|
||||||
match path.exists() {
|
match path.exists() {
|
||||||
true => {
|
true => {
|
||||||
add_entry(path, args.force, &mut added_files, rules.clone(), &mut ignored_f);
|
let mut obj = Obj::from_path(f.clone());
|
||||||
|
if obj.has_changes() {
|
||||||
|
add_entry(path, args.force, &mut added_files, rules.clone(), &mut ignored_f);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
if Object::new(path.to_str().unwrap()).exists() {
|
if Obj::from_path(file.clone()).exists_on_remote() {
|
||||||
// object is deleted so not present but can still be added for deletion
|
// object is deleted so not present but can still be added for deletion
|
||||||
added_files.push(String::from(f));
|
added_files.push(String::from(f));
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,7 +28,7 @@ pub fn init() {
|
|||||||
path.push(".nextsync");
|
path.push(".nextsync");
|
||||||
match builder.create(path.clone()) {
|
match builder.create(path.clone()) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(_) => println!("Error: cannot create .nextsync"),
|
Err(err) => println!("Error: cannot create .nextsync ({})", err),
|
||||||
};
|
};
|
||||||
|
|
||||||
path.push("objects");
|
path.push("objects");
|
||||||
@ -59,12 +59,12 @@ pub fn init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo
|
// todo
|
||||||
path.pop();
|
// path.pop();
|
||||||
path.pop();
|
// path.pop();
|
||||||
path.push(".nextsyncignore");
|
// path.push(".nextsyncignore");
|
||||||
|
//
|
||||||
match File::create(path) {
|
// match File::create(path) {
|
||||||
Ok(_) => (),
|
// Ok(_) => (),
|
||||||
Err(_) => println!("Error: cannot create .nextsyncignore"),
|
// Err(_) => println!("Error: cannot create .nextsyncignore"),
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,10 @@ pub fn push() {
|
|||||||
},
|
},
|
||||||
PushState::Done => remove_obj_from_index(obj.clone()),
|
PushState::Done => remove_obj_from_index(obj.clone()),
|
||||||
PushState::Conflict => {
|
PushState::Conflict => {
|
||||||
|
eprintln!("conflict when pushing blob");
|
||||||
// download file
|
// download file
|
||||||
}
|
}
|
||||||
PushState::Error => (),
|
PushState::Error => (eprintln!("error when pushing changes blob")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ impl PushChange for Deleted {
|
|||||||
|
|
||||||
// update tree
|
// update tree
|
||||||
// todo date
|
// todo date
|
||||||
Blob::from_path(obj.path.clone()).rm()?;
|
Blob::from_path(obj.path.clone()).rm_node()?;
|
||||||
|
|
||||||
// remove index
|
// remove index
|
||||||
index::rm_line(obj.path.to_str().unwrap())?;
|
index::rm_line(obj.path.to_str().unwrap())?;
|
||||||
|
@ -73,9 +73,16 @@ pub trait PushChange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// check if remote is newest
|
// check if remote is newest
|
||||||
let last_sync_ts = Blob::from_path(obj.path.clone())
|
let last_sync_ts = {
|
||||||
.saved_remote_ts()
|
if obj.otype == String::from("blob") {
|
||||||
.parse::<i64>().unwrap();
|
Blob::from_path(obj.path.clone())
|
||||||
|
.saved_remote_ts()
|
||||||
|
.parse::<i64>().unwrap()
|
||||||
|
} else {
|
||||||
|
// todo timestamp on tree
|
||||||
|
99999999999999
|
||||||
|
}
|
||||||
|
};
|
||||||
let remote_ts = obj_data.lastmodified.unwrap().timestamp_millis();
|
let remote_ts = obj_data.lastmodified.unwrap().timestamp_millis();
|
||||||
|
|
||||||
if last_sync_ts < remote_ts {
|
if last_sync_ts < remote_ts {
|
||||||
|
@ -160,19 +160,8 @@ pub struct LocalObj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_staged() -> Vec<LocalObj> {
|
pub fn get_all_staged() -> Vec<LocalObj> {
|
||||||
let mut staged_objs = vec![];
|
let mut all_hashes = get_all_objs_hashes();
|
||||||
|
get_staged(&mut all_hashes)
|
||||||
if let Ok(entries) = index::read_line() {
|
|
||||||
for line in entries {
|
|
||||||
|
|
||||||
let obj = Obj::from_path(line.unwrap()).get_local_obj();
|
|
||||||
if obj.state != State::Default {
|
|
||||||
staged_objs.push(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
staged_objs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_staged(hashes: &mut HashMap<String, LocalObj>) -> Vec<LocalObj> {
|
fn get_staged(hashes: &mut HashMap<String, LocalObj>) -> Vec<LocalObj> {
|
||||||
|
@ -26,12 +26,13 @@ pub trait ObjMethods {
|
|||||||
fn get_name(&self) -> String;
|
fn get_name(&self) -> String;
|
||||||
fn get_hash_path(&self) -> String;
|
fn get_hash_path(&self) -> String;
|
||||||
fn get_local_obj(&self) -> LocalObj;
|
fn get_local_obj(&self) -> LocalObj;
|
||||||
fn get_line(&self) -> String;
|
fn get_line(&self, obj_type: ObjType) -> String;
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()>;
|
fn add_ref_to_parent(&self) -> io::Result<()>;
|
||||||
fn rm(&mut self) -> io::Result<()>;
|
fn rm(&mut self) -> io::Result<()>;
|
||||||
fn rm_node(&mut self) -> io::Result<()>;
|
fn rm_node(&mut self) -> io::Result<()>;
|
||||||
fn rm_node_down(&mut self) -> io::Result<()>;
|
fn rm_node_down(&mut self) -> io::Result<()>;
|
||||||
fn exists_on_remote(&mut self) -> bool;
|
fn exists_on_remote(&mut self) -> bool;
|
||||||
|
fn has_changes(&mut self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Obj {
|
pub struct Obj {
|
||||||
@ -89,12 +90,17 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build line for parent reference
|
// build line for parent reference
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, obj_type: ObjType) -> String {
|
||||||
format!("tree {} {}", self.get_hash_path(), self.get_name())
|
let type_str = match obj_type {
|
||||||
|
ObjType::BLOB => "blob",
|
||||||
|
ObjType::TREE => "tree",
|
||||||
|
ObjType::DEFAULT => "default",
|
||||||
|
};
|
||||||
|
format!("{} {} {}", type_str, self.get_hash_path(), self.get_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
let line = self.get_line();
|
let line = self.get_line(self.obj_type);
|
||||||
if self.get_relative_file_path().iter().count() == 1 {
|
if self.get_relative_file_path().iter().count() == 1 {
|
||||||
head::add_line(line)?;
|
head::add_line(line)?;
|
||||||
} else {
|
} else {
|
||||||
@ -104,11 +110,8 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
// remove self object and children object
|
|
||||||
self.rm_node_down();
|
|
||||||
|
|
||||||
// remove parent reference to self
|
// remove parent reference to self
|
||||||
let line = self.get_line();
|
let line = self.get_line(self.obj_type);
|
||||||
if self.get_relative_file_path().iter().count() == 1 {
|
if self.get_relative_file_path().iter().count() == 1 {
|
||||||
head::rm_line(&line)?;
|
head::rm_line(&line)?;
|
||||||
} else {
|
} else {
|
||||||
@ -129,7 +132,21 @@ impl ObjMethods for Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
PathBuf::from(self.get_hash_path()).exists()
|
self.obj_path.exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
if !self.obj_path.exists() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.obj_type {
|
||||||
|
ObjType::BLOB => Blob::from_path(self.relative_file_path.clone()).has_changes(),
|
||||||
|
ObjType::TREE => Tree::from_path(self.relative_file_path.clone()).has_changes(),
|
||||||
|
ObjType::DEFAULT => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,8 +183,8 @@ impl ObjMethods for Blob {
|
|||||||
self.obj.get_hash_path()
|
self.obj.get_hash_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, _: ObjType) -> String {
|
||||||
self.obj.get_line()
|
self.obj.get_line(ObjType::BLOB)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
@ -175,6 +192,8 @@ impl ObjMethods for Blob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
|
// remove self object and children object
|
||||||
|
let _ = self.rm_node_down();
|
||||||
self.obj.rm_node()
|
self.obj.rm_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +215,10 @@ impl ObjMethods for Blob {
|
|||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
self.obj.exists_on_remote()
|
self.obj.exists_on_remote()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
self.obj.has_changes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjMethods for Tree {
|
impl ObjMethods for Tree {
|
||||||
@ -231,8 +254,8 @@ impl ObjMethods for Tree {
|
|||||||
self.obj.get_hash_path()
|
self.obj.get_hash_path()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_line(&self) -> String {
|
fn get_line(&self, _: ObjType) -> String {
|
||||||
self.obj.get_line()
|
self.obj.get_line(ObjType::TREE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_ref_to_parent(&self) -> io::Result<()> {
|
fn add_ref_to_parent(&self) -> io::Result<()> {
|
||||||
@ -240,6 +263,8 @@ impl ObjMethods for Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rm_node(&mut self) -> io::Result<()> {
|
fn rm_node(&mut self) -> io::Result<()> {
|
||||||
|
// remove self object and children object
|
||||||
|
let _ = self.rm_node_down();
|
||||||
self.obj.rm_node()
|
self.obj.rm_node()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,6 +296,10 @@ impl ObjMethods for Tree {
|
|||||||
fn exists_on_remote(&mut self) -> bool {
|
fn exists_on_remote(&mut self) -> bool {
|
||||||
self.obj.exists_on_remote()
|
self.obj.exists_on_remote()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn has_changes(&mut self) -> bool {
|
||||||
|
self.obj.has_changes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Obj {
|
impl Obj {
|
||||||
@ -287,6 +316,7 @@ impl Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_path<S>(path: S) -> Obj where S: IntoPathBuf {
|
pub fn from_path<S>(path: S) -> Obj where S: IntoPathBuf {
|
||||||
|
|
||||||
let path = path.into();
|
let path = path.into();
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
hasher.input_str(path.to_str().unwrap());
|
hasher.input_str(path.to_str().unwrap());
|
||||||
@ -297,8 +327,13 @@ impl Obj {
|
|||||||
obj_path.push(dir);
|
obj_path.push(dir);
|
||||||
obj_path.push(res);
|
obj_path.push(res);
|
||||||
|
|
||||||
|
// set to absolute path if not already
|
||||||
let root = path::repo_root();
|
let root = path::repo_root();
|
||||||
let abs_path = root.join(path.clone());
|
let abs_path = match path.clone().starts_with(root.clone()) {
|
||||||
|
true => path.clone(),
|
||||||
|
false => root.join(path.clone())
|
||||||
|
};
|
||||||
|
|
||||||
Obj {
|
Obj {
|
||||||
name: match abs_path.file_name() {
|
name: match abs_path.file_name() {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
@ -321,9 +356,9 @@ impl Obj {
|
|||||||
|
|
||||||
/// load from the information line stored in the object
|
/// load from the information line stored in the object
|
||||||
pub fn from_line(line: String, base_dir: Option<PathBuf>) -> Box<dyn ObjMethods> {
|
pub fn from_line(line: String, base_dir: Option<PathBuf>) -> Box<dyn ObjMethods> {
|
||||||
let mut split = line.rsplit(' ');
|
let mut split = line.trim().rsplit(' ');
|
||||||
if split.clone().count() != 3 {
|
if split.clone().count() != 3 {
|
||||||
eprintln!("fatal: invalid object(s)");
|
eprintln!("fatal: invalid object(s) ({})", line.trim());
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,14 +42,20 @@ impl Tree {
|
|||||||
if let Ok(file) = File::open(self.get_obj_path()) {
|
if let Ok(file) = File::open(self.get_obj_path()) {
|
||||||
self.buf_reader = Some(BufReader::new(file));
|
self.buf_reader = Some(BufReader::new(file));
|
||||||
|
|
||||||
// skip first line if is head
|
// skip first line (declaration) if is not head
|
||||||
if !self.is_head {
|
if !self.is_head {
|
||||||
self.next();
|
let mut line = String::new();
|
||||||
|
self.buf_reader.as_mut().unwrap().read_line(&mut line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_changes(&mut self) -> bool {
|
||||||
|
todo!();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) -> Option<Box<dyn ObjMethods>> {
|
pub fn next(&mut self) -> Option<Box<dyn ObjMethods>> {
|
||||||
self.read();
|
self.read();
|
||||||
//if let Some(ref mut file) = self.buf_reader {
|
//if let Some(ref mut file) = self.buf_reader {
|
||||||
@ -99,11 +105,11 @@ impl Tree {
|
|||||||
.open(self.get_obj_path())?;
|
.open(self.get_obj_path())?;
|
||||||
|
|
||||||
// update date for all parent
|
// update date for all parent
|
||||||
if up_parent {
|
// if up_parent {
|
||||||
if let Err(err) = update_dates(self.get_relative_file_path(), date) {
|
// if let Err(err) = update_dates(self.get_relative_file_path(), date) {
|
||||||
eprintln!("err: updating parent date of {}: {}", self.get_relative_file_path().display(), err);
|
// eprintln!("err: updating parent date of {}: {}", self.get_relative_file_path().display(), err);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
writeln!(file, "{}", content)?;
|
writeln!(file, "{}", content)?;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use clap::{Arg, ArgMatches, Command};
|
use clap::{Arg, ArgMatches, Command, ArgAction};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::add::AddArgs;
|
use crate::commands::add::AddArgs;
|
||||||
@ -7,7 +7,7 @@ pub fn create() -> Command {
|
|||||||
Command::new("add")
|
Command::new("add")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("files")
|
Arg::new("files")
|
||||||
.required(true)
|
.required_unless_present("all")
|
||||||
.conflicts_with("all")
|
.conflicts_with("all")
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
@ -17,12 +17,14 @@ pub fn create() -> Command {
|
|||||||
Arg::new("force")
|
Arg::new("force")
|
||||||
.short('f')
|
.short('f')
|
||||||
.long("force")
|
.long("force")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.help("Allow adding otherwise ignored files."),
|
.help("Allow adding otherwise ignored files."),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("all")
|
Arg::new("all")
|
||||||
.short('A')
|
.short('A')
|
||||||
.long("all")
|
.long("all")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.help("This adds, modifies, and removes index entries to match the working tree"),
|
.help("This adds, modifies, and removes index entries to match the working tree"),
|
||||||
)
|
)
|
||||||
.about("Add changes to the index")
|
.about("Add changes to the index")
|
||||||
@ -34,7 +36,7 @@ pub fn handler(args: &ArgMatches) {
|
|||||||
None => vec![],
|
None => vec![],
|
||||||
Some(vals) => vals.map(|s| s.to_string()).collect(),
|
Some(vals) => vals.map(|s| s.to_string()).collect(),
|
||||||
},
|
},
|
||||||
force: args.contains_id("force"),
|
force: *args.get_one::<bool>("force").unwrap(),
|
||||||
all: args.contains_id("all"),
|
all: *args.get_one::<bool>("all").unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use clap::{Arg, Command, ArgMatches};
|
use clap::{Arg, Command, ArgMatches, ArgAction};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::remote::RemoteArgs;
|
use crate::commands::remote::RemoteArgs;
|
||||||
@ -26,6 +26,7 @@ pub fn create() -> Command {
|
|||||||
Arg::new("verbose")
|
Arg::new("verbose")
|
||||||
.short('v')
|
.short('v')
|
||||||
.long("verbose")
|
.long("verbose")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
.help("Be a little more verbose and show remote url after name.")
|
.help("Be a little more verbose and show remote url after name.")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -39,7 +40,7 @@ pub fn handler(args: &ArgMatches) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
commands::remote::remote_list(args.contains_id("verbose"));
|
commands::remote::remote_list(*args.get_one::<bool>("verbose").unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,3 +22,9 @@ impl IntoPathBuf for String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoPathBuf for &str {
|
||||||
|
fn into(self) -> PathBuf {
|
||||||
|
PathBuf::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
19
tests/add.rs
19
tests/add.rs
@ -40,6 +40,8 @@ fn collect_status_lines(client: &mut ClientTest) -> Vec<String> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod add_tests {
|
mod add_tests {
|
||||||
|
use crate::utils::{server::ServerTest, status_utils::status_should_be_empty};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -94,4 +96,21 @@ mod add_tests {
|
|||||||
client.clean();
|
client.clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_file_no_changes() {
|
||||||
|
// add a file push it and add it again
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
let _ = client.add_file("file1", "foo");
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
client.run_cmd_ok("add file1");
|
||||||
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
|
clean_test(client, &mut server)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
use utils::{utils::*, server::ServerTest, client::ClientTest};
|
use utils::{utils::*};
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -8,10 +8,7 @@ mod pull_tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_pull() {
|
fn simple_pull() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone());
|
|
||||||
server.init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = server.add_file("file1", "foo");
|
let _ = server.add_file("file1", "foo");
|
||||||
client.run_cmd_ok("pull");
|
client.run_cmd_ok("pull");
|
||||||
@ -19,16 +16,12 @@ mod pull_tests {
|
|||||||
// tests
|
// tests
|
||||||
assert!(client.has_file("file1", "foo"));
|
assert!(client.has_file("file1", "foo"));
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_pull_directory() {
|
fn simple_pull_directory() {
|
||||||
let id = get_random_test_id();
|
let (mut client, mut server) = init_test();
|
||||||
let mut server = ServerTest::new(id.clone());
|
|
||||||
server.init();
|
|
||||||
let mut client = ClientTest::new(id).init();
|
|
||||||
|
|
||||||
let _ = server.add_dir("dir");
|
let _ = server.add_dir("dir");
|
||||||
let _ = server.add_file("dir/file1", "foo");
|
let _ = server.add_file("dir/file1", "foo");
|
||||||
@ -38,7 +31,6 @@ mod pull_tests {
|
|||||||
// tests
|
// tests
|
||||||
assert!(client.has_file("dir/file1", "foo"));
|
assert!(client.has_file("dir/file1", "foo"));
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
use utils::{utils::*, status_utils::*, server::ServerTest, client::ClientTest};
|
use utils::{utils::*, status_utils::*};
|
||||||
|
|
||||||
fn init_test() -> (ClientTest, ServerTest) {
|
|
||||||
let id = get_random_test_id();
|
|
||||||
let mut server = ServerTest::new(id.clone());
|
|
||||||
server.init();
|
|
||||||
let client = ClientTest::new(id).init();
|
|
||||||
(client, server)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod push_tests {
|
mod push_tests {
|
||||||
@ -29,8 +19,7 @@ mod push_tests {
|
|||||||
lines_should_not_contains(staged, "file1");
|
lines_should_not_contains(staged, "file1");
|
||||||
lines_should_not_contains(not_staged, "file1");
|
lines_should_not_contains(not_staged, "file1");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -60,9 +49,7 @@ mod push_tests {
|
|||||||
lines_should_not_contains(staged, "file1");
|
lines_should_not_contains(staged, "file1");
|
||||||
lines_should_not_contains(not_staged, "file1");
|
lines_should_not_contains(not_staged, "file1");
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
client.clean();
|
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -84,8 +71,7 @@ mod push_tests {
|
|||||||
lines_should_not_contains(not_staged.clone(), "file2");
|
lines_should_not_contains(not_staged.clone(), "file2");
|
||||||
lines_should_not_contains(not_staged, "foo");
|
lines_should_not_contains(not_staged, "foo");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -107,8 +93,7 @@ mod push_tests {
|
|||||||
lines_should_not_contains(not_staged.clone(), "file2");
|
lines_should_not_contains(not_staged.clone(), "file2");
|
||||||
lines_should_not_contains(not_staged, "foo");
|
lines_should_not_contains(not_staged, "foo");
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -130,8 +115,7 @@ mod push_tests {
|
|||||||
assert!(staged.len() == 0);
|
assert!(staged.len() == 0);
|
||||||
assert!(not_staged.len() == 0);
|
assert!(not_staged.len() == 0);
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -151,14 +135,34 @@ mod push_tests {
|
|||||||
// remove it
|
// remove it
|
||||||
let _ = client.remove_file("file1");
|
let _ = client.remove_file("file1");
|
||||||
client.run_cmd_ok("add file1");
|
client.run_cmd_ok("add file1");
|
||||||
dbg!(client.get_status());
|
|
||||||
client.run_cmd_ok("push");
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
// tests
|
// tests
|
||||||
assert!(server.has_not_file("file1"));
|
assert!(server.has_not_file("file1"));
|
||||||
status_should_be_empty(&mut client);
|
status_should_be_empty(&mut client);
|
||||||
|
|
||||||
client.clean();
|
clean_test(client, &mut server);
|
||||||
server.clean();
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn push_dir_deletion() {
|
||||||
|
let (mut client, mut server) = init_test();
|
||||||
|
|
||||||
|
// push dir and file2
|
||||||
|
let _ = client.add_dir("dir");
|
||||||
|
let _ = client.add_file("dir/file2", "bar");
|
||||||
|
client.run_cmd_ok("add dir");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
|
||||||
|
// tests
|
||||||
|
assert!(server.has_file("dir/file2", "bar"));
|
||||||
|
|
||||||
|
// push deletion
|
||||||
|
let _ = client.remove_dir("dir");
|
||||||
|
client.run_cmd_ok("add dir");
|
||||||
|
client.run_cmd_ok("push");
|
||||||
|
assert!(server.has_not_dir("dir"));
|
||||||
|
|
||||||
|
clean_test(client, &mut server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,15 @@ impl ClientTest {
|
|||||||
let mut path = self.volume.clone();
|
let mut path = self.volume.clone();
|
||||||
path.push_str("/");
|
path.push_str("/");
|
||||||
path.push_str(name);
|
path.push_str(name);
|
||||||
|
fs::remove_file(path)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fs::remove_file(name)?;
|
pub fn remove_dir(&mut self, name: &str) -> std::io::Result<()> {
|
||||||
|
let mut path = self.volume.clone();
|
||||||
|
path.push_str("/");
|
||||||
|
path.push_str(name);
|
||||||
|
fs::remove_dir_all(path)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,3 +36,15 @@ pub fn has_not_file(full_path: PathBuf, file: &str, test_id: String) -> bool
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn has_not_dir(full_path: PathBuf, dir: &str, test_id: String) -> bool
|
||||||
|
{
|
||||||
|
if full_path.exists() {
|
||||||
|
println!("id: {}", test_id.clone());
|
||||||
|
eprintln!("Dir '{}' exists but it shouldn't", dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -113,5 +113,11 @@ impl ServerTest {
|
|||||||
let full_path = self.volume.clone().join(file);
|
let full_path = self.volume.clone().join(file);
|
||||||
files_utils::has_not_file(full_path, file, self.test_id.clone())
|
files_utils::has_not_file(full_path, file, self.test_id.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_not_dir(&mut self, dir: &str) -> bool {
|
||||||
|
let full_path = self.volume.clone().join(dir);
|
||||||
|
dbg!(full_path.clone());
|
||||||
|
files_utils::has_not_file(full_path, dir, self.test_id.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@ pub fn status_should_be_empty(client: &mut ClientTest) {
|
|||||||
let (staged, not_staged) = client.get_status();
|
let (staged, not_staged) = client.get_status();
|
||||||
if staged.len() != 0 {
|
if staged.len() != 0 {
|
||||||
eprintln!("id: {}", client.test_id.clone());
|
eprintln!("id: {}", client.test_id.clone());
|
||||||
eprintln!("Staged should be empty but has '{}'", staged.len());
|
eprintln!("Staged should be empty but has '{}' line(s)", staged.len());
|
||||||
assert!(staged.len() == 0);
|
assert!(staged.len() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if staged.len() != 0 {
|
if staged.len() != 0 {
|
||||||
eprintln!("id: {}", client.test_id.clone());
|
eprintln!("id: {}", client.test_id.clone());
|
||||||
eprintln!("Not Staged should be empty but has '{}'", not_staged.len());
|
eprintln!("Not Staged should be empty but has '{}' line(s)", not_staged.len());
|
||||||
assert!(not_staged.len() == 0);
|
assert!(not_staged.len() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use rand::{distributions::Alphanumeric, Rng};
|
use rand::{distributions::Alphanumeric, Rng};
|
||||||
|
use super::client::ClientTest;
|
||||||
|
use super::server::ServerTest;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn get_random_test_id() -> String {
|
pub fn get_random_test_id() -> String {
|
||||||
@ -10,3 +12,20 @@ pub fn get_random_test_id() -> String {
|
|||||||
id.push_str("_nextsync");
|
id.push_str("_nextsync");
|
||||||
id.to_owned()
|
id.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn init_test() -> (ClientTest, ServerTest) {
|
||||||
|
|
||||||
|
let id = get_random_test_id();
|
||||||
|
let mut server = ServerTest::new(id.clone());
|
||||||
|
server.init();
|
||||||
|
let client = ClientTest::new(id).init();
|
||||||
|
(client, server)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn clean_test(client: ClientTest, server: &mut ServerTest) {
|
||||||
|
client.clean();
|
||||||
|
server.clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user