Skip to content

Commit

Permalink
cli: implement jj root
Browse files Browse the repository at this point in the history
This is a convenient command when scripting around, for things like:
$ cd $(jj root) && do something

Currently this fails if the path to the repo contains non-utf8 bytes,
similarly to `jj status` failing on non-utf8 paths inside the repo.
  • Loading branch information
v-gb committed Jan 10, 2024
1 parent d5a98df commit e887ffb
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `jj branch rename` will now warn if the renamed branch has a remote branch, since
those will have to be manually renamed outside of `jj`.

* `jj root` will print the path to the working copy root.

### Fixed bugs


Expand Down
3 changes: 3 additions & 0 deletions cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod prev;
mod rebase;
mod resolve;
mod restore;
mod root;
mod run;
mod show;
mod sparse;
Expand Down Expand Up @@ -118,6 +119,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),
Expand Down Expand Up @@ -179,6 +181,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),
Expand Down
41 changes: 41 additions & 0 deletions cli/src/commands/root.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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::io::Write;

use tracing::instrument;

use crate::cli_util::{user_error, CommandError, CommandHelper};
use crate::ui::Ui;

#[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> {
let workspace_root = command.workspace_loader()?.workspace_root();
if let Some(p) = workspace_root.to_str() {
writeln!(ui.stdout(), "{}", p)?;
Ok(())
} else {
Err(user_error(format!(
"root path {:?} is not valid UTF-8",
workspace_root
)))
}
}
38 changes: 38 additions & 0 deletions cli/tests/test_root.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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 crate::common::TestEnvironment;

pub mod common;

#[test]
fn test_root() {
let test_env = TestEnvironment::default();
for (repo_name, opts) in &[
("jj", &["--config-toml", "ui.allow-init-native=true"][..]),
("jj+git", &["--git"][..]),
] {
test_env.jj_cmd_ok(test_env.env_root(), &[&["init", repo_name], *opts].concat());
let subdir = test_env.env_root().join(repo_name).join("subdir");
std::fs::create_dir(&subdir).unwrap();
let stdout = test_env.jj_cmd_success(&subdir, &["root"]);
assert_eq!(&stdout, &["$TEST_ENV/", repo_name, "\n"].concat());
}
let stdout = test_env.jj_cmd_failure(Path::new("/"), &["root"]);
insta::assert_snapshot!(stdout, @r###"
Error: There is no jj repo in "."
"###);
}

0 comments on commit e887ffb

Please sign in to comment.