ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: move ui.cwd() to CommandHelper

I'm going to remove owned UserSettings from Ui so that UserSettings can be
instantiated after both user and repo configs are loaded. ui.cwd() belongs
to the same category (random environment stuff), and Ui doesn't depend on it,
so let's remove it first from Ui.

I'm not pretty sure if CommandHelper and WorkspaceCommandHelper should be
a permanent home for cwd and settings, but it works for now as CommandHelper
is immutable.
This commit is contained in:
Yuya Nishihara 2023-01-04 17:18:45 +09:00
parent 42fa8bc20a
commit d7911ff279
4 changed files with 23 additions and 19 deletions

View file

@ -45,12 +45,12 @@ fn create_store_factories() -> StoreFactories {
fn run_custom_command(
ui: &mut Ui,
_command_helper: &CommandHelper,
command_helper: &CommandHelper,
command: CustomCommands,
) -> Result<(), CommandError> {
match command {
CustomCommands::InitJit => {
let wc_path = ui.cwd();
let wc_path = command_helper.cwd();
// Initialize a workspace with the custom backend
Workspace::init_with_backend(ui.settings(), wc_path, |store_path| {
Box::new(JitBackend::init(store_path))

View file

@ -13,7 +13,7 @@
// limitations under the License.
use std::collections::{HashSet, VecDeque};
use std::env::{ArgsOs, VarError};
use std::env::{self, ArgsOs, VarError};
use std::ffi::{OsStr, OsString};
use std::fmt::Debug;
use std::iter;
@ -260,6 +260,7 @@ impl TracingSubscription {
pub struct CommandHelper {
app: clap::Command,
cwd: PathBuf,
string_args: Vec<String>,
global_args: GlobalArgs,
store_factories: StoreFactories,
@ -268,12 +269,14 @@ pub struct CommandHelper {
impl CommandHelper {
pub fn new(
app: clap::Command,
cwd: PathBuf,
string_args: Vec<String>,
global_args: GlobalArgs,
store_factories: StoreFactories,
) -> Self {
Self {
app,
cwd,
string_args,
global_args,
store_factories,
@ -284,6 +287,10 @@ impl CommandHelper {
&self.app
}
pub fn cwd(&self) -> &Path {
&self.cwd
}
pub fn string_args(&self) -> &Vec<String> {
&self.string_args
}
@ -301,7 +308,7 @@ impl CommandHelper {
pub fn load_workspace(&self, ui: &Ui) -> Result<Workspace, CommandError> {
let wc_path_str = self.global_args.repository.as_deref().unwrap_or(".");
let wc_path = ui.cwd().join(wc_path_str);
let wc_path = self.cwd.join(wc_path_str);
Workspace::load(ui.settings(), &wc_path, &self.store_factories).map_err(|err| match err {
WorkspaceLoadError::NoWorkspaceHere(wc_path) => {
let message = format!("There is no jj repo in \"{wc_path_str}\"");
@ -383,6 +390,7 @@ jj init --git-repo=.",
WorkspaceCommandHelper::new(
ui,
workspace,
self.cwd.clone(),
self.string_args.clone(),
&self.global_args,
repo,
@ -408,6 +416,7 @@ impl WorkspaceCommandHelper {
pub fn new(
ui: &mut Ui,
workspace: Workspace,
cwd: PathBuf,
string_args: Vec<String>,
global_args: &GlobalArgs,
repo: Arc<ReadonlyRepo>,
@ -426,7 +435,7 @@ impl WorkspaceCommandHelper {
working_copy_shared_with_git = git_workdir == workspace.workspace_root().as_path();
}
Ok(Self {
cwd: ui.cwd().to_owned(),
cwd,
string_args,
global_args: global_args.clone(),
settings,
@ -1764,11 +1773,13 @@ impl CliRunner {
}
pub fn run(self, ui: &mut Ui) -> Result<(), CommandError> {
let cwd = env::current_dir().unwrap(); // TODO: maybe map_err to CommandError?
ui.reset(crate::config::read_config()?);
let string_args = expand_args(ui, &self.app, std::env::args_os())?;
let (matches, args) = parse_args(ui, &self.app, &self.tracing_subscription, &string_args)?;
let command_helper = CommandHelper::new(
self.app,
cwd,
string_args,
args.global_args,
self.store_factories.unwrap_or_default(),

View file

@ -1130,7 +1130,7 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
if command.global_args().repository.is_some() {
return Err(user_error("'--repository' cannot be used with 'init'"));
}
let wc_path = ui.cwd().join(&args.destination);
let wc_path = command.cwd().join(&args.destination);
match fs::create_dir(&wc_path) {
Ok(()) => {}
Err(_) if wc_path.is_dir() => {}
@ -1141,7 +1141,7 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
.map_err(|e| user_error(format!("Failed to create workspace: {e}")))?; // raced?
if let Some(git_store_str) = &args.git_repo {
let mut git_store_path = ui.cwd().join(git_store_str);
let mut git_store_path = command.cwd().join(git_store_str);
git_store_path = git_store_path
.canonicalize()
.map_err(|_| user_error(format!("{} doesn't exist", git_store_path.display())))?;
@ -1190,7 +1190,7 @@ Set `ui.allow-init-native` to allow initializing a repo with the native backend.
}
Workspace::init_local(ui.settings(), &wc_path)?;
};
let cwd = ui.cwd().canonicalize().unwrap();
let cwd = command.cwd().canonicalize().unwrap();
let relative_wc_path = file_util::relative_path(&cwd, &wc_path);
writeln!(ui, "Initialized repo in \"{}\"", relative_wc_path.display())?;
if args.git && wc_path.join(".git").exists() {
@ -3430,7 +3430,7 @@ fn cmd_workspace_add(
args: &WorkspaceAddArgs,
) -> Result<(), CommandError> {
let old_workspace_command = command.workspace_helper(ui)?;
let destination_path = ui.cwd().join(&args.destination);
let destination_path = command.cwd().join(&args.destination);
if destination_path.exists() {
return Err(user_error("Workspace already exists"));
} else {
@ -3469,6 +3469,7 @@ fn cmd_workspace_add(
let mut new_workspace_command = WorkspaceCommandHelper::new(
ui,
new_workspace,
command.cwd().to_owned(),
command.string_args().clone(),
command.global_args(),
repo,
@ -3793,13 +3794,13 @@ fn cmd_git_clone(
if command.global_args().repository.is_some() {
return Err(user_error("'--repository' cannot be used with 'git clone'"));
}
let source = absolute_git_source(ui.cwd(), &args.source);
let source = absolute_git_source(command.cwd(), &args.source);
let wc_path_str = args
.destination
.as_deref()
.or_else(|| clone_destination_for_source(&source))
.ok_or_else(|| user_error("No destination specified and wasn't able to guess it"))?;
let wc_path = ui.cwd().join(wc_path_str);
let wc_path = command.cwd().join(wc_path_str);
let wc_path_existed = wc_path.exists();
if wc_path_existed {
if !is_empty_dir(&wc_path) {

View file

@ -13,7 +13,6 @@
// limitations under the License.
use std::io::{Stderr, Stdout, Write};
use std::path::{Path, PathBuf};
use std::process::{Child, ChildStdin, Stdio};
use std::str::FromStr;
use std::{fmt, io, mem};
@ -28,7 +27,6 @@ pub struct Ui {
color: bool,
paginate: PaginationChoice,
progress_indicator: bool,
cwd: PathBuf,
formatter_factory: FormatterFactory,
output: UiOutput,
settings: UserSettings,
@ -123,13 +121,11 @@ impl Default for Ui {
impl Ui {
pub fn new() -> Ui {
let settings = UserSettings::from_config(crate::config::default_config());
let cwd = std::env::current_dir().unwrap();
let color = use_color(color_setting(&settings));
let progress_indicator = progress_indicator_setting(&settings);
let formatter_factory = FormatterFactory::prepare(&settings, color);
Ui {
color,
cwd,
formatter_factory,
paginate: PaginationChoice::Auto,
progress_indicator,
@ -177,10 +173,6 @@ impl Ui {
self.color
}
pub fn cwd(&self) -> &Path {
&self.cwd
}
pub fn settings(&self) -> &UserSettings {
&self.settings
}