diff --git a/lib/src/testutils.rs b/lib/src/testutils.rs index 1dda6a73d..2f82fc962 100644 --- a/lib/src/testutils.rs +++ b/lib/src/testutils.rs @@ -60,14 +60,13 @@ pub fn init_repo(settings: &UserSettings, use_git: bool) -> TestWorkspace { let workspace_root = temp_dir.path().join("repo"); fs::create_dir(&workspace_root).unwrap(); - let repo = if use_git { + let (workspace, repo) = if use_git { let git_path = temp_dir.path().join("git-repo"); git2::Repository::init(&git_path).unwrap(); - ReadonlyRepo::init_external_git(settings, workspace_root.clone(), git_path).unwrap() + Workspace::init_external_git(settings, workspace_root, git_path).unwrap() } else { - ReadonlyRepo::init_local(settings, workspace_root.clone()).unwrap() + Workspace::init_local(settings, workspace_root).unwrap() }; - let workspace = Workspace::load(settings, workspace_root).unwrap(); TestWorkspace { temp_dir, diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index e9783dd41..66bc7ce66 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -13,8 +13,9 @@ // limitations under the License. use std::path::PathBuf; +use std::sync::Arc; -use crate::repo::{RepoLoadError, RepoLoader}; +use crate::repo::{ReadonlyRepo, RepoInitError, RepoLoadError, RepoLoader}; use crate::settings::UserSettings; use crate::working_copy::WorkingCopy; @@ -29,6 +30,38 @@ pub struct Workspace { } impl Workspace { + pub fn init_local( + user_settings: &UserSettings, + workspace_root: PathBuf, + ) -> Result<(Self, Arc), RepoInitError> { + let repo = ReadonlyRepo::init_local(user_settings, workspace_root.clone())?; + let repo_loader = repo.loader(); + let workspace = Self::from_repo_loader(workspace_root, repo_loader); + Ok((workspace, repo)) + } + + pub fn init_internal_git( + user_settings: &UserSettings, + workspace_root: PathBuf, + ) -> Result<(Self, Arc), RepoInitError> { + let repo = ReadonlyRepo::init_internal_git(user_settings, workspace_root.clone())?; + let repo_loader = repo.loader(); + let workspace = Self::from_repo_loader(workspace_root, repo_loader); + Ok((workspace, repo)) + } + + pub fn init_external_git( + user_settings: &UserSettings, + workspace_root: PathBuf, + git_repo_path: PathBuf, + ) -> Result<(Self, Arc), RepoInitError> { + let repo = + ReadonlyRepo::init_external_git(user_settings, workspace_root.clone(), git_repo_path)?; + let repo_loader = repo.loader(); + let workspace = Self::from_repo_loader(workspace_root, repo_loader); + Ok((workspace, repo)) + } + pub fn load( user_settings: &UserSettings, workspace_root: PathBuf, @@ -36,17 +69,21 @@ impl Workspace { // TODO: Move the find_repo_dir() call from RepoLoader::init() to here let repo_loader = RepoLoader::init(user_settings, workspace_root)?; let workspace_root = repo_loader.working_copy_path().clone(); - let working_copy_state_path = repo_path.join("working_copy"); + Ok(Self::from_repo_loader(workspace_root, repo_loader)) + } + + fn from_repo_loader(workspace_root: PathBuf, repo_loader: RepoLoader) -> Self { + let working_copy_state_path = repo_loader.repo_path().join("working_copy"); let working_copy = WorkingCopy::load( repo_loader.store().clone(), workspace_root.clone(), working_copy_state_path, ); - Ok(Self { + Self { workspace_root, repo_loader, working_copy, - }) + } } pub fn workspace_root(&self) -> &PathBuf { diff --git a/lib/tests/test_init.rs b/lib/tests/test_init.rs index e03d35ade..c566a28f6 100644 --- a/lib/tests/test_init.rs +++ b/lib/tests/test_init.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use jujutsu_lib::repo::ReadonlyRepo; use jujutsu_lib::settings::UserSettings; use jujutsu_lib::testutils; +use jujutsu_lib::workspace::Workspace; use test_case::test_case; #[test] @@ -22,10 +22,10 @@ fn test_init_local() { let settings = testutils::user_settings(); let temp_dir = tempfile::tempdir().unwrap(); let wc_path = temp_dir.path().to_owned(); - let repo = ReadonlyRepo::init_local(&settings, wc_path.clone()).unwrap(); + let (workspace, repo) = Workspace::init_local(&settings, wc_path.clone()).unwrap(); assert!(repo.store().git_repo().is_none()); - assert_eq!(repo.working_copy_path(), &wc_path); assert_eq!(repo.repo_path(), &wc_path.join(".jj")); + assert_eq!(workspace.workspace_root(), &wc_path); // Just test that we can write a commit to the store let mut tx = repo.start_transaction("test"); @@ -38,10 +38,10 @@ fn test_init_internal_git() { let settings = testutils::user_settings(); let temp_dir = tempfile::tempdir().unwrap(); let wc_path = temp_dir.path().to_owned(); - let repo = ReadonlyRepo::init_internal_git(&settings, wc_path.clone()).unwrap(); + let (workspace, repo) = Workspace::init_internal_git(&settings, wc_path.clone()).unwrap(); assert!(repo.store().git_repo().is_some()); - assert_eq!(repo.working_copy_path(), &wc_path); assert_eq!(repo.repo_path(), &wc_path.join(".jj")); + assert_eq!(workspace.workspace_root(), &wc_path); // Just test that we ca write a commit to the store let mut tx = repo.start_transaction("test"); @@ -57,10 +57,11 @@ fn test_init_external_git() { git2::Repository::init(&git_repo_path).unwrap(); let wc_path = temp_dir.path().join("jj"); std::fs::create_dir(&wc_path).unwrap(); - let repo = ReadonlyRepo::init_external_git(&settings, wc_path.clone(), git_repo_path).unwrap(); + let (workspace, repo) = + Workspace::init_external_git(&settings, wc_path.clone(), git_repo_path).unwrap(); assert!(repo.store().git_repo().is_some()); - assert_eq!(repo.working_copy_path(), &wc_path); assert_eq!(repo.repo_path(), &wc_path.join(".jj")); + assert_eq!(workspace.workspace_root(), &wc_path); // Just test that we can write a commit to the store let mut tx = repo.start_transaction("test"); diff --git a/src/commands.rs b/src/commands.rs index 597f68157..2ed5eed26 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1384,20 +1384,19 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &ArgMatches) -> Result<( if let Some(git_store_str) = args.value_of("git-store") { let git_store_path = ui.cwd().join(git_store_str); - let repo = ReadonlyRepo::init_external_git(ui.settings(), wc_path.clone(), git_store_path)?; + let (workspace, repo) = + Workspace::init_external_git(ui.settings(), wc_path.clone(), git_store_path)?; let git_repo = repo.store().git_repo().unwrap(); - let workspace = Workspace::load(ui.settings(), wc_path.clone()).unwrap(); let mut workspace_command = command.for_loaded_repo(ui, workspace, repo); let mut tx = workspace_command.start_transaction("import git refs"); git::import_refs(tx.mut_repo(), &git_repo).unwrap(); // TODO: Check out a recent commit. Maybe one with the highest generation // number. workspace_command.finish_transaction(ui, tx)?; - workspace_command.repo } else if args.is_present("git") { - ReadonlyRepo::init_internal_git(ui.settings(), wc_path.clone())? + Workspace::init_internal_git(ui.settings(), wc_path.clone())?; } else { - ReadonlyRepo::init_local(ui.settings(), wc_path.clone())? + Workspace::init_local(ui.settings(), wc_path.clone())?; }; writeln!(ui, "Initialized repo in \"{}\"", wc_path.display())?; Ok(()) @@ -3526,10 +3525,9 @@ fn cmd_git_clone( fs::create_dir(&wc_path).unwrap(); } - let repo = ReadonlyRepo::init_internal_git(ui.settings(), wc_path.clone())?; + let (workspace, repo) = Workspace::init_internal_git(ui.settings(), wc_path.clone())?; let git_repo = get_git_repo(repo.store())?; writeln!(ui, "Fetching into new repo in {:?}", wc_path)?; - let workspace = Workspace::load(ui.settings(), wc_path).unwrap(); let mut workspace_command = command.for_loaded_repo(ui, workspace, repo); let remote_name = "origin"; git_repo.remote(remote_name, source).unwrap();