##// END OF EJS Templates
errors: make exit codes class variables instead...
errors: make exit codes class variables instead Kyle pointed out to me that we can simply make the exit codes class variables. Python provides some magic for making them accessible as instance variables. This also makes it easier to let subclasses of existing errors override the exit codes by letting them simply define their own values as class variables. That means that there's no need to pass them into the superclass's constructor arguments, so the superclass doesn't need to expose the them as arguments. (Making a subclass set a different exit code for a subclass of `StorageError` was actually the goal with my recent series.) Differential Revision: https://phab.mercurial-scm.org/D10758

File last commit:

r47687:b5e8bf10 default
r48085:73f52278 default
Show More
files.rs
91 lines | 2.7 KiB | application/rls-services+xml | RustLexer
use crate::error::CommandError;
use crate::ui::Ui;
use clap::Arg;
use hg::operations::list_rev_tracked_files;
use hg::operations::Dirstate;
use hg::repo::Repo;
use hg::utils::current_dir;
use hg::utils::files::{get_bytes_from_path, relativize_path};
use hg::utils::hg_path::{HgPath, HgPathBuf};
pub const HELP_TEXT: &str = "
List tracked files.
Returns 0 on success.
";
pub fn args() -> clap::App<'static, 'static> {
clap::SubCommand::with_name("files")
.arg(
Arg::with_name("rev")
.help("search the repository as it is in REV")
.short("-r")
.long("--revision")
.value_name("REV")
.takes_value(true),
)
.about(HELP_TEXT)
}
pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
let relative = invocation.config.get(b"ui", b"relative-paths");
if relative.is_some() {
return Err(CommandError::unsupported(
"non-default ui.relative-paths",
));
}
let rev = invocation.subcommand_args.value_of("rev");
let repo = invocation.repo?;
if let Some(rev) = rev {
let files = list_rev_tracked_files(repo, rev).map_err(|e| (e, rev))?;
display_files(invocation.ui, repo, files.iter())
} else {
let distate = Dirstate::new(repo)?;
let files = distate.tracked_files()?;
display_files(invocation.ui, repo, files)
}
}
fn display_files<'a>(
ui: &Ui,
repo: &Repo,
files: impl IntoIterator<Item = &'a HgPath>,
) -> Result<(), CommandError> {
let mut stdout = ui.stdout_buffer();
let cwd = current_dir()?;
let working_directory = repo.working_directory_path();
let working_directory = cwd.join(working_directory); // Make it absolute
let mut any = false;
if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&working_directory) {
// The current directory is inside the repo, so we can work with
// relative paths
let cwd = HgPathBuf::from(get_bytes_from_path(cwd_relative_to_repo));
for file in files {
any = true;
stdout.write_all(relativize_path(&file, &cwd).as_ref())?;
stdout.write_all(b"\n")?;
}
} else {
let working_directory =
HgPathBuf::from(get_bytes_from_path(working_directory));
let cwd = HgPathBuf::from(get_bytes_from_path(cwd));
for file in files {
any = true;
// Absolute path in the filesystem
let file = working_directory.join(file);
stdout.write_all(relativize_path(&file, &cwd).as_ref())?;
stdout.write_all(b"\n")?;
}
}
stdout.flush()?;
if any {
Ok(())
} else {
Err(CommandError::Unsuccessful)
}
}