rg (ripgrep 15.2), grep (ours, on ripgrep's regex crates), find and xargs (ours), sed (uutils 0.3 wrapper), diff and cmp (uutils diffutils 0.6 with -r), fd 10.5, jaq 2.3, env and timeout. userland/spawn is a small Command-like client of the process interface. search-test.nu: 42 cases match native tools.
86 lines
2.1 KiB
Rust
86 lines
2.1 KiB
Rust
// This file is part of the uutils diffutils package.
|
|
//
|
|
// For the full copyright and license information, please view the LICENSE-*
|
|
// files that was distributed with this source code.
|
|
|
|
use std::{
|
|
env::ArgsOs,
|
|
ffi::{OsStr, OsString},
|
|
iter::Peekable,
|
|
path::{Path, PathBuf},
|
|
process::ExitCode,
|
|
};
|
|
|
|
mod cmp;
|
|
mod context_diff;
|
|
mod diff;
|
|
mod ed_diff;
|
|
mod macros;
|
|
mod normal_diff;
|
|
mod params;
|
|
mod side_diff;
|
|
mod unified_diff;
|
|
mod utils;
|
|
|
|
/// # Panics
|
|
/// Panics if the binary path cannot be determined
|
|
fn binary_path(args: &mut Peekable<ArgsOs>) -> PathBuf {
|
|
match args.peek() {
|
|
Some(ref s) if !s.is_empty() => PathBuf::from(s),
|
|
_ => std::env::current_exe().unwrap(),
|
|
}
|
|
}
|
|
|
|
/// #Panics
|
|
/// Panics if path has no UTF-8 valid name
|
|
fn name(binary_path: &Path) -> &OsStr {
|
|
binary_path.file_stem().unwrap()
|
|
}
|
|
|
|
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
|
|
fn usage(name: &str) {
|
|
println!("{name} {VERSION} (multi-call binary)\n");
|
|
println!("Usage: {name} [function [arguments...]]\n");
|
|
println!("Currently defined functions:\n");
|
|
println!(" cmp, diff\n");
|
|
}
|
|
|
|
fn second_arg_error(name: &OsStr) -> ! {
|
|
eprintln!("Expected utility name as second argument, got nothing.");
|
|
usage(&name.to_string_lossy());
|
|
std::process::exit(0);
|
|
}
|
|
|
|
fn main() -> ExitCode {
|
|
let mut args = std::env::args_os().peekable();
|
|
|
|
let exe_path = binary_path(&mut args);
|
|
let exe_name = name(&exe_path);
|
|
|
|
let util_name = if exe_name.as_encoded_bytes().ends_with(b"diffutils") {
|
|
// Discard the item we peeked.
|
|
let _ = args.next();
|
|
|
|
args.peek()
|
|
.cloned()
|
|
.unwrap_or_else(|| second_arg_error(exe_name))
|
|
} else {
|
|
OsString::from(exe_name)
|
|
};
|
|
|
|
match util_name.as_encoded_bytes() {
|
|
name if name.ends_with(b"diff") => diff::main(args),
|
|
name if name.ends_with(b"cmp") => cmp::main(args),
|
|
name => {
|
|
use std::io::{stderr, Write as _};
|
|
let _ = writeln!(
|
|
stderr(),
|
|
"{}: utility not supported",
|
|
String::from_utf8_lossy(name)
|
|
);
|
|
ExitCode::from(2)
|
|
}
|
|
}
|
|
}
|