Mercurial > hg
comparison contrib/merge-lists/src/main.rs @ 49011:b999edb15f8c
merge-lists: make it possible to specify pattern to match
The `merge-lists` tool doesn't know anything about Python other than
its regex that attempts to match import lines. Let's make it possible
to pass in a custom regex so it's easy to use the tool for e.g. C/C++
`#include` lines or Rust `use` lines (given the limited).
Differential Revision: https://phab.mercurial-scm.org/D12392
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 18 Mar 2022 12:23:47 -0700 |
parents | 681b25ea579e |
children |
comparison
equal
deleted
inserted
replaced
49010:681b25ea579e | 49011:b999edb15f8c |
---|---|
1 use clap::Parser; | 1 use clap::{ArgGroup, Parser}; |
2 use itertools::Itertools; | 2 use itertools::Itertools; |
3 use regex::bytes::Regex; | 3 use regex::bytes::Regex; |
4 use similar::ChangeTag; | 4 use similar::ChangeTag; |
5 use std::cmp::{max, min, Ordering}; | 5 use std::cmp::{max, min, Ordering}; |
6 use std::collections::HashSet; | 6 use std::collections::HashSet; |
148 /// A tool that performs a 3-way merge, resolving conflicts in sorted lists and | 148 /// A tool that performs a 3-way merge, resolving conflicts in sorted lists and |
149 /// leaving other conflicts unchanged. This is useful with Mercurial's support | 149 /// leaving other conflicts unchanged. This is useful with Mercurial's support |
150 /// for partial merge tools (configured in `[partial-merge-tools]`). | 150 /// for partial merge tools (configured in `[partial-merge-tools]`). |
151 #[derive(Parser, Debug)] | 151 #[derive(Parser, Debug)] |
152 #[clap(version, about, long_about = None)] | 152 #[clap(version, about, long_about = None)] |
153 #[clap(group(ArgGroup::new("match").required(true).args(&["pattern", "python-imports"])))] | |
153 struct Args { | 154 struct Args { |
154 /// Path to the file's content in the "local" side | 155 /// Path to the file's content in the "local" side |
155 local: OsString, | 156 local: OsString, |
156 | 157 |
157 /// Path to the file's content in the base | 158 /// Path to the file's content in the base |
158 base: OsString, | 159 base: OsString, |
159 | 160 |
160 /// Path to the file's content in the "other" side | 161 /// Path to the file's content in the "other" side |
161 other: OsString, | 162 other: OsString, |
163 | |
164 /// Regular expression to use | |
165 #[clap(long, short)] | |
166 pattern: Option<String>, | |
167 | |
168 /// Use built-in regular expression for Python imports | |
169 #[clap(long)] | |
170 python_imports: bool, | |
171 } | |
172 | |
173 fn get_regex(args: &Args) -> Regex { | |
174 let pattern = if args.python_imports { | |
175 r"import \w+(\.\w+)*( +#.*)?\n|from (\w+(\.\w+)* import \w+( as \w+)?(, \w+( as \w+)?)*( +#.*)?)" | |
176 } else if let Some(pattern) = &args.pattern { | |
177 pattern | |
178 } else { | |
179 ".*" | |
180 }; | |
181 let pattern = format!(r"{}\r?\n?", pattern); | |
182 regex::bytes::Regex::new(&pattern).unwrap() | |
162 } | 183 } |
163 | 184 |
164 fn main() { | 185 fn main() { |
165 let args: Args = Args::parse(); | 186 let args: Args = Args::parse(); |
166 | 187 |
170 | 191 |
171 let base_bytes = std::fs::read(&base_path).unwrap(); | 192 let base_bytes = std::fs::read(&base_path).unwrap(); |
172 let local_bytes = std::fs::read(&local_path).unwrap(); | 193 let local_bytes = std::fs::read(&local_path).unwrap(); |
173 let other_bytes = std::fs::read(&other_path).unwrap(); | 194 let other_bytes = std::fs::read(&other_path).unwrap(); |
174 | 195 |
175 let regex = | 196 let regex = get_regex(&args); |
176 regex::bytes::Regex::new(r"import \w+(\.\w+)*( +#.*)?\n|from (\w+(\.\w+)* import \w+( as \w+)?(, \w+( as \w+)?)*( +#.*)?)\r?\n?").unwrap(); | |
177 let (new_base_bytes, new_local_bytes, new_other_bytes) = | 197 let (new_base_bytes, new_local_bytes, new_other_bytes) = |
178 resolve(&base_bytes, &local_bytes, &other_bytes, ®ex); | 198 resolve(&base_bytes, &local_bytes, &other_bytes, ®ex); |
179 | 199 |
180 // Write out the result if anything changed | 200 // Write out the result if anything changed |
181 if new_base_bytes != base_bytes { | 201 if new_base_bytes != base_bytes { |