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) {
|
pub fn exec(args: StatusArgs, config: Config) {
|
||||||
let status = get_obj_changes(&args, &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 {
|
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 {
|
if objs.staged.len() == 0 && objs.not_staged.len() == 0 {
|
||||||
println!("Nothing to push, working tree clean");
|
println!("Nothing to push, working tree clean");
|
||||||
return;
|
return;
|
||||||
@ -168,7 +168,7 @@ fn print_status(objs: &ObjStaged) {
|
|||||||
// (use "git restore --staged <file>..." to unstage)
|
// (use "git restore --staged <file>..." to unstage)
|
||||||
// by alphabetical order
|
// by alphabetical order
|
||||||
for obj in objs.staged.iter() {
|
for obj in objs.staged.iter() {
|
||||||
print_object(&obj, |status: &str| status.green());
|
print_object(&obj, root_path, |status: &str| status.green());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// modified
|
// modified
|
||||||
@ -178,7 +178,7 @@ fn print_status(objs: &ObjStaged) {
|
|||||||
println!("Changes not staged for push:");
|
println!("Changes not staged for push:");
|
||||||
println!(" (Use \"nextsync add <file>...\" to update what will be pushed)");
|
println!(" (Use \"nextsync add <file>...\" to update what will be pushed)");
|
||||||
for obj in objs.not_staged.iter() {
|
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:");
|
// 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!(
|
println!(
|
||||||
" {}{}",
|
" {}{}",
|
||||||
match obj.get_status() {
|
match obj.get_status() {
|
||||||
@ -201,7 +201,7 @@ fn print_object(obj: &Obj, color: impl Fn(&str) -> ColoredString) {
|
|||||||
ObjStatus::Deleted => color("deleted: "),
|
ObjStatus::Deleted => color("deleted: "),
|
||||||
_ => "unknown".red(),
|
_ => "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 crate::utils::path;
|
||||||
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
@ -26,7 +27,6 @@ impl From<ObjType> for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl TryFrom<u8> for ObjType {
|
impl TryFrom<u8> for ObjType {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
@ -96,6 +96,32 @@ impl Obj {
|
|||||||
&self.obj_path
|
&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 {
|
pub fn cpy_path(&self) -> String {
|
||||||
path::to_string(&self.obj_path)
|
path::to_string(&self.obj_path)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ static REPO_ROOT: OnceLock<PathBuf> = OnceLock::new();
|
|||||||
|
|
||||||
pub fn init(repo_root: &Option<PathBuf>) {
|
pub fn init(repo_root: &Option<PathBuf>) {
|
||||||
if tests::is_var_setup() {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,15 @@ pub fn to_string(path: &PathBuf) -> String {
|
|||||||
path.to_str().unwrap().to_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.
|
/// Improve the path to try remove and solve .. token.
|
||||||
/// Taken from https://stackoverflow.com/questions/68231306/stdfscanonicalize-for-files-that-dont-exist
|
/// Taken from https://stackoverflow.com/questions/68231306/stdfscanonicalize-for-files-that-dont-exist
|
||||||
///
|
///
|
||||||
|
@ -66,6 +66,13 @@ impl ClientTest {
|
|||||||
Config::from(Some(&self.volume))
|
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<()> {
|
pub fn ok(self) -> io::Result<()> {
|
||||||
fs::remove_dir_all(&self.volume)?;
|
fs::remove_dir_all(&self.volume)?;
|
||||||
Ok(())
|
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());
|
assert_eq!(res.not_staged.len(), not_staged.len());
|
||||||
|
|
||||||
for obj in staged {
|
for obj in staged {
|
||||||
assert!(res
|
assert!(
|
||||||
.staged
|
res.staged
|
||||||
.iter()
|
.iter()
|
||||||
.position(|e| { e.get_obj_path() == &PathBuf::from(obj) })
|
.position(|e| {
|
||||||
.is_some());
|
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 {
|
for obj in not_staged {
|
||||||
assert!(res
|
assert!(
|
||||||
.not_staged
|
res.not_staged
|
||||||
.iter()
|
.iter()
|
||||||
.position(|e| { e.get_obj_path() == &PathBuf::from(obj) })
|
.position(|e| {
|
||||||
.is_some());
|
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"]);
|
status_expected(&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_expected(
|
||||||
|
&client.get_config(),
|
||||||
|
vec!["dir/foo", "dir/bar"],
|
||||||
|
vec!["foo"],
|
||||||
|
);
|
||||||
|
|
||||||
client.ok()
|
client.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn all_folder_current() -> io::Result<()> {
|
fn all_folder_current() -> io::Result<()> {
|
||||||
let mut client = ClientTest::new("status__all_folder_current").init();
|
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");
|
client.exec_ok("add dir");
|
||||||
status_expected(
|
status_expected(
|
||||||
&Config::from(Some(&String::from("./dir"))),
|
&client.new_config("dir"),
|
||||||
vec!["foor", "bar"],
|
vec!["dir/foo", "dir/bar"],
|
||||||
vec!["../foo"],
|
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()
|
client.ok()
|
||||||
|
Loading…
Reference in New Issue
Block a user