rust/rhg/src/commands/annotate.rs
author Mitchell Kember <mkember@janestreet.com>
Fri, 07 Feb 2025 17:42:43 -0500
changeset 52969 874c64e041b5
parent 52767 6183949219b2
permissions -rw-r--r--
rhg-annotate: support whitespace options This adds support to rhg annotate for all the whitespace options: -w, --ignore-all-space -b, --ignore-space-change -B, --ignore-blank-lines -Z, --ignore-space-at-eol Note that --ignore-blank-lines has no effect on annotate so it is ignored. You can see this in dagop.py _annotepair which only checks if blocks are '=' or not, whereas the effect of --ignore-blank-lines is to change some '!' into '~'. When the other 3 are combined, we use the strongest option since -w implies -b and -b implies -Z. This is not explicit in the Python implementation, but I have verified that's how it behaves.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52767
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     1
use core::str;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     2
use std::{collections::hash_map::Entry, ffi::OsString};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     3
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     4
use format_bytes::format_bytes;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     5
use hg::{
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     6
    encoding::Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     7
    operations::{
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     8
        annotate, AnnotateOptions, AnnotateOutput, ChangesetAnnotation,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     9
    },
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    10
    revlog::changelog::Changelog,
52969
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
    11
    utils::strings::CleanWhitespace,
52767
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    12
    FastHashMap, Revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    13
};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    14
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    15
use crate::{error::CommandError, utils::path_utils::resolve_file_args};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    16
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    17
pub const HELP_TEXT: &str = "
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    18
show changeset information by line for each file
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    19
";
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    20
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    21
pub fn args() -> clap::Command {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    22
    clap::command!("annotate")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    23
        .alias("blame")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    24
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    25
            clap::Arg::new("files")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    26
                .help("files to annotate")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    27
                .required(true)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    28
                .num_args(1..)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    29
                .value_name("FILE")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    30
                .value_parser(clap::value_parser!(OsString)),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    31
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    32
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    33
            clap::Arg::new("rev")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    34
                .help("annotate the specified revision")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    35
                .short('r')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    36
                .long("rev")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    37
                .value_name("REV")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    38
                .default_value("."),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    39
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    40
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    41
            clap::Arg::new("no-follow")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    42
                .help("don't follow copies and renames")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    43
                .long("no-follow")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    44
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    45
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    46
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    47
            clap::Arg::new("text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    48
                .help("treat all files as text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    49
                .short('a')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    50
                .long("text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    51
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    52
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    53
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    54
            clap::Arg::new("user")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    55
                .help("list the author (long with -v)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    56
                .short('u')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    57
                .long("user")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    58
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    59
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    60
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    61
            clap::Arg::new("number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    62
                .help("list the revision number (default)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    63
                .short('n')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    64
                .long("number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    65
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    66
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    67
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    68
            clap::Arg::new("changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    69
                .help("list the changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    70
                .short('c')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    71
                .long("changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    72
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    73
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    74
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    75
            clap::Arg::new("date")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    76
                .help("list the date (short with -q)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    77
                .short('d')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    78
                .long("date")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    79
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    80
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    81
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    82
            clap::Arg::new("file")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    83
                .help("list the filename")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    84
                .short('f')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    85
                .long("file")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    86
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    87
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    88
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    89
            clap::Arg::new("line-number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    90
                .help("show the line number at the first appearance")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    91
                .short('l')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    92
                .long("line-number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    93
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    94
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    95
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    96
            clap::Arg::new("quiet")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    97
                .help("show short date for -d")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    98
                .short('q')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    99
                .long("quiet")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   100
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   101
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   102
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   103
            clap::Arg::new("verbose")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   104
                .help("show full username for -u")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   105
                .short('v')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   106
                .long("verbose")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   107
                .action(clap::ArgAction::SetTrue)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   108
                .conflicts_with("quiet"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   109
        )
52969
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   110
        .arg(
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   111
            clap::Arg::new("ignore-all-space")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   112
                .help("ignore white space when comparing lines")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   113
                .short('w')
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   114
                .long("ignore-all-space")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   115
                .action(clap::ArgAction::SetTrue),
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   116
        )
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   117
        .arg(
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   118
            clap::Arg::new("ignore-space-change")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   119
                .help("ignore changes in the amount of white space")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   120
                .short('b')
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   121
                .long("ignore-space-change")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   122
                .action(clap::ArgAction::SetTrue),
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   123
        )
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   124
        .arg(
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   125
            clap::Arg::new("ignore-blank-lines")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   126
                .help("ignore changes whose lines are all blank")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   127
                .short('B')
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   128
                .long("ignore-blank-lines")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   129
                .action(clap::ArgAction::SetTrue),
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   130
        )
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   131
        .arg(
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   132
            clap::Arg::new("ignore-space-at-eol")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   133
                .help("ignore changes in whitespace at EOL")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   134
                .short('Z')
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   135
                .long("ignore-space-at-eol")
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   136
                .action(clap::ArgAction::SetTrue),
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   137
        )
52767
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   138
        .about(HELP_TEXT)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   139
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   140
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   141
pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   142
    let config = invocation.config;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   143
    if config.has_non_empty_section(b"annotate") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   144
        return Err(CommandError::unsupported(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   145
            "rhg annotate does not support any [annotate] configs",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   146
        ));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   147
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   148
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   149
    let repo = invocation.repo?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   150
    let args = invocation.subcommand_args;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   151
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   152
    let rev = args.get_one::<String>("rev").expect("rev has a default");
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   153
    let rev = hg::revset::resolve_single(rev, repo)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   154
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   155
    let files = match args.get_many::<OsString>("files") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   156
        None => vec![],
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   157
        Some(files) => resolve_file_args(repo, files)?,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   158
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   159
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   160
    let options = AnnotateOptions {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   161
        treat_binary_as_text: args.get_flag("text"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   162
        follow_copies: !args.get_flag("no-follow"),
52969
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   163
        whitespace: if args.get_flag("ignore-all-space") {
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   164
            CleanWhitespace::All
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   165
        } else if args.get_flag("ignore-space-change") {
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   166
            CleanWhitespace::Collapse
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   167
        } else if args.get_flag("ignore-space-at-eol") {
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   168
            CleanWhitespace::AtEol
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   169
        } else {
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   170
            // We ignore the --ignore-blank-lines flag (present for consistency
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   171
            // with other commands) since it has no effect on annotate.
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   172
            CleanWhitespace::None
874c64e041b5 rhg-annotate: support whitespace options
Mitchell Kember <mkember@janestreet.com>
parents: 52767
diff changeset
   173
        },
52767
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   174
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   175
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   176
    let mut include = Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   177
        user: args.get_flag("user"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   178
        number: args.get_flag("number"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   179
        changeset: args.get_flag("changeset"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   180
        date: args.get_flag("date"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   181
        file: args.get_flag("file"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   182
        line_number: args.get_flag("line-number"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   183
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   184
    if !(include.user || include.file || include.date || include.changeset) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   185
        include.number = true;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   186
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   187
    if include.line_number && !(include.number || include.changeset) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   188
        return Err(CommandError::abort(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   189
            "at least one of -n/-c is required for -l",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   190
        ));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   191
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   192
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   193
    let verbosity = match (args.get_flag("quiet"), args.get_flag("verbose")) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   194
        (false, false) => Verbosity::Default,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   195
        (true, false) => Verbosity::Quiet,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   196
        (false, true) => Verbosity::Verbose,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   197
        (true, true) => unreachable!(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   198
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   199
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   200
    let changelog = repo.changelog()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   201
    let mut formatter = Formatter::new(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   202
        &changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   203
        invocation.ui.encoder(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   204
        include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   205
        verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   206
    );
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   207
    let mut stdout = invocation.ui.stdout_buffer();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   208
    for path in files {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   209
        match annotate(repo, &path, rev, options)? {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   210
            AnnotateOutput::Text(text) => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   211
                let annotations = formatter.format(text.annotations)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   212
                for (annotation, line) in annotations.iter().zip(&text.lines) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   213
                    stdout.write_all(&format_bytes!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   214
                        b"{}: {}", annotation, line
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   215
                    ))?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   216
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   217
                if let Some(line) = text.lines.last() {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   218
                    if !line.ends_with(b"\n") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   219
                        stdout.write_all(b"\n")?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   220
                    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   221
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   222
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   223
            AnnotateOutput::Binary => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   224
                stdout.write_all(&format_bytes!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   225
                    b"{}: binary file\n",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   226
                    path.as_bytes()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   227
                ))?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   228
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   229
            AnnotateOutput::NotFound => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   230
                let short = changelog.node_from_rev(rev).short();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   231
                return Err(CommandError::abort(format!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   232
                    "{path}: no such file in rev {short:x}",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   233
                )));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   234
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   235
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   236
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   237
    stdout.flush()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   238
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   239
    Ok(())
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   240
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   241
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   242
struct Formatter<'a> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   243
    changelog: &'a Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   244
    encoder: &'a Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   245
    include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   246
    verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   247
    cache: FastHashMap<Revision, ChangesetData>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   248
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   249
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   250
#[derive(Copy, Clone)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   251
struct Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   252
    user: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   253
    number: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   254
    changeset: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   255
    date: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   256
    file: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   257
    line_number: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   258
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   259
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   260
impl Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   261
    fn count(&self) -> usize {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   262
        // Rust guarantees false is 0 and true is 1.
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   263
        self.user as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   264
            + self.number as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   265
            + self.changeset as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   266
            + self.date as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   267
            + self.file as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   268
            + self.line_number as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   269
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   270
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   271
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   272
#[derive(Copy, Clone)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   273
enum Verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   274
    Quiet,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   275
    Default,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   276
    Verbose,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   277
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   278
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   279
#[derive(Default)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   280
struct ChangesetData {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   281
    user: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   282
    changeset: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   283
    date: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   284
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   285
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   286
impl ChangesetData {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   287
    fn create(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   288
        revision: Revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   289
        changelog: &Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   290
        include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   291
        verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   292
    ) -> Result<ChangesetData, CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   293
        let mut result = ChangesetData::default();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   294
        if !(include.user || include.changeset || include.date) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   295
            return Ok(result);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   296
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   297
        let entry = changelog.entry(revision)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   298
        let data = entry.data()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   299
        if include.user {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   300
            let user = match verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   301
                Verbosity::Verbose => data.user(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   302
                _ => hg::utils::strings::short_user(data.user()),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   303
            };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   304
            result.user = Some(user.to_vec());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   305
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   306
        if include.changeset {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   307
            let changeset = entry.as_revlog_entry().node().short();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   308
            result.changeset = Some(format!("{:x}", changeset).into_bytes());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   309
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   310
        if include.date {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   311
            let date = data.timestamp()?.format(match verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   312
                Verbosity::Quiet => "%Y-%m-%d",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   313
                _ => "%a %b %d %H:%M:%S %Y %z",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   314
            });
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   315
            result.date = Some(format!("{}", date).into_bytes());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   316
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   317
        Ok(result)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   318
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   319
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   320
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   321
impl<'a> Formatter<'a> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   322
    fn new(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   323
        changelog: &'a Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   324
        encoder: &'a Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   325
        include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   326
        verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   327
    ) -> Self {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   328
        let cache = FastHashMap::default();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   329
        Self {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   330
            changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   331
            encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   332
            include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   333
            verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   334
            cache,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   335
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   336
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   337
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   338
    fn format(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   339
        &mut self,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   340
        annotations: Vec<ChangesetAnnotation>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   341
    ) -> Result<Vec<Vec<u8>>, CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   342
        let mut lines: Vec<Vec<Vec<u8>>> =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   343
            Vec::with_capacity(annotations.len());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   344
        let num_fields = self.include.count();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   345
        let mut widths = vec![0usize; num_fields];
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   346
        for annotation in annotations {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   347
            let revision = annotation.revision;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   348
            let data = match self.cache.entry(revision) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   349
                Entry::Occupied(occupied) => occupied.into_mut(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   350
                Entry::Vacant(vacant) => vacant.insert(ChangesetData::create(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   351
                    revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   352
                    self.changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   353
                    self.include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   354
                    self.verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   355
                )?),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   356
            };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   357
            let mut fields = Vec::with_capacity(num_fields);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   358
            if let Some(user) = &data.user {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   359
                fields.push(user.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   360
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   361
            if self.include.number {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   362
                fields.push(format_bytes!(b"{}", revision));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   363
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   364
            if let Some(changeset) = &data.changeset {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   365
                fields.push(changeset.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   366
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   367
            if let Some(date) = &data.date {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   368
                fields.push(date.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   369
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   370
            if self.include.file {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   371
                fields.push(annotation.path.into_vec());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   372
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   373
            if self.include.line_number {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   374
                fields.push(format_bytes!(b"{}", annotation.line_number));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   375
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   376
            for (field, width) in fields.iter().zip(widths.iter_mut()) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   377
                *width = std::cmp::max(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   378
                    *width,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   379
                    self.encoder.column_width_bytes(field),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   380
                );
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   381
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   382
            lines.push(fields);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   383
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   384
        let total_width = widths.iter().sum::<usize>() + num_fields - 1;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   385
        Ok(lines
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   386
            .iter()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   387
            .map(|fields| {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   388
                let mut bytes = Vec::with_capacity(total_width);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   389
                for (i, (field, width)) in
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   390
                    fields.iter().zip(widths.iter()).enumerate()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   391
                {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   392
                    if i > 0 {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   393
                        let colon =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   394
                            self.include.line_number && i == num_fields - 1;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   395
                        bytes.push(if colon { b':' } else { b' ' });
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   396
                    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   397
                    let padding =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   398
                        width - self.encoder.column_width_bytes(field);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   399
                    bytes.resize(bytes.len() + padding, b' ');
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   400
                    bytes.extend_from_slice(field);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   401
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   402
                bytes
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   403
            })
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   404
            .collect())
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   405
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   406
}