From ceca9054b9d0f98db92e27ffdd9d7bed07840639 Mon Sep 17 00:00:00 2001 From: Valentin Gatien-Baron Date: Wed, 10 Jan 2024 07:54:09 -0500 Subject: [PATCH] cli: move `jj workspace root` to `jj root, for discoverability This is a convenient command, for scripting things like `cd $(jj root) && do something`, and it seems better to allow people to find it before they learn about workspaces. --- CHANGELOG.md | 2 ++ cli/src/commands/mod.rs | 3 +++ cli/src/commands/root.rs | 36 ++++++++++++++++++++++++++++++++ cli/tests/test_root.rs | 44 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 cli/src/commands/root.rs create mode 100644 cli/tests/test_root.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 77e07fb7c5..8432652a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj resolve` now displays the file being resolved. +* `jj workspace root` was aliased to `jj root`, for ease of discoverability + ### Fixed bugs * Fixed snapshots of symlinks in `gitignore`-d directory. diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 03c43d37c6..96af7c1127 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -43,6 +43,7 @@ mod prev; mod rebase; mod resolve; mod restore; +mod root; mod run; mod show; mod sparse; @@ -119,6 +120,7 @@ enum Command { help_template = "Not a real subcommand; consider `jj backout` or `jj restore`" )] Revert(DummyCommandArgs), + Root(root::RootArgs), #[command(hide = true)] // TODO: Flesh out. Run(run::RunArgs), @@ -182,6 +184,7 @@ pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), Co Command::Unsquash(sub_args) => unsquash::cmd_unsquash(ui, command_helper, sub_args), Command::Restore(sub_args) => restore::cmd_restore(ui, command_helper, sub_args), Command::Revert(_args) => revert(), + Command::Root(sub_args) => root::cmd_root(ui, command_helper, sub_args), Command::Run(sub_args) => run::cmd_run(ui, command_helper, sub_args), Command::Diffedit(sub_args) => diffedit::cmd_diffedit(ui, command_helper, sub_args), Command::Split(sub_args) => split::cmd_split(ui, command_helper, sub_args), diff --git a/cli/src/commands/root.rs b/cli/src/commands/root.rs new file mode 100644 index 0000000000..54794f7a26 --- /dev/null +++ b/cli/src/commands/root.rs @@ -0,0 +1,36 @@ +// Copyright 2024 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use tracing::instrument; + +use crate::cli_util::{CommandError, CommandHelper}; +use crate::commands::workspace; +use crate::ui::Ui; + +/// Show the current workspace root directory +#[derive(clap::Args, Clone, Debug)] +pub(crate) struct RootArgs {} + +#[instrument(skip_all)] +pub(crate) fn cmd_root( + ui: &mut Ui, + command: &CommandHelper, + RootArgs {}: &RootArgs, +) -> Result<(), CommandError> { + workspace::cmd_workspace( + ui, + command, + &workspace::WorkspaceCommand::Root(workspace::WorkspaceRootArgs {}), + ) +} diff --git a/cli/tests/test_root.rs b/cli/tests/test_root.rs new file mode 100644 index 0000000000..6870eae240 --- /dev/null +++ b/cli/tests/test_root.rs @@ -0,0 +1,44 @@ +// Copyright 2024 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::path::Path; + +use test_case::test_case; +use testutils::{TestRepoBackend, TestWorkspace}; + +use crate::common::TestEnvironment; + +pub mod common; + +#[test_case(TestRepoBackend::Local ; "local backend")] +#[test_case(TestRepoBackend::Git ; "git backend")] +fn test_root(backend: TestRepoBackend) { + let test_env = TestEnvironment::default(); + let settings = testutils::user_settings(); + let test_workspace = TestWorkspace::init_with_backend(&settings, backend); + let root = test_workspace.workspace.workspace_root(); + let subdir = root.join("subdir"); + std::fs::create_dir(&subdir).unwrap(); + let stdout = test_env.jj_cmd_success(&subdir, &["root"]); + assert_eq!(&stdout, &[root.to_str().unwrap(), "\n"].concat()); +} + +#[test] +fn test_root_outside_a_repo() { + let test_env = TestEnvironment::default(); + let stdout = test_env.jj_cmd_failure(Path::new("/"), &["root"]); + insta::assert_snapshot!(stdout, @r###" + Error: There is no jj repo in "." + "###); +}