diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 37d1b8776..5c77603a2 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -614,6 +614,18 @@ impl CommandHelper { self.for_loaded_repo(ui, workspace, repo) } + pub fn get_working_copy_factory(&self) -> Result<&dyn WorkingCopyFactory, CommandError> { + let loader = self.workspace_loader()?; + + // We convert StoreLoadError -> WorkspaceLoadError -> CommandError + let factory: Result<_, WorkspaceLoadError> = loader + .get_working_copy_factory(&self.working_copy_factories) + .map_err(|e| e.into()); + let factory = factory + .map_err(|err| map_workspace_load_error(err, self.global_args.repository.as_deref()))?; + Ok(factory) + } + #[instrument(skip_all)] pub fn load_workspace(&self) -> Result { let loader = self.workspace_loader()?; diff --git a/cli/src/commands/workspace.rs b/cli/src/commands/workspace.rs index 585b8519e..334de480d 100644 --- a/cli/src/commands/workspace.rs +++ b/cli/src/commands/workspace.rs @@ -23,7 +23,7 @@ use jj_lib::object_id::ObjectId; use jj_lib::op_store::WorkspaceId; use jj_lib::repo::Repo; use jj_lib::rewrite::merge_commit_trees; -use jj_lib::workspace::{default_working_copy_factory, Workspace}; +use jj_lib::workspace::Workspace; use tracing::instrument; use crate::cli_util::{ @@ -148,12 +148,13 @@ fn cmd_workspace_add( "Workspace named '{name}' already exists" ))); } - // TODO: How do we create a workspace with a non-default working copy? + + let working_copy_factory = command.get_working_copy_factory()?; let (new_workspace, repo) = Workspace::init_workspace_with_existing_repo( command.settings(), &destination_path, repo, - &*default_working_copy_factory(), + working_copy_factory, workspace_id, )?; writeln!( diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index 752d2a542..7fc65c8c5 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -484,25 +484,33 @@ impl WorkspaceLoader { Ok(workspace) } - fn load_working_copy( + pub fn get_working_copy_factory<'a>( &self, - store: &Arc, - working_copy_factories: &HashMap>, - ) -> Result, StoreLoadError> { + working_copy_factories: &'a HashMap>, + ) -> Result<&'a dyn WorkingCopyFactory, StoreLoadError> { // For compatibility with existing repos. TODO: Delete default in 0.17+ let working_copy_type = read_store_type_compat( "working copy", self.working_copy_state_path.join("type"), LocalWorkingCopy::name, )?; - let working_copy_factory = - working_copy_factories - .get(&working_copy_type) - .ok_or_else(|| StoreLoadError::UnsupportedType { - store: "working copy", - store_type: working_copy_type.to_string(), - })?; + if let Some(factory) = working_copy_factories.get(&working_copy_type) { + Ok(factory.as_ref()) + } else { + Err(StoreLoadError::UnsupportedType { + store: "working copy", + store_type: working_copy_type.to_string(), + }) + } + } + + fn load_working_copy( + &self, + store: &Arc, + working_copy_factories: &HashMap>, + ) -> Result, StoreLoadError> { + let working_copy_factory = self.get_working_copy_factory(working_copy_factories)?; Ok(working_copy_factory.load_working_copy( store.clone(), self.workspace_root.to_owned(),