rust/rhg/src/commands/cat.rs
author Simon Sapin <simon.sapin@octobus.net>
Mon, 14 Dec 2020 16:33:15 +0100
changeset 46167 8a4914397d02
parent 46135 dca9cb99971c
child 46434 3e2d539d0d1a
permissions -rw-r--r--
rust: introduce Repo and Vfs types for filesystem abstraction This is similar to the corresponding Python classes. Repo represents a repository and knows the path to the `.hg` directory, the `store` directory, and the working directory. Separating these will enable supporting the share extension. A Vfs is created from a Repo for one of these three directories. It has filesystem access APIs that take a relative std::path::Path as a parameter. Differential Revision: https://phab.mercurial-scm.org/D9596
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     1
use crate::commands::Command;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     2
use crate::error::{CommandError, CommandErrorKind};
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     3
use crate::ui::utf8_to_local;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     4
use crate::ui::Ui;
46135
dca9cb99971c rust: replace most "operation" structs with functions
Simon Sapin <simon.sapin@octobus.net>
parents: 46032
diff changeset
     5
use hg::operations::{cat, CatRevError, CatRevErrorKind};
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
     6
use hg::repo::Repo;
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     7
use hg::utils::hg_path::HgPathBuf;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     8
use micro_timer::timed;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     9
use std::convert::TryFrom;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    10
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    11
pub const HELP_TEXT: &str = "
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    12
Output the current or given revision of files
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    13
";
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    14
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    15
pub struct CatCommand<'a> {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    16
    rev: Option<&'a str>,
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    17
    files: Vec<&'a str>,
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    18
}
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    19
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    20
impl<'a> CatCommand<'a> {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    21
    pub fn new(rev: Option<&'a str>, files: Vec<&'a str>) -> Self {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    22
        Self { rev, files }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    23
    }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    24
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    25
    fn display(&self, ui: &Ui, data: &[u8]) -> Result<(), CommandError> {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    26
        ui.write_stdout(data)?;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    27
        Ok(())
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    28
    }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    29
}
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    30
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    31
impl<'a> Command for CatCommand<'a> {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    32
    #[timed]
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    33
    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    34
        let repo = Repo::find()?;
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    35
        repo.check_requirements()?;
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    36
        let cwd = std::env::current_dir()
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    37
            .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    38
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    39
        let mut files = vec![];
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    40
        for file in self.files.iter() {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    41
            let normalized = cwd.join(&file);
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    42
            let stripped = normalized
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    43
                .strip_prefix(&repo.working_directory_path())
45604
db11f8f39caf rhg: use `.or(Err(Error))` not `.map_err(|_| Error)` (D9100#inline-15067)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
    44
                .or(Err(CommandErrorKind::Abort(None)))?;
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    45
            let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
45604
db11f8f39caf rhg: use `.or(Err(Error))` not `.map_err(|_| Error)` (D9100#inline-15067)
Antoine cezar<acezar@chwitlabs.fr>
parents: 45542
diff changeset
    46
                .or(Err(CommandErrorKind::Abort(None)))?;
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    47
            files.push(hg_file);
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    48
        }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    49
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    50
        match self.rev {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    51
            Some(rev) => {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents: 46135
diff changeset
    52
                let data = cat(&repo, rev, &files)
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    53
                    .map_err(|e| map_rev_error(rev, e))?;
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    54
                self.display(ui, &data)
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    55
            }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    56
            None => Err(CommandErrorKind::Unimplemented.into()),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    57
        }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    58
    }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    59
}
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    60
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    61
/// Convert `CatRevErrorKind` to `CommandError`
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    62
fn map_rev_error(rev: &str, err: CatRevError) -> CommandError {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    63
    CommandError {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    64
        kind: match err.kind {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    65
            CatRevErrorKind::IoError(err) => CommandErrorKind::Abort(Some(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    66
                utf8_to_local(&format!("abort: {}\n", err)).into(),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    67
            )),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    68
            CatRevErrorKind::InvalidRevision => CommandErrorKind::Abort(Some(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    69
                utf8_to_local(&format!(
45996
904647f7d983 rhg: add a test for --rev with a hex changeset ID
Simon Sapin <simon-commits@exyr.org>
parents: 45937
diff changeset
    70
                    "abort: invalid revision identifier {}\n",
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    71
                    rev
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    72
                ))
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    73
                .into(),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    74
            )),
46032
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    75
            CatRevErrorKind::AmbiguousPrefix => CommandErrorKind::Abort(Some(
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    76
                utf8_to_local(&format!(
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    77
                    "abort: ambiguous revision identifier {}\n",
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    78
                    rev
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    79
                ))
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    80
                .into(),
8d6164098782 rhg: allow specifying a changeset ID prefix
Simon Sapin <simon-commits@exyr.org>
parents: 45996
diff changeset
    81
            )),
45542
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    82
            CatRevErrorKind::UnsuportedRevlogVersion(version) => {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    83
                CommandErrorKind::Abort(Some(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    84
                    utf8_to_local(&format!(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    85
                        "abort: unsupported revlog version {}\n",
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    86
                        version
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    87
                    ))
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    88
                    .into(),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    89
                ))
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    90
            }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    91
            CatRevErrorKind::CorruptedRevlog => CommandErrorKind::Abort(Some(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    92
                "abort: corrupted revlog\n".into(),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    93
            )),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    94
            CatRevErrorKind::UnknowRevlogDataFormat(format) => {
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    95
                CommandErrorKind::Abort(Some(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    96
                    utf8_to_local(&format!(
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    97
                        "abort: unknow revlog dataformat {:?}\n",
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    98
                        format
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    99
                    ))
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   100
                    .into(),
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   101
                ))
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   102
            }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   103
        },
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   104
    }
33ded2d3f4fc rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
   105
}