feat(status): relative path of obj
This commit is contained in:
parent
e66dc8d408
commit
8f636b4bf7
@ -106,7 +106,7 @@ fn setup_staged(obj_statuses: Arc<ObjStatuses>, indexer: &Indexer) -> ObjStaged
|
||||
|
||||
pub fn exec(args: StatusArgs, config: Config) {
|
||||
let status = get_obj_changes(&args, &config);
|
||||
print_status(&status);
|
||||
print_status(&status, config.get_root_unsafe());
|
||||
}
|
||||
|
||||
pub fn get_obj_changes(args: &StatusArgs, config: &Config) -> ObjStaged {
|
||||
@ -156,7 +156,7 @@ pub fn get_obj_changes(args: &StatusArgs, config: &Config) -> ObjStaged {
|
||||
}
|
||||
|
||||
///
|
||||
fn print_status(objs: &ObjStaged) {
|
||||
fn print_status(objs: &ObjStaged, root_path: &PathBuf) {
|
||||
if objs.staged.len() == 0 && objs.not_staged.len() == 0 {
|
||||
println!("Nothing to push, working tree clean");
|
||||
return;
|
||||
@ -168,7 +168,7 @@ fn print_status(objs: &ObjStaged) {
|
||||
// (use "git restore --staged <file>..." to unstage)
|
||||
// by alphabetical order
|
||||
for obj in objs.staged.iter() {
|
||||
print_object(&obj, |status: &str| status.green());
|
||||
print_object(&obj, root_path, |status: &str| status.green());
|
||||
}
|
||||
}
|
||||
// modified
|
||||
@ -178,7 +178,7 @@ fn print_status(objs: &ObjStaged) {
|
||||
println!("Changes not staged for push:");
|
||||
println!(" (Use \"nextsync add <file>...\" to update what will be pushed)");
|
||||
for obj in objs.not_staged.iter() {
|
||||
print_object(&obj, |status: &str| status.red());
|
||||
print_object(&obj, root_path, |status: &str| status.red());
|
||||
}
|
||||
|
||||
// println!("Untracked files:");
|
||||
@ -187,7 +187,7 @@ fn print_status(objs: &ObjStaged) {
|
||||
// }
|
||||
}
|
||||
|
||||
fn print_object(obj: &Obj, color: impl Fn(&str) -> ColoredString) {
|
||||
fn print_object(obj: &Obj, root_path: &PathBuf, color: impl Fn(&str) -> ColoredString) {
|
||||
println!(
|
||||
" {}{}",
|
||||
match obj.get_status() {
|
||||
@ -201,7 +201,7 @@ fn print_object(obj: &Obj, color: impl Fn(&str) -> ColoredString) {
|
||||
ObjStatus::Deleted => color("deleted: "),
|
||||
_ => "unknown".red(),
|
||||
},
|
||||
color(&obj.cpy_path().to_string())
|
||||
color(&path::to_string(&obj.get_env_relative_path(root_path)))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::store::{structs::ObjPath, nsobject::NsObject};
|
||||
use crate::store::{nsobject::NsObject, structs::ObjPath};
|
||||
use crate::utils::path;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
@ -26,7 +27,6 @@ impl From<ObjType> for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl TryFrom<u8> for ObjType {
|
||||
type Error = String;
|
||||
|
||||
@ -96,6 +96,32 @@ impl Obj {
|
||||
&self.obj_path
|
||||
}
|
||||
|
||||
/// Return the path of the current object relatively to the path the
|
||||
/// command was executed from.
|
||||
///
|
||||
/// * `repo_root`: the absolute repo's root path
|
||||
pub fn get_env_relative_path(&self, repo_root: &PathBuf) -> PathBuf {
|
||||
let binding = env::current_dir().unwrap();
|
||||
|
||||
if let Ok(root_diff) = binding.strip_prefix(repo_root) {
|
||||
match self.obj_path.strip_prefix(&root_diff) {
|
||||
Ok(path) => path.to_path_buf(),
|
||||
Err(_) => {
|
||||
// if cannot strip prefix then we need to go up to the root
|
||||
let mut res_path = PathBuf::new();
|
||||
for _ in 0..path::get_level(&root_diff.to_path_buf()) {
|
||||
res_path.push("..");
|
||||
}
|
||||
res_path.push(&*self.obj_path);
|
||||
res_path
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if cannot strip prefix then we are at the repo's root
|
||||
self.obj_path.to_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cpy_path(&self) -> String {
|
||||
path::to_string(&self.obj_path)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ 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();
|
||||
REPO_ROOT_DEV.lock().unwrap()[0] = repo_root.clone().expect("Tried to initialize REPO_ROOT_DEV without a proper `repo_root`");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,15 @@ pub fn to_string(path: &PathBuf) -> String {
|
||||
path.to_str().unwrap().to_string()
|
||||
}
|
||||
|
||||
pub fn get_level(path: &PathBuf) -> i32 {
|
||||
let mut level = 0;
|
||||
let mut path = path.clone();
|
||||
while path.pop() {
|
||||
level += 1;
|
||||
}
|
||||
level
|
||||
}
|
||||
|
||||
/// Improve the path to try remove and solve .. token.
|
||||
/// Taken from https://stackoverflow.com/questions/68231306/stdfscanonicalize-for-files-that-dont-exist
|
||||
///
|
||||
|
@ -66,6 +66,13 @@ impl ClientTest {
|
||||
Config::from(Some(&self.volume))
|
||||
}
|
||||
|
||||
pub fn new_config(&self, path: &str) -> Config {
|
||||
let mut full_path = self.volume.clone();
|
||||
full_path.push_str("/");
|
||||
full_path.push_str(path);
|
||||
Config::from(Some(&full_path))
|
||||
}
|
||||
|
||||
pub fn ok(self) -> io::Result<()> {
|
||||
fs::remove_dir_all(&self.volume)?;
|
||||
Ok(())
|
||||
|
@ -15,19 +15,35 @@ fn status_expected(config: &Config, staged: Vec<&str>, not_staged: Vec<&str>) {
|
||||
assert_eq!(res.not_staged.len(), not_staged.len());
|
||||
|
||||
for obj in staged {
|
||||
assert!(res
|
||||
.staged
|
||||
.iter()
|
||||
.position(|e| { e.get_obj_path() == &PathBuf::from(obj) })
|
||||
.is_some());
|
||||
assert!(
|
||||
res.staged
|
||||
.iter()
|
||||
.position(|e| {
|
||||
e.get_env_relative_path(config.get_root_unsafe()) == PathBuf::from(obj)
|
||||
})
|
||||
.is_some(),
|
||||
"{:?}",
|
||||
res.staged
|
||||
.iter()
|
||||
.map(|e| { e.get_env_relative_path(config.get_root_unsafe()) })
|
||||
.collect::<Vec<PathBuf>>()
|
||||
);
|
||||
}
|
||||
|
||||
for obj in not_staged {
|
||||
assert!(res
|
||||
.not_staged
|
||||
.iter()
|
||||
.position(|e| { e.get_obj_path() == &PathBuf::from(obj) })
|
||||
.is_some());
|
||||
assert!(
|
||||
res.not_staged
|
||||
.iter()
|
||||
.position(|e| {
|
||||
e.get_env_relative_path(config.get_root_unsafe()) == PathBuf::from(obj)
|
||||
})
|
||||
.is_some(),
|
||||
"{:?}",
|
||||
res.not_staged
|
||||
.iter()
|
||||
.map(|e| { e.get_env_relative_path(config.get_root_unsafe()) })
|
||||
.collect::<Vec<PathBuf>>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,13 +71,16 @@ fn all_folder() -> io::Result<()> {
|
||||
status_expected(&client.get_config(), vec![], vec!["foo", "dir"]);
|
||||
|
||||
client.exec_ok("add dir");
|
||||
status_expected(&client.get_config(), vec!["dir/foo", "dir/bar"], vec!["foo"]);
|
||||
status_expected(
|
||||
&client.get_config(),
|
||||
vec!["dir/foo", "dir/bar"],
|
||||
vec!["foo"],
|
||||
);
|
||||
|
||||
client.ok()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn all_folder_current() -> io::Result<()> {
|
||||
let mut client = ClientTest::new("status__all_folder_current").init();
|
||||
|
||||
@ -73,9 +92,31 @@ fn all_folder_current() -> io::Result<()> {
|
||||
|
||||
client.exec_ok("add dir");
|
||||
status_expected(
|
||||
&Config::from(Some(&String::from("./dir"))),
|
||||
vec!["foor", "bar"],
|
||||
vec!["../foo"],
|
||||
&client.new_config("dir"),
|
||||
vec!["dir/foo", "dir/bar"],
|
||||
vec![],
|
||||
);
|
||||
|
||||
client.ok()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn relative_path() -> io::Result<()> {
|
||||
let mut client = ClientTest::new("status__all_folder_current").init();
|
||||
|
||||
client.add_dir("dir")?;
|
||||
client.add_file("dir/foo", "foo")?;
|
||||
client.add_file("dir/bar", "bar")?;
|
||||
client.add_file("foor", "foor")?;
|
||||
status_expected(&client.get_config(), vec![], vec!["foor", "dir"]);
|
||||
|
||||
client.exec_ok("add dir");
|
||||
// client.set_execution_path("dir");
|
||||
status_expected(
|
||||
&client.new_config("dir"),
|
||||
vec!["foo", "bar"],
|
||||
vec!["../foor"],
|
||||
);
|
||||
|
||||
client.ok()
|
||||
|
Loading…
Reference in New Issue
Block a user