Merge branch 'master' of github.com:uutils/coreutils into refactoring_parse_size

This commit is contained in:
Jan Scheer
2021-06-03 22:32:34 +02:00
112 changed files with 489 additions and 350 deletions
+1
View File
@@ -30,6 +30,7 @@ peekreader
quickcheck
rand_chacha
ringbuffer
rlimit
smallvec
tempdir
tempfile
+1
View File
@@ -18,6 +18,7 @@ search the issues to make sure no one else is working on it.
## Best practices
1. Follow what GNU is doing in term of options and behavior.
1. If possible, look at the GNU test suite execution in the CI and make the test work if failing.
1. Use clap for argument management.
1. Make sure that the code coverage is covering all of the cases, including errors.
1. The code must be clippy-warning-free and rustfmt-compliant.
Generated
+11
View File
@@ -233,6 +233,7 @@ dependencies = [
"pretty_assertions",
"rand 0.7.3",
"regex",
"rlimit",
"sha1",
"tempfile",
"textwrap",
@@ -1410,6 +1411,16 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c17925a9027d298a4603d286befe3f9dc0e8ed02523141914eb628798d6e5b"
[[package]]
name = "rlimit"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b02d62c38353a6fce45c25ca19783e25dd5f495ca681c674a4ee15aa4c1536"
dependencies = [
"cfg-if 0.1.10",
"libc",
]
[[package]]
name = "rust-ini"
version = "0.13.0"
+1
View File
@@ -354,6 +354,7 @@ walkdir = "2.2"
atty = "0.2.14"
[target.'cfg(unix)'.dev-dependencies]
rlimit = "0.4.0"
rust-users = { version="0.10", package="users" }
unix_socket = "0.5.0"
+4
View File
@@ -327,8 +327,12 @@ To run locally:
```bash
$ bash util/build-gnu.sh
$ bash util/run-gnu-test.sh
# To run a single test:
$ bash util/run-gnu-test.sh tests/touch/not-owner.sh # for example
```
Note that it relies on individual utilities (not the multicall binary).
## Contribute
To contribute to uutils, please see [CONTRIBUTING](CONTRIBUTING.md).
+2 -3
View File
@@ -11,15 +11,14 @@ extern crate uucore;
use platform_info::*;
use clap::App;
use clap::{crate_version, App};
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Display machine architecture";
static SUMMARY: &str = "Determine architecture name for current machine.";
pub fn uumain(args: impl uucore::Args) -> i32 {
App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.after_help(SUMMARY)
.get_matches_from(args);
+2 -3
View File
@@ -10,11 +10,10 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::path::{is_separator, PathBuf};
use uucore::InvalidEncodingHandling;
static VERSION: &str = env!("CARGO_PKG_VERSION");
static SUMMARY: &str = "Print NAME with any leading directory components removed
If specified, also remove a trailing SUFFIX";
@@ -42,7 +41,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
// Argument parsing
//
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(SUMMARY)
.usage(&usage[..])
.arg(
+2 -3
View File
@@ -16,7 +16,7 @@ extern crate unix_socket;
extern crate uucore;
// last synced with: cat (GNU coreutils) 8.13
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::fs::{metadata, File};
use std::io::{self, Read, Write};
use thiserror::Error;
@@ -38,7 +38,6 @@ use unix_socket::UnixStream;
use uucore::InvalidEncodingHandling;
static NAME: &str = "cat";
static VERSION: &str = env!("CARGO_PKG_VERSION");
static SYNTAX: &str = "[OPTION]... [FILE]...";
static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output
With no FILE, or when FILE is -, read standard input.";
@@ -173,7 +172,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = App::new(executable!())
.name(NAME)
.version(VERSION)
.version(crate_version!())
.usage(SYNTAX)
.about(SUMMARY)
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
+2 -3
View File
@@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
@@ -21,7 +21,6 @@ use uucore::mode;
use uucore::InvalidEncodingHandling;
use walkdir::WalkDir;
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.";
@@ -63,7 +62,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let after_help = get_long_usage();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(&usage[..])
.after_help(&after_help[..])
+2 -3
View File
@@ -14,7 +14,7 @@ use uucore::fs::resolve_relative_path;
use uucore::libc::{gid_t, uid_t};
use uucore::perms::{wrap_chown, Verbosity};
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use walkdir::WalkDir;
@@ -26,7 +26,6 @@ use std::path::Path;
use uucore::InvalidEncodingHandling;
static ABOUT: &str = "change file owner and group";
static VERSION: &str = env!("CARGO_PKG_VERSION");
pub mod options {
pub mod verbosity {
@@ -75,7 +74,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(&usage[..])
.arg(
+2 -3
View File
@@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::ffi::CString;
use std::io::Error;
use std::path::Path;
@@ -18,7 +18,6 @@ use std::process::Command;
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
use uucore::{entries, InvalidEncodingHandling};
static VERSION: &str = env!("CARGO_PKG_VERSION");
static NAME: &str = "chroot";
static ABOUT: &str = "Run COMMAND with root directory set to NEWROOT.";
static SYNTAX: &str = "[OPTION]... NEWROOT [COMMAND [ARG]...]";
@@ -37,7 +36,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.accept_any();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(SYNTAX)
.arg(Arg::with_name(options::NEWROOT).hidden(true).required(true))
+2 -3
View File
@@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::fs::File;
use std::io::{self, stdin, BufReader, Read};
use std::path::Path;
@@ -20,7 +20,6 @@ use uucore::InvalidEncodingHandling;
const CRC_TABLE_LEN: usize = 256;
const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table();
const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = "cksum";
const SYNTAX: &str = "[OPTIONS] [FILE]...";
const SUMMARY: &str = "Print CRC and size for each file";
@@ -187,7 +186,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = App::new(executable!())
.name(NAME)
.version(VERSION)
.version(crate_version!())
.about(SUMMARY)
.usage(SYNTAX)
.arg(Arg::with_name(options::FILE).hidden(true).multiple(true))
+2 -3
View File
@@ -16,9 +16,8 @@ use std::io::{self, stdin, BufRead, BufReader, Stdin};
use std::path::Path;
use uucore::InvalidEncodingHandling;
use clap::{App, Arg, ArgMatches};
use clap::{crate_version, App, Arg, ArgMatches};
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "compare two sorted files line by line";
static LONG_HELP: &str = "";
@@ -140,7 +139,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.accept_any();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(&usage[..])
.after_help(LONG_HELP)
+7 -9
View File
@@ -25,7 +25,7 @@ use winapi::um::fileapi::GetFileInformationByHandle;
use std::borrow::Cow;
use clap::{App, Arg, ArgMatches};
use clap::{crate_version, App, Arg, ArgMatches};
use filetime::FileTime;
use quick_error::ResultExt;
use std::collections::HashSet;
@@ -41,7 +41,7 @@ use std::io;
use std::io::{stdin, stdout, Write};
use std::mem;
#[cfg(target_os = "linux")]
use std::os::unix::io::IntoRawFd;
use std::os::unix::io::AsRawFd;
#[cfg(windows)]
use std::os::windows::ffi::OsStrExt;
use std::path::{Path, PathBuf, StripPrefixError};
@@ -213,7 +213,6 @@ pub struct Options {
verbose: bool,
}
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.";
static LONG_HELP: &str = "";
static EXIT_OK: i32 = 0;
@@ -294,7 +293,7 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP))
.usage(&usage[..])
@@ -1261,17 +1260,16 @@ fn copy_helper(source: &Path, dest: &Path, options: &Options) -> CopyResult<()>
fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyResult<()> {
debug_assert!(mode != ReflinkMode::Never);
let src_file = File::open(source).unwrap().into_raw_fd();
let src_file = File::open(source).context(&*context_for(source, dest))?;
let dst_file = OpenOptions::new()
.write(true)
.truncate(false)
.create(true)
.open(dest)
.unwrap()
.into_raw_fd();
.context(&*context_for(source, dest))?;
match mode {
ReflinkMode::Always => unsafe {
let result = ficlone(dst_file, src_file as *const i32);
let result = ficlone(dst_file.as_raw_fd(), src_file.as_raw_fd() as *const i32);
if result != 0 {
return Err(format!(
"failed to clone {:?} from {:?}: {}",
@@ -1285,7 +1283,7 @@ fn copy_on_write_linux(source: &Path, dest: &Path, mode: ReflinkMode) -> CopyRes
}
},
ReflinkMode::Auto => unsafe {
let result = ficlone(dst_file, src_file as *const i32);
let result = ficlone(dst_file.as_raw_fd(), src_file.as_raw_fd() as *const i32);
if result != 0 {
fs::copy(source, dest).context(&*context_for(source, dest))?;
}
+2 -3
View File
@@ -2,7 +2,7 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg, ArgMatches};
use clap::{crate_version, App, Arg, ArgMatches};
use regex::Regex;
use std::cmp::Ordering;
use std::io::{self, BufReader};
@@ -19,7 +19,6 @@ use crate::csplit_error::CsplitError;
use crate::split_name::SplitName;
use uucore::InvalidEncodingHandling;
static VERSION: &str = env!("CARGO_PKG_VERSION");
static SUMMARY: &str = "split a file into sections determined by context lines";
static LONG_HELP: &str = "Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output.";
@@ -713,7 +712,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.accept_any();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(SUMMARY)
.usage(&usage[..])
.arg(
+2 -3
View File
@@ -11,7 +11,7 @@
extern crate uucore;
use bstr::io::BufReadExt;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::fs::File;
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
use std::path::Path;
@@ -24,7 +24,6 @@ use uucore::InvalidEncodingHandling;
mod searcher;
static NAME: &str = "cut";
static VERSION: &str = env!("CARGO_PKG_VERSION");
static SYNTAX: &str =
"[-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+";
static SUMMARY: &str =
@@ -400,7 +399,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let matches = App::new(executable!())
.name(NAME)
.version(VERSION)
.version(crate_version!())
.usage(SYNTAX)
.about(SUMMARY)
.after_help(LONG_HELP)
+2 -3
View File
@@ -14,7 +14,7 @@ extern crate uucore;
use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
#[cfg(all(unix, not(target_os = "macos")))]
use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
@@ -37,7 +37,6 @@ const SECOND: &str = "second";
const NS: &str = "ns";
const NAME: &str = "date";
const VERSION: &str = env!("CARGO_PKG_VERSION");
const ABOUT: &str = "print or set the system date and time";
const OPT_DATE: &str = "date";
@@ -144,7 +143,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
NAME
);
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(&syntax[..])
.arg(
+2 -3
View File
@@ -12,7 +12,7 @@ extern crate uucore;
use uucore::fsext::statfs_fn;
use uucore::fsext::{read_fs_list, FsUsage, MountInfo};
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use number_prefix::NumberPrefix;
use std::cell::Cell;
@@ -30,7 +30,6 @@ use uucore::libc::{c_char, fsid_t, uid_t};
#[cfg(windows)]
use std::path::Path;
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Show information about the file system on which each FILE resides,\n\
or all file systems by default.";
@@ -260,7 +259,7 @@ fn use_size(free_size: u64, total_size: u64) -> String {
pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(ABOUT)
.usage(&usage[..])
.arg(
+2 -3
View File
@@ -8,12 +8,11 @@
#[macro_use]
extern crate uucore;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::path::Path;
use uucore::InvalidEncodingHandling;
static ABOUT: &str = "strip last component from file name";
static VERSION: &str = env!("CARGO_PKG_VERSION");
mod options {
pub const ZERO: &str = "zero";
@@ -43,7 +42,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.about(ABOUT)
.usage(&usage[..])
.after_help(&after_help[..])
.version(VERSION)
.version(crate_version!())
.arg(
Arg::with_name(options::ZERO)
.long(options::ZERO)
+40 -21
View File
@@ -10,11 +10,13 @@ extern crate uucore;
use chrono::prelude::DateTime;
use chrono::Local;
use clap::{App, Arg};
use clap::{crate_version, App, Arg};
use std::collections::HashSet;
use std::convert::TryFrom;
use std::env;
use std::fs;
#[cfg(not(windows))]
use std::fs::Metadata;
use std::io::{stderr, ErrorKind, Result, Write};
use std::iter;
#[cfg(not(windows))]
@@ -58,7 +60,6 @@ mod options {
pub const FILE: &str = "FILE";
}
const VERSION: &str = env!("CARGO_PKG_VERSION");
const NAME: &str = "du";
const SUMMARY: &str = "estimate file space usage";
const LONG_HELP: &str = "
@@ -94,7 +95,7 @@ struct Stat {
size: u64,
blocks: u64,
inode: Option<FileInfo>,
created: u64,
created: Option<u64>,
accessed: u64,
modified: u64,
}
@@ -115,7 +116,7 @@ impl Stat {
size: metadata.len(),
blocks: metadata.blocks() as u64,
inode: Some(file_info),
created: metadata.mtime() as u64,
created: birth_u64(&metadata),
accessed: metadata.atime() as u64,
modified: metadata.mtime() as u64,
});
@@ -131,7 +132,7 @@ impl Stat {
size: metadata.len(),
blocks: size_on_disk / 1024 * 2,
inode: file_info,
created: windows_time_to_unix_time(metadata.creation_time()),
created: windows_creation_time_to_unix_time(metadata.creation_time()),
accessed: windows_time_to_unix_time(metadata.last_access_time()),
modified: windows_time_to_unix_time(metadata.last_write_time()),
})
@@ -139,10 +140,24 @@ impl Stat {
}
#[cfg(windows)]
// https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.creation_time
// https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.last_access_time
// "The returned 64-bit value [...] which represents the number of 100-nanosecond intervals since January 1, 1601 (UTC)."
// "If the underlying filesystem does not support last access time, the returned value is 0."
fn windows_time_to_unix_time(win_time: u64) -> u64 {
win_time / 10_000_000 - 11_644_473_600
(win_time / 10_000_000).saturating_sub(11_644_473_600)
}
#[cfg(windows)]
fn windows_creation_time_to_unix_time(win_time: u64) -> Option<u64> {
(win_time / 10_000_000).checked_sub(11_644_473_600)
}
#[cfg(not(windows))]
fn birth_u64(meta: &Metadata) -> Option<u64> {
meta.created()
.ok()
.and_then(|t| t.duration_since(UNIX_EPOCH).ok())
.map(|e| e.as_secs() as u64)
}
#[cfg(windows)]
@@ -360,7 +375,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
let usage = get_usage();
let matches = App::new(executable!())
.version(VERSION)
.version(crate_version!())
.about(SUMMARY)
.usage(&usage[..])
.after_help(LONG_HELP)
@@ -501,10 +516,11 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.value_name("WORD")
.require_equals(true)
.min_values(0)
.possible_values(&["atime", "access", "use", "ctime", "status", "birth", "creation"])
.help(
"show time of the last modification of any file in the \
directory, or any of its subdirectories. If WORD is given, show time as WORD instead \
of modification time: atime, access, use, ctime or status"
of modification time: atime, access, use, ctime, status, birth or creation"
)
)
.arg(
@@ -629,19 +645,22 @@ Try '{} --help' for more information.",
let secs = {
match matches.value_of(options::TIME) {
Some(s) => match s {
"accessed" => stat.accessed,
"created" => stat.created,
"modified" => stat.modified,
_ => {
show_error!(
"invalid argument 'modified' for '--time'
Valid arguments are:
- 'accessed', 'created', 'modified'
Try '{} --help' for more information.",
NAME
);
return 1;
"ctime" | "status" => stat.modified,
"access" | "atime" | "use" => stat.accessed,
"birth" | "creation" => {
if let Some(time) = stat.created {
time
} else {
show_error!(
"Invalid argument {} for --time.
birth and creation arguments are not supported on this platform.",
s
);
return 1;
}
}
// below should never happen as clap already restricts the values.
_ => unreachable!("Invalid field for --time"),
},
None => stat.modified,
}

Some files were not shown because too many files have changed in this diff Show More