#[cfg(test)]
mod tests {
use std::path::PathBuf;
use crate::config::UserConfig;
use crate::error::OxenError;
use crate::model::NewCommitBody;
use crate::model::staged_data::StagedDataOpts;
use crate::opts::clone_opts::CloneOpts;
use crate::{api, repositories, test, util};
#[tokio::test]
async fn test_remote_mode_add_file_with_full_path() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let file_path = test::add_txt_file_to_dir(&cloned_repo.path, "new file contents")?;
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 1);
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![file_path],
&Some(cloned_repo.clone()),
)
.await?;
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 0);
assert_eq!(status.staged_files.len(), 1);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_file_with_relative_path() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let file_path = test::add_txt_file_to_dir(&cloned_repo.path, "new file contents")?;
let relative_path =
util::fs::path_relative_to_dir(&file_path, cloned_repo.path.clone())?;
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![relative_path],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 0);
assert_eq!(status.staged_files.len(), 1);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_file_with_canon_path() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let file_path = test::add_txt_file_to_dir(&cloned_repo.path, "new file contents")?;
let canon_path = util::fs::canonicalize(&file_path)?;
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![canon_path],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 0);
assert_eq!(status.staged_files.len(), 1);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_and_modify_file_in_new_subdir() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let subdir_path = PathBuf::from("new").join("dir");
util::fs::create_dir_all(&subdir_path)?;
let file_path = subdir_path.join("new_file.csv");
let full_path = cloned_repo.path.join(&file_path);
let file_contents = "cateory_1,category_2,category_3\nnew,file,contents";
util::fs::write_to_path(&full_path, file_contents)?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let directory = String::from(".");
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&PathBuf::from("."),
&status_opts,
)
.await?;
status.print_with_params(&status_opts);
assert_eq!(status.staged_files.len(), 0);
assert_eq!(status.staged_dirs.len(), 0);
assert_eq!(status.modified_files.len(), 0);
assert_eq!(status.untracked_dirs.len(), 1);
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![full_path.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print_with_params(&status_opts);
assert_eq!(status.staged_files.len(), 1);
assert_eq!(status.staged_dirs.len(), 1);
assert_eq!(status.modified_files.len(), 0);
assert_eq!(status.untracked_dirs.len(), 0);
assert!(status.staged_files.contains_key(&file_path));
let file_contents = "file,label\ntrain/cat_1.jpg,1000";
test::modify_txt_file(&full_path, file_contents)?;
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![full_path.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print_with_params(&status_opts);
assert_eq!(status.staged_files.len(), 1);
assert_eq!(status.staged_dirs.len(), 1);
assert_eq!(status.untracked_dirs.len(), 0);
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![full_path.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print_with_params(&status_opts);
assert_eq!(status.staged_files.len(), 1);
assert_eq!(status.staged_dirs.len(), 1);
assert_eq!(status.modified_files.len(), 0);
assert_eq!(status.untracked_dirs.len(), 0);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_multiple_files_in_sub_dir() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
let training_data_dir = PathBuf::from("training_data");
let sub_dir = cloned_repo.path.join(&training_data_dir);
util::fs::create_dir_all(&sub_dir)?;
let sub_file_1 = test::add_txt_file_to_dir(&sub_dir, "Hello")?;
let sub_file_2 = test::add_txt_file_to_dir(&sub_dir, "World")?;
let sub_file_3 = test::add_txt_file_to_dir(&sub_dir, "!")?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
assert_eq!(status.untracked_dirs.len(), 1);
assert_eq!(status.staged_files.len(), 0);
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![sub_file_1, sub_file_2, sub_file_3],
&Some(cloned_repo.clone()),
)
.await?;
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_dirs.len(), 0);
assert_eq!(status.staged_files.len(), 3);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_files_with_glob_path() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
let repo_dir = cloned_repo.path.clone();
let _file_1 = test::add_txt_file_to_dir(&repo_dir, "Hello")?;
let _file_2 = test::add_txt_file_to_dir(&repo_dir, "World")?;
let _file_3 = test::add_txt_file_to_dir(&repo_dir, "!")?;
let training_data_dir = PathBuf::from("training_data");
let sub_dir = cloned_repo.path.join(&training_data_dir);
util::fs::create_dir_all(&sub_dir)?;
let _sub_file_1 = test::add_txt_file_to_dir(&sub_dir, "Hello")?;
let _sub_file_2 = test::add_txt_file_to_dir(&sub_dir, "World")?;
let _sub_file_3 = test::add_txt_file_to_dir(&sub_dir, "!")?;
let glob_path = PathBuf::from("*");
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![glob_path],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 0);
assert_eq!(status.untracked_dirs.len(), 0);
assert_eq!(status.staged_files.len(), 6);
assert_eq!(status.staged_dirs.len(), 2);
let file_path = PathBuf::from("new_file.txt");
let full_path = cloned_repo.path.join(&file_path);
let file_content = "new file".to_string();
test::write_txt_file_to_path(&full_path, &file_content)?;
let excluded_path = PathBuf::from("excluded.txt");
let excluded_full_path = cloned_repo.path.join(&excluded_path);
let excluded_content = "excluded".to_string();
test::write_txt_file_to_path(&excluded_full_path, &excluded_content)?;
let dir_path = PathBuf::from("new_dir");
let full_dir_path = cloned_repo.path.join(&dir_path);
util::fs::create_dir_all(&full_dir_path)?;
let embedded_file = PathBuf::from("embedded.txt");
let embedded_full_path = full_dir_path.join(embedded_file);
let embedded_content = "embedded file".to_string();
test::write_txt_file_to_path(&embedded_full_path, &embedded_content)?;
let glob_path2 = PathBuf::from("n*");
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![glob_path2],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.untracked_files.len(), 1);
assert_eq!(status.untracked_dirs.len(), 0);
assert_eq!(status.staged_files.len(), 8);
assert_eq!(status.staged_dirs.len(), 3);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_add_dir_recursive() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
let new_dir = cloned_repo.path.join("new");
let train_dir = new_dir.join("train");
let test_dir = new_dir.join("test");
util::fs::create_dir_all(&train_dir)?;
util::fs::create_dir_all(&test_dir)?;
let _ = test::add_txt_file_to_dir(&new_dir, "text 1")?;
let _ = test::add_txt_file_to_dir(&train_dir, "text 2")?;
let _ = test::add_txt_file_to_dir(&train_dir, "text 3")?;
let _ = test::add_txt_file_to_dir(&test_dir, "text 4")?;
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![new_dir.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert_eq!(status.staged_dirs.len(), 3);
assert_eq!(status.staged_files.len(), 4);
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
#[tokio::test]
async fn test_remote_mode_cannot_add_if_not_modified() -> Result<(), OxenError> {
test::run_remote_repo_test_bounding_box_csv_pushed(|_local_repo, remote_repo| async move {
let remote_repo_copy = remote_repo.clone();
test::run_empty_dir_test_async(|dir| async move {
let mut opts = CloneOpts::new(&remote_repo.remote.url, dir.join("new_repo"));
opts.is_remote = true;
let cloned_repo = repositories::clone(&opts).await?;
assert!(cloned_repo.is_remote_mode());
let workspace_identifier = cloned_repo.workspace_name.clone().unwrap();
let directory = ".".to_string();
let dir_path = cloned_repo.path.join("dir");
util::fs::create_dir_all(&dir_path)?;
let hello_file_path = test::add_txt_file_to_dir(&dir_path, "hello.txt")?;
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![hello_file_path.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let cfg = UserConfig::get()?;
let body = NewCommitBody {
message: "Add text file".to_string(),
author: cfg.name,
email: cfg.email,
};
repositories::remote_mode::commit(&cloned_repo, &body).await?;
api::client::workspaces::files::add(
&remote_repo,
&workspace_identifier,
&directory,
vec![hello_file_path.clone()],
&Some(cloned_repo.clone()),
)
.await?;
let status_opts =
StagedDataOpts::from_paths_remote_mode(&[cloned_repo.path.clone()]);
let status = repositories::remote_mode::status(
&cloned_repo,
&remote_repo,
&workspace_identifier,
&directory,
&status_opts,
)
.await?;
status.print();
assert!(status.is_clean());
Ok(())
})
.await?;
Ok(remote_repo_copy)
})
.await
}
}