annotate rust/rhg/src/commands/annotate.rs @ 52969:874c64e041b5

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.
author Mitchell Kember <mkember@janestreet.com>
date Fri, 07 Feb 2025 17:42:43 -0500
parents 6183949219b2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 }