From f8aa7f6c8a632546b4cb234abf0030a39be52eed Mon Sep 17 00:00:00 2001
From: Teddy Wing
Date: Wed, 26 Aug 2020 21:41:36 +0200
Subject: Add `diff_options` to parse Git diff options
In order to accept Git diff options on the command line, we need a way
to extract these from args.
Add a function to parse diff options. These were sourced from:
https://github.com/git/git/blob/675a4aaf3b226c0089108221b96559e0baae5de9/Documentation/diff-options.txt
The function loops through the input arguments and extracts all diff
options and their values.
Still needs some work to integrate it into `git-sugdiff`, but it
currently works as advertised.
---
src/diff_options.rs | 380 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 380 insertions(+)
create mode 100644 src/diff_options.rs
(limited to 'src/diff_options.rs')
diff --git a/src/diff_options.rs b/src/diff_options.rs
new file mode 100644
index 0000000..587e214
--- /dev/null
+++ b/src/diff_options.rs
@@ -0,0 +1,380 @@
+// Copyright (c) 2020 Teddy Wing
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+
+static FLAGS: [&'static str; 59] = [
+ "-p",
+ "--no-stat",
+ "-p",
+ "-u",
+ "--patch",
+ "-s",
+ "--no-patch",
+ "--raw",
+ "--patch-with-raw",
+ "-t",
+ "--indent-heuristic",
+ "--no-indent-heuristic",
+ "--minimal",
+ "--patience",
+ "--histogram",
+ "--compact-summary",
+ "--numstat",
+ "--shortstat",
+ "--cumulative",
+ "--summary",
+ "--patch-with-stat",
+ "-z",
+ "--name-only",
+ "--name-status",
+ "--no-color",
+ "--no-color-moved",
+ "--no-color-moved-ws",
+ "--no-renames",
+ "--rename-empty",
+ "--no-rename-empty",
+ "--check",
+ "--full-index",
+ "--binary",
+ "--find-copies-harder",
+ "-D",
+ "--irreversible-delete",
+ "--pickaxe-all",
+ "--pickaxe-regex",
+ "-R",
+ "--no-relative",
+ "-a",
+ "--text",
+ "--ignore-cr-at-eol",
+ "--ignore-space-at-eol",
+ "-b",
+ "--ignore-space-change",
+ "-w",
+ "--ignore-all-space",
+ "--ignore-blank-lines",
+ "-W",
+ "--function-context",
+ "--exit-code",
+ "--quiet",
+ "--ext-diff",
+ "--no-ext-diff",
+ "--textconv",
+ "--no-textconv",
+ "--no-prefix",
+ "--ita-invisible-in-index",
+];
+
+// static OPTIONS: [&'static str; 21] = [
+// "-U",
+// "--unified=",
+// "--output=",
+// "--output-indicator-new=",
+// "--output-indicator-old=",
+// "--output-indicator-context=",
+// "--anchored=",
+// "--diff-algorithm={patience|minimal|histogram|myers}",
+// "--stat[=[,[,]]]",
+// "-X[]",
+// "--dirstat[=]",
+// "--dirstat-by-file[=...]",
+// "--submodule[=]",
+// "--color[=]",
+// "--color-moved[=]",
+// "--color-moved-ws=",
+// "--word-diff[=]",
+// "--word-diff-regex=",
+// "--color-words[=]",
+// "--ws-error-highlight=",
+// "--abbrev[=]",
+// "-B[][/]",
+// "--break-rewrites[=[][/]]",
+// "-M[]",
+// "--find-renames[=]",
+// "-C[]",
+// "--find-copies[=]",
+// "-l",
+// "--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]",
+// "-S",
+// "-G",
+// "--find-object=",
+// "-O",
+// "--relative[=]",
+// "--inter-hunk-context=",
+// "--ignore-submodules[=]",
+// "--src-prefix=",
+// "--dst-prefix=",
+// "--line-prefix=",
+// ];
+
+static ARG_OPTIONS: [&'static str; 20] = [
+ "-U",
+ "--unified",
+ "--output",
+ "--output-indicator-new",
+ "--output-indicator-old",
+ "--output-indicator-context",
+ "--anchored",
+ "--diff-algorithm",
+ "--color-moved-ws",
+ "--word-diff-regex",
+ "--ws-error-highlight",
+ "-l",
+ "-S",
+ "-G",
+ "--find-object",
+ "-O",
+ "--inter-hunk-context",
+ "--src-prefix",
+ "--dst-prefix",
+ "--line-prefix",
+];
+
+static OPT_OPTIONS: [&'static str; 19] = [
+ "--stat",
+ "-X",
+ "--dirstat",
+ "--dirstat-by-file",
+ "--submodule",
+ "--color",
+ "--color-moved",
+ "--word-diff",
+ "--color-words",
+ "--abbrev",
+ "-B",
+ "--break-rewrites",
+ "-M",
+ "--find-renames",
+ "-C",
+ "--find-copies",
+ "--diff-filter",
+ "--relative",
+ "--ignore-submodules",
+];
+
+
+// pub fn parse(args: &[String]) -> &[String] {
+pub fn parse(args: &[String]) -> Vec<&String> {
+ let mut found_args = Vec::new();
+ let mut add_next_arg = false;
+
+ for arg in args {
+ let find_arg_prefix = arg.find('-');
+
+ if add_next_arg
+ && (
+ find_arg_prefix.is_none()
+ || find_arg_prefix != Some(0)
+ )
+ {
+ found_args.push(arg);
+
+ add_next_arg = false;
+
+ continue;
+ }
+
+ for flag in FLAGS.iter() {
+ if arg.starts_with(flag) {
+ found_args.push(arg);
+ }
+ }
+
+ // TODO: check for "=" and get next arg
+ // '='
+ // if no equals, then add next arg
+ for option in &ARG_OPTIONS {
+ if arg.starts_with(option) {
+ found_args.push(arg);
+
+ // if arg doesn't have an = after it
+ // if i < arg.len() {
+ // let char_after_option = arg.get(option.len());
+ // if char_after_option.is_some()
+ // && char_after_option.unwrap() == '=' {
+
+ let (_option, rest) = arg.split_at(option.len());
+
+ dbg!(arg);
+ dbg!(arg.len());
+ dbg!(option);
+ dbg!(option.len());
+ dbg!(rest.find('=').is_none());
+ // if arg.len() > option.len()
+ // && rest.find('=').is_none() {
+ if rest.find('=').is_none() {
+ add_next_arg = true;
+ }
+ }
+ }
+
+ // check '='
+ // If no equals, add next arg if it doesn't begin with '-'
+ for option in &OPT_OPTIONS {
+ if arg.starts_with(option) {
+ found_args.push(arg);
+
+ let (_option, rest) = arg.split_at(option.len());
+
+ if rest.find('=').is_none() {
+ add_next_arg = true;
+ }
+ }
+ }
+ }
+
+ found_args
+}
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parse_extracts_diff_options() {
+ let args = vec![
+ "--github-token".to_owned(),
+ "MY_TOKEN".to_owned(),
+ "--diff-filter=A".to_owned(),
+ "-D".to_owned(),
+ "--color".to_owned(),
+ "always".to_owned(),
+ "-U5".to_owned(),
+ "--patience".to_owned(),
+ "--ws-error-highlight".to_owned(),
+ "old,new".to_owned(),
+ "--no-rename-empty".to_owned(),
+ "--stat=50".to_owned(),
+ "-M90%".to_owned(),
+ "--relative".to_owned(),
+ ];
+
+ let options = parse(&args);
+
+ assert_eq!(options, vec![
+ "--diff-filter=A",
+ "-D",
+ "--color",
+ "always",
+ "-U5",
+ "--patience",
+ "--ws-error-highlight",
+ "old,new",
+ "--no-rename-empty",
+ "--stat=50",
+ "-M90%",
+ "--relative",
+ ]);
+ }
+}
+
+// -p
+// --no-stat
+// -p
+// -u
+// --patch
+// -s
+// --no-patch
+// -U
+// --unified=
+// --output=
+// --output-indicator-new=
+// --output-indicator-old=
+// --output-indicator-context=
+// --raw
+// --patch-with-raw
+// -t
+// --indent-heuristic
+// --no-indent-heuristic
+// --minimal
+// --patience
+// --histogram
+// --anchored=
+// --diff-algorithm={patience|minimal|histogram|myers}
+// --stat[=[,[,]]]
+// --compact-summary
+// --numstat
+// --shortstat
+// -X[]
+// --dirstat[=]
+// --cumulative
+// --dirstat-by-file[=...]
+// --summary
+// --patch-with-stat
+// -z
+// --name-only
+// --name-status
+// --submodule[=]
+// --color[=]
+// --no-color
+// --color-moved[=]
+// --no-color-moved
+// --color-moved-ws=
+// --no-color-moved-ws
+// --word-diff[=]
+// --word-diff-regex=
+// --color-words[=]
+// --no-renames
+// --[no-]rename-empty
+// --check
+// --ws-error-highlight=
+// --full-index
+// --binary
+// --abbrev[=]
+// -B[][/]
+// --break-rewrites[=[][/]]
+// -M[]
+// --find-renames[=]
+// -C[]
+// --find-copies[=]
+// --find-copies-harder
+// -D
+// --irreversible-delete
+// -l
+// --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
+// -S
+// -G
+// -S"frotz\(nitfol" --pickaxe-regex` will not (because the number of
+// --find-object=
+// --pickaxe-all
+// --pickaxe-regex
+// -O
+// -R
+// --relative[=]
+// --no-relative
+// -a
+// --text
+// --ignore-cr-at-eol
+// --ignore-space-at-eol
+// -b
+// --ignore-space-change
+// -w
+// --ignore-all-space
+// --ignore-blank-lines
+// --inter-hunk-context=
+// -W
+// --function-context
+// --exit-code
+// --quiet
+// --ext-diff
+// --no-ext-diff
+// --textconv
+// --no-textconv
+// --ignore-submodules[=]
+// --src-prefix=
+// --dst-prefix=
+// --no-prefix
+// --line-prefix=
+// --ita-invisible-in-index
--
cgit v1.2.3