summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Davison <dandavison7@gmail.com>2020-12-16 23:17:45 +0000
committerGitHub <noreply@github.com>2020-12-16 23:17:45 +0000
commit46eb84bd34f8ff67f749eec8a287d5a3e7a0919a (patch)
tree98fe1d11098a1bc23039d0fc4079ee9588a4378a
parenta632e3f704d8e5b10326f6d79ad58807f2fa103d (diff)
Exit with diff's exit code (#449)
Fixes #448
-rw-r--r--src/config.rs5
-rw-r--r--src/main.rs105
2 files changed, 92 insertions, 18 deletions
diff --git a/src/config.rs b/src/config.rs
index b2cd2eab..28e571d6 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -23,6 +23,7 @@ pub struct Config {
pub commit_style: Style,
pub color_only: bool,
pub decorations_width: cli::Width,
+ pub error_exit_code: i32,
pub file_added_label: String,
pub file_copied_label: String,
pub file_modified_label: String,
@@ -153,6 +154,7 @@ impl From<cli::Opt> for Config {
commit_style,
color_only: opt.color_only,
decorations_width: opt.computed.decorations_width,
+ error_exit_code: 2, // Use 2 for error because diff uses 0 and 1 for non-error.
file_added_label: opt.file_added_label,
file_copied_label: opt.file_copied_label,
file_modified_label: opt.file_modified_label,
@@ -411,10 +413,11 @@ pub fn user_supplied_option(option: &str, arg_matches: &clap::ArgMatches) -> boo
}
pub fn delta_unreachable(message: &str) -> ! {
+ let error_exit_code = 2; // This is also stored in Config.
eprintln!(
"{} This should not be possible. \
Please report the bug at https://github.com/dandavison/delta/issues.",
message
);
- process::exit(1);
+ process::exit(error_exit_code);
}
diff --git a/src/main.rs b/src/main.rs
index 51a0b702..36239b67 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -36,6 +36,7 @@ use structopt::StructOpt;
use crate::bat_utils::assets::{list_languages, HighlightingAssets};
use crate::bat_utils::output::{OutputType, PagingMode};
+use crate::config::delta_unreachable;
use crate::delta::delta;
use crate::options::theme::is_light_syntax_theme;
@@ -73,17 +74,20 @@ fn main() -> std::io::Result<()> {
let mut stdout = stdout.lock();
show_config(&config, &mut stdout)?;
process::exit(0);
- } else if atty::is(atty::Stream::Stdin) {
- return diff(
- config.minus_file.as_ref(),
- config.plus_file.as_ref(),
- &config,
- );
}
let mut output_type = OutputType::from_mode(config.paging_mode, None, &config).unwrap();
let mut writer = output_type.handle().unwrap();
+ if atty::is(atty::Stream::Stdin) {
+ process::exit(diff(
+ config.minus_file.as_ref(),
+ config.plus_file.as_ref(),
+ &config,
+ &mut writer,
+ ));
+ }
+
if let Err(error) = delta(io::stdin().lock().byte_lines(), &mut writer, &config) {
match error.kind() {
ErrorKind::BrokenPipe => process::exit(0),
@@ -98,14 +102,15 @@ fn diff(
minus_file: Option<&PathBuf>,
plus_file: Option<&PathBuf>,
config: &config::Config,
-) -> std::io::Result<()> {
+ writer: &mut dyn Write,
+) -> i32 {
use std::io::BufReader;
let die = || {
eprintln!("Usage: delta minus_file plus_file");
- process::exit(1);
+ process::exit(config.error_exit_code);
};
- let command = "diff";
- let diff_process = process::Command::new(PathBuf::from(command))
+ let diff_command = "diff";
+ let mut diff_process = process::Command::new(PathBuf::from(diff_command))
.arg("-u")
.args(&[
minus_file.unwrap_or_else(die),
@@ -114,23 +119,34 @@ fn diff(
.stdout(process::Stdio::piped())
.spawn()
.unwrap_or_else(|err| {
- eprintln!("Failed to execute the command '{}': {}", command, err);
- process::exit(1);
+ eprintln!("Failed to execute the command '{}': {}", diff_command, err);
+ process::exit(config.error_exit_code);
+ });
+ let exit_code = diff_process
+ .wait()
+ .unwrap_or_else(|_| {
+ delta_unreachable(&format!("'{}' process not running.", diff_command));
+ })
+ .code()
+ .unwrap_or_else(|| {
+ eprintln!("'{}' process terminated without exit status.", diff_command);
+ process::exit(config.error_exit_code);
});
- let mut output_type = OutputType::from_mode(config.paging_mode, None, &config).unwrap();
- let mut writer = output_type.handle().unwrap();
if let Err(error) = delta(
BufReader::new(diff_process.stdout.unwrap()).byte_lines(),
- &mut writer,
+ writer,
&config,
) {
match error.kind() {
ErrorKind::BrokenPipe => process::exit(0),
- _ => eprintln!("{}", error),
+ _ => {
+ eprintln!("{}", error);
+ process::exit(config.error_exit_code);
+ }
}
};
- Ok(())
+ exit_code
}
fn show_config(config: &config::Config, writer: &mut dyn Write) -> std::io::Result<()> {
@@ -467,4 +483,59 @@ mod main_tests {
assert!(s.contains("light GitHub\n"));
assert!(s.contains("dark Dracula\n"));
}
+
+ #[test]
+ #[cfg_attr(target_os = "windows", ignore)]
+ fn test_diff_same_empty_file() {
+ let config = integration_test_utils::make_config_from_args(&[]);
+ let mut writer = Cursor::new(vec![]);
+ let exit_code = diff(
+ Some(&PathBuf::from("/dev/null")),
+ Some(&PathBuf::from("/dev/null")),
+ &config,
+ &mut writer,
+ );
+ assert_eq!(exit_code, 0);
+ let mut s = String::new();
+ writer.seek(SeekFrom::Start(0)).unwrap();
+ writer.read_to_string(&mut s).unwrap();
+ assert!(s.is_empty());
+ }
+
+ #[test]
+ #[cfg_attr(target_os = "windows", ignore)]
+ fn test_diff_same_non_empty_file() {
+ let config = integration_test_utils::make_config_from_args(&[]);
+ let mut writer = Cursor::new(vec![]);
+ let exit_code = diff(
+ Some(&PathBuf::from("/etc/passwd")),
+ Some(&PathBuf::from("/etc/passwd")),
+ &config,
+ &mut writer,
+ );
+ assert_eq!(exit_code, 0);
+ let mut s = String::new();
+ writer.seek(SeekFrom::Start(0)).unwrap();
+ writer.read_to_string(&mut s).unwrap();
+ assert!(s.is_empty());
+ }
+
+ #[test]
+ #[cfg_attr(target_os = "windows", ignore)]
+ fn test_diff_differing_files() {
+ let config = integration_test_utils::make_config_from_args(&[]);
+ let mut writer = Cursor::new(vec![]);
+ let exit_code = diff(
+ Some(&PathBuf::from("/dev/null")),
+ Some(&PathBuf::from("/etc/passwd")),
+ &config,
+ &mut writer,
+ );
+ assert_eq!(exit_code, 1);
+ let mut s = String::new();
+ writer.seek(SeekFrom::Start(0)).unwrap();
+ writer.read_to_string(&mut s).unwrap();
+ let s = ansi::strip_ansi_codes(&s);
+ assert!(s.contains("comparing: /dev/null ⟶ /etc/passwd\n"));
+ }
}