1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-30 04:27:45 +00:00

Merge branch 'uutils:main' into mkdir-fix

This commit is contained in:
Pyokyeong Son 2022-03-25 23:03:29 +09:00 committed by GitHub
commit 8108fb15b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
249 changed files with 2625 additions and 1299 deletions

View file

@ -20,6 +20,13 @@ env:
on: [push, pull_request]
jobs:
cargo-deny:
name: Style/cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: EmbarkStudios/cargo-deny-action@v1
style_deps:
## ToDO: [2021-11-10; rivy] 'Style/deps' needs more informative output and better integration of results into the GHA dashboard
name: Style/deps
@ -631,7 +638,7 @@ jobs:
# target-specific options
# * CARGO_FEATURES_OPTION
CARGO_FEATURES_OPTION='' ;
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi
outputs CARGO_FEATURES_OPTION
# * CARGO_USE_CROSS (truthy)
CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac;
@ -651,17 +658,6 @@ jobs:
*-pc-windows-msvc) STRIP="" ;;
esac;
outputs STRIP
- name: Install/setup prerequisites
shell: bash
run: |
## Install/setup prerequisites
case '${{ matrix.job.target }}' in
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
case '${{ matrix.job.os }}' in
macos-latest) brew install coreutils ;; # needed for testing
esac
- name: Create all needed build/work directories
shell: bash
run: |
@ -680,6 +676,21 @@ jobs:
case '${{ matrix.job.os }}' in
macos-latest) brew install coreutils ;; # needed for testing
esac
case '${{ matrix.job.os }}' in
ubuntu-*)
# pinky is a tool to show logged-in users from utmp, and gecos fields from /etc/passwd.
# In GitHub Action *nix VMs, no accounts log in, even the "runner" account that runs the commands. The account also has empty gecos fields.
# To work around this for pinky tests, we create a fake login entry for the GH runner account...
FAKE_UTMP='[7] [999999] [tty2] [runner] [tty2] [] [0.0.0.0] [2022-02-22T22:22:22,222222+00:00]'
# ... by dumping the login records, adding our fake line, then reverse dumping ...
(utmpdump /var/run/utmp ; echo $FAKE_UTMP) | sudo utmpdump -r -o /var/run/utmp
# ... and add a full name to each account with a gecos field but no full name.
sudo sed -i 's/:,/:runner name,/' /etc/passwd
# We also create a couple optional files pinky looks for
touch /home/runner/.project
echo "foo" > /home/runner/.plan
;;
esac
- name: rust toolchain ~ install
uses: actions-rs/toolchain@v1
with:
@ -694,7 +705,7 @@ jobs:
## Dependent VARs setup
outputs() { step_id="dep_vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; }
# * determine sub-crate utility list
UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})"
UTILITY_LIST="$(./util/show-utils.sh ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }})"
echo UTILITY_LIST=${UTILITY_LIST}
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)"
outputs CARGO_UTILITY_LIST_OPTIONS
@ -937,7 +948,7 @@ jobs:
# target-specific options
# * CARGO_FEATURES_OPTION
CARGO_FEATURES_OPTION='--all-features' ; ## default to '--all-features' for code coverage
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi
outputs CARGO_FEATURES_OPTION
# * CODECOV_FLAGS
CODECOV_FLAGS=$( echo "${{ matrix.job.os }}" | sed 's/[^[:alnum:]]/_/g' )
@ -949,6 +960,21 @@ jobs:
case '${{ matrix.job.os }}' in
macos-latest) brew install coreutils ;; # needed for testing
esac
case '${{ matrix.job.os }}' in
ubuntu-latest)
# pinky is a tool to show logged-in users from utmp, and gecos fields from /etc/passwd.
# In GitHub Action *nix VMs, no accounts log in, even the "runner" account that runs the commands. The account also has empty gecos fields.
# To work around this for pinky tests, we create a fake login entry for the GH runner account...
FAKE_UTMP='[7] [999999] [tty2] [runner] [tty2] [] [0.0.0.0] [2022-02-22T22:22:22,222222+00:00]'
# ... by dumping the login records, adding our fake line, then reverse dumping ...
(utmpdump /var/run/utmp ; echo $FAKE_UTMP) | sudo utmpdump -r -o /var/run/utmp
# ... and add a full name to each account with a gecos field but no full name.
sudo sed -i 's/:,/:runner name,/' /etc/passwd
# We also create a couple optional files pinky looks for
touch /home/runner/.project
echo "foo" > /home/runner/.plan
;;
esac
- name: rust toolchain ~ install
uses: actions-rs/toolchain@v1
with:
@ -962,7 +988,7 @@ jobs:
## Dependent VARs setup
outputs() { step_id="dep_vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo ::set-output name=${var}::${!var}; done; }
# * determine sub-crate utility list
UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})"
UTILITY_LIST="$(./util/show-utils.sh ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }})"
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo "-puu_${u}"; done;)"
outputs CARGO_UTILITY_LIST_OPTIONS
- name: Test uucore

View file

@ -137,6 +137,8 @@ jobs:
echo "::error ::Failed to find summary of test results (missing '${SUITE_LOG_FILE}'); failing early"
exit 1
fi
# Compress logs before upload (fails otherwise)
gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }}
- name: Reserve SHA1/ID of 'test-summary'
uses: actions/upload-artifact@v2
with:

View file

@ -48,6 +48,7 @@ EditorConfig
FreeBSD
Gmail
GNU
Illumos
Irix
MS-DOS
MSDOS

View file

@ -94,6 +94,16 @@ uutils: add new utility
gitignore: add temporary files
```
## cargo-deny
This project uses [cargo-deny](https://github.com/EmbarkStudios/cargo-deny/) to
detect duplicate dependencies, checks licenses, etc. To run it locally, first
install it and then run with:
```
cargo deny --all-features check all
```
## Licensing
uutils is distributed under the terms of the MIT License; see the `LICENSE` file

289
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -245,11 +245,11 @@ test = [ "uu_test" ]
[workspace]
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
clap_complete = "3.0"
phf = "0.10.1"
lazy_static = { version="1.3" }
textwrap = { version="0.14", features=["terminal_size"] }
textwrap = { version="0.15", features=["terminal_size"] }
uucore = { version=">=0.0.11", package="uucore", path="src/uucore" }
selinux = { version="0.2", optional = true }
ureq = "2.4.0"

View file

@ -43,7 +43,7 @@ pub fn main() {
let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();
mf.write_all(
"type UtilityMap<T> = phf::Map<&'static str, (fn(T) -> i32, fn() -> App<'static>)>;\n\
"type UtilityMap<T> = phf::Map<&'static str, (fn(T) -> i32, fn() -> Command<'static>)>;\n\
\n\
fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n"
.as_bytes(),

95
deny.toml Normal file
View file

@ -0,0 +1,95 @@
# spell-checker:ignore SSLeay RUSTSEC
# This section is considered when running `cargo deny check advisories`
# More documentation for the advisories section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
vulnerability = "warn"
unmaintained = "warn"
yanked = "warn"
notice = "warn"
ignore = [
#"RUSTSEC-0000-0000",
]
# This section is considered when running `cargo deny check licenses`
# More documentation for the licenses section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
[licenses]
unlicensed = "deny"
allow = [
"MIT",
"Apache-2.0",
"ISC",
"BSD-2-Clause",
"BSD-2-Clause-FreeBSD",
"BSD-3-Clause",
"CC0-1.0",
"MPL-2.0", # XXX considered copyleft?
]
copyleft = "deny"
allow-osi-fsf-free = "neither"
default = "deny"
confidence-threshold = 0.8
exceptions = [
{ allow = ["OpenSSL"], name = "ring" },
]
[[licenses.clarify]]
name = "ring"
# SPDX considers OpenSSL to encompass both the OpenSSL and SSLeay licenses
# https://spdx.org/licenses/OpenSSL.html
# ISC - Both BoringSSL and ring use this for their new files
# MIT - "Files in third_party/ have their own licenses, as described therein. The MIT
# license, for third_party/fiat, which, unlike other third_party directories, is
# compiled into non-test libraries, is included below."
# OpenSSL - Obviously
expression = "ISC AND MIT AND OpenSSL"
license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }]
# This section is considered when running `cargo deny check bans`.
# More documentation about the 'bans' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html
[bans]
multiple-versions = "deny"
wildcards = "allow"
highlight = "all"
# For each duplicate dependency, indicate the name of the dependency which
# introduces it.
# spell-checker: disable
skip = [
# blake2d_simd
{ name = "arrayvec", version = "=0.7.2" },
# flimit/unix_socket
{ name = "cfg-if", version = "=0.1.10" },
# ordered-multimap
{ name = "hashbrown", version = "=0.9.1" },
# kernel32-sys
{ name = "winapi", version = "=0.2.8" },
# bindgen 0.59.2
{ name = "clap", version = "=2.34.0" },
{ name = "strsim", version = "=0.8.0" },
{ name = "textwrap", version = "=0.11.0" },
{ name = "cpp_common", version = "=0.4.0" },
# quickcheck
{ name = "env_logger", version = "=0.8.4" },
# cpp_*
{ name = "memchr", version = "=1.0.2" },
{ name = "quote", version = "=0.3.15" },
{ name = "unicode-xid", version = "=0.0.4" },
# exacl
{ name = "nix", version = "=0.21.0" },
]
# spell-checker: enable
# This section is considered when running `cargo deny check sources`.
# More documentation about the 'sources' section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html
[sources]
unknown-registry = "warn"
unknown-git = "warn"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []

View file

@ -40,6 +40,8 @@ TARGETS = [
"x86_64-linux-android",
# Solaris
"x86_64-sun-solaris",
# Illumos
"x86_64-unknown-illumos",
# WASM
"wasm32-wasi",
# Redox

View file

@ -5,7 +5,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use clap::{App, Arg};
use clap::{Arg, Command};
use clap_complete::Shell;
use std::cmp;
use std::ffi::OsStr;
@ -138,7 +138,7 @@ fn gen_completions<T: uucore::Args>(
.chain(util_map.keys().copied())
.collect();
let matches = App::new("completion")
let matches = Command::new("completion")
.about("Prints completions to stdout")
.arg(
Arg::new("utility")
@ -155,7 +155,7 @@ fn gen_completions<T: uucore::Args>(
let utility = matches.value_of("utility").unwrap();
let shell = matches.value_of("shell").unwrap();
let mut app = if utility == "coreutils" {
let mut command = if utility == "coreutils" {
gen_coreutils_app(util_map)
} else {
util_map.get(utility).unwrap().1()
@ -163,15 +163,15 @@ fn gen_completions<T: uucore::Args>(
let shell: Shell = shell.parse().unwrap();
let bin_name = std::env::var("PROG_PREFIX").unwrap_or_default() + utility;
clap_complete::generate(shell, &mut app, bin_name, &mut io::stdout());
clap_complete::generate(shell, &mut command, bin_name, &mut io::stdout());
io::stdout().flush().unwrap();
process::exit(0);
}
fn gen_coreutils_app<T: uucore::Args>(util_map: &UtilityMap<T>) -> App<'static> {
let mut app = App::new("coreutils");
fn gen_coreutils_app<T: uucore::Args>(util_map: &UtilityMap<T>) -> Command<'static> {
let mut command = Command::new("coreutils");
for (_, (_, sub_app)) in util_map {
app = app.subcommand(sub_app());
command = command.subcommand(sub_app());
}
app
command
}

View file

@ -4,7 +4,7 @@
// file that was distributed with this source code.
// spell-checker:ignore tldr
use clap::App;
use clap::Command;
use std::ffi::OsString;
use std::fs::File;
use std::io::Cursor;
@ -46,13 +46,13 @@ fn main() -> io::Result<()> {
let mut utils = utils.entries().collect::<Vec<_>>();
utils.sort();
for (&name, (_, app)) in utils {
for (&name, (_, command)) in utils {
if name == "[" {
continue;
}
let p = format!("docs/src/utils/{}.md", name);
if let Ok(f) = File::create(&p) {
write_markdown(f, &mut app(), name, &mut tldr_zip)?;
write_markdown(f, &mut command(), name, &mut tldr_zip)?;
println!("Wrote to '{}'", p);
} else {
println!("Error writing to {}", p);
@ -64,29 +64,29 @@ fn main() -> io::Result<()> {
fn write_markdown(
mut w: impl Write,
app: &mut App,
command: &mut Command,
name: &str,
tldr_zip: &mut zip::ZipArchive<impl Read + Seek>,
) -> io::Result<()> {
write!(w, "# {}\n\n", name)?;
write_version(&mut w, app)?;
write_usage(&mut w, app, name)?;
write_description(&mut w, app)?;
write_options(&mut w, app)?;
write_version(&mut w, command)?;
write_usage(&mut w, command, name)?;
write_description(&mut w, command)?;
write_options(&mut w, command)?;
write_examples(&mut w, name, tldr_zip)
}
fn write_version(w: &mut impl Write, app: &App) -> io::Result<()> {
fn write_version(w: &mut impl Write, command: &Command) -> io::Result<()> {
writeln!(
w,
"<div class=\"version\">version: {}</div>",
app.render_version().split_once(' ').unwrap().1
command.render_version().split_once(' ').unwrap().1
)
}
fn write_usage(w: &mut impl Write, app: &mut App, name: &str) -> io::Result<()> {
fn write_usage(w: &mut impl Write, command: &mut Command, name: &str) -> io::Result<()> {
writeln!(w, "\n```")?;
let mut usage: String = app
let mut usage: String = command
.render_usage()
.lines()
.skip(1)
@ -99,8 +99,8 @@ fn write_usage(w: &mut impl Write, app: &mut App, name: &str) -> io::Result<()>
writeln!(w, "```")
}
fn write_description(w: &mut impl Write, app: &App) -> io::Result<()> {
if let Some(about) = app.get_long_about().or_else(|| app.get_about()) {
fn write_description(w: &mut impl Write, command: &Command) -> io::Result<()> {
if let Some(about) = command.get_long_about().or_else(|| command.get_about()) {
writeln!(w, "{}", about)
} else {
Ok(())
@ -152,10 +152,10 @@ fn get_zip_content(archive: &mut ZipArchive<impl Read + Seek>, name: &str) -> Op
Some(s)
}
fn write_options(w: &mut impl Write, app: &App) -> io::Result<()> {
fn write_options(w: &mut impl Write, command: &Command) -> io::Result<()> {
writeln!(w, "<h2>Options</h2>")?;
write!(w, "<dl>")?;
for arg in app.get_arguments() {
for arg in command.get_arguments() {
write!(w, "<dt>")?;
let mut first = true;
for l in arg.get_long_and_visible_aliases().unwrap_or_default() {

View file

@ -16,7 +16,7 @@ path = "src/arch.rs"
[dependencies]
platform-info = "0.2"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -8,7 +8,7 @@
use platform_info::*;
use clap::{crate_version, App, AppSettings};
use clap::{crate_version, Command};
use uucore::error::{FromIo, UResult};
static ABOUT: &str = "Display machine architecture";
@ -23,10 +23,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.after_help(SUMMARY)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/base32.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features = ["encoding"] }
[[bin]]

View file

@ -7,7 +7,7 @@
use std::io::{stdin, Read};
use clap::App;
use clap::Command;
use uucore::{encoding::Format, error::UResult};
pub mod base_common;
@ -44,6 +44,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
)
}
pub fn uu_app<'a>() -> App<'a> {
pub fn uu_app<'a>() -> Command<'a> {
base_common::base_app(ABOUT, USAGE)
}

View file

@ -18,7 +18,7 @@ use std::fs::File;
use std::io::{BufReader, Stdin};
use std::path::Path;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
pub static BASE_CMD_PARSE_ERROR: i32 = 1;
@ -86,19 +86,19 @@ impl Config {
}
pub fn parse_base_cmd_args(args: impl uucore::Args, about: &str, usage: &str) -> UResult<Config> {
let app = base_app(about, usage);
let command = base_app(about, usage);
let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
Config::from(&app.get_matches_from(arg_list))
Config::from(&command.get_matches_from(arg_list))
}
pub fn base_app<'a>(about: &'a str, usage: &'a str) -> App<'a> {
App::new(uucore::util_name())
pub fn base_app<'a>(about: &'a str, usage: &'a str) -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(about)
.override_usage(format_usage(usage))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
// Format arguments.
.arg(
Arg::new(options::DECODE)

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/basename.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -7,7 +7,7 @@
// spell-checker:ignore (ToDO) fullname
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::path::{is_separator, PathBuf};
use uucore::display::Quotable;
use uucore::error::{UResult, UUsageError};
@ -87,12 +87,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::MULTIPLE)
.short('a')

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/basenc.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features = ["encoding"] }
uu_base32 = { version=">=0.0.8", package="uu_base32", path="../base32"}

View file

@ -8,7 +8,7 @@
//spell-checker:ignore (args) lsbf msbf
use clap::{App, Arg};
use clap::{Arg, Command};
use uu_base32::base_common::{self, Config, BASE_CMD_PARSE_ERROR};
use uucore::{
@ -40,12 +40,12 @@ const ENCODINGS: &[(&str, Format)] = &[
const USAGE: &str = "{} [OPTION]... [FILE]";
pub fn uu_app<'a>() -> App<'a> {
let mut app = base_common::base_app(ABOUT, USAGE);
pub fn uu_app<'a>() -> Command<'a> {
let mut command = base_common::base_app(ABOUT, USAGE);
for encoding in ENCODINGS {
app = app.arg(Arg::new(encoding.0).long(encoding.0));
command = command.arg(Arg::new(encoding.0).long(encoding.0));
}
app
command
}
fn parse_cmd_args(args: impl uucore::Args) -> UResult<(Config, Format)> {

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/cat.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
thiserror = "1.0"
atty = "0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "pipes"] }
@ -24,9 +24,6 @@ uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=[
unix_socket = "0.5.0"
nix = "0.23.1"
[target.'cfg(windows)'.dependencies]
winapi-util = "0.1.5"
[[bin]]
name = "cat"
path = "src/main.rs"

View file

@ -14,7 +14,7 @@
extern crate unix_socket;
// last synced with: cat (GNU coreutils) 8.13
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs::{metadata, File};
use std::io::{self, Read, Write};
use thiserror::Error;
@ -239,13 +239,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
cat_files(&files, &options)
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.override_usage(format_usage(USAGE))
.about(SUMMARY)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::FILE)
.hide(true)

View file

@ -14,7 +14,7 @@ edition = "2018"
path = "src/chcon.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version = ">=0.0.9", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
selinux = { version = "0.2" }
fts-sys = { version = "0.2" }

View file

@ -6,7 +6,7 @@ use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::{display::Quotable, show_error, show_warning};
use clap::{App, AppSettings, Arg};
use clap::{Arg, Command};
use selinux::{OpaqueSecurityContext, SecurityContext};
use std::borrow::Cow;
@ -29,6 +29,7 @@ const USAGE: &str = "\
{} [OPTION]... --reference=RFILE FILE...";
pub mod options {
pub static HELP: &str = "help";
pub static VERBOSE: &str = "verbose";
pub static REFERENCE: &str = "reference";
@ -65,7 +66,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(r) => r,
Err(r) => {
if let Error::CommandLine(r) = &r {
match r.kind {
match r.kind() {
clap::ErrorKind::DisplayHelp | clap::ErrorKind::DisplayVersion => {
println!("{}", r);
return Ok(());
@ -154,12 +155,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Err(libc::EXIT_FAILURE.into())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(VERSION)
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information."),
)
.arg(
Arg::new(options::dereference::DEREFERENCE)
.long(options::dereference::DEREFERENCE)
@ -303,7 +309,7 @@ struct Options {
files: Vec<PathBuf>,
}
fn parse_command_line(config: clap::App, args: impl uucore::Args) -> Result<Options> {
fn parse_command_line(config: clap::Command, args: impl uucore::Args) -> Result<Options> {
let matches = config.try_get_matches_from(args)?;
let verbose = matches.is_present(options::VERBOSE);
@ -402,23 +408,21 @@ enum RecursiveMode {
impl RecursiveMode {
fn is_recursive(self) -> bool {
match self {
RecursiveMode::NotRecursive => false,
Self::NotRecursive => false,
RecursiveMode::RecursiveButDoNotFollowSymLinks
| RecursiveMode::RecursiveAndFollowAllDirSymLinks
| RecursiveMode::RecursiveAndFollowArgDirSymLinks => true,
Self::RecursiveButDoNotFollowSymLinks
| Self::RecursiveAndFollowAllDirSymLinks
| Self::RecursiveAndFollowArgDirSymLinks => true,
}
}
fn fts_open_options(self) -> c_int {
match self {
RecursiveMode::NotRecursive | RecursiveMode::RecursiveButDoNotFollowSymLinks => {
fts_sys::FTS_PHYSICAL
}
Self::NotRecursive | Self::RecursiveButDoNotFollowSymLinks => fts_sys::FTS_PHYSICAL,
RecursiveMode::RecursiveAndFollowAllDirSymLinks => fts_sys::FTS_LOGICAL,
Self::RecursiveAndFollowAllDirSymLinks => fts_sys::FTS_LOGICAL,
RecursiveMode::RecursiveAndFollowArgDirSymLinks => {
Self::RecursiveAndFollowArgDirSymLinks => {
fts_sys::FTS_PHYSICAL | fts_sys::FTS_COMFOLLOW
}
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/chgrp.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
[[bin]]

View file

@ -13,7 +13,7 @@ use uucore::error::{FromIo, UResult, USimpleError};
use uucore::format_usage;
use uucore::perms::{chown_base, options, IfFrom};
use clap::{App, AppSettings, Arg, ArgMatches};
use clap::{Arg, ArgMatches, Command};
use std::fs;
use std::os::unix::fs::MetadataExt;
@ -54,12 +54,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
chown_base(uu_app(), args, options::ARG_GROUP, parse_gid_and_uid, true)
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(VERSION)
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information.")
)
.arg(
Arg::new(options::verbosity::CHANGES)
.short('c')

View file

@ -15,8 +15,8 @@ edition = "2018"
path = "src/chmod.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.121"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "mode"] }
[[bin]]

View file

@ -7,7 +7,7 @@
// spell-checker:ignore (ToDO) Chmoder cmode fmode fperm fref ugoa RFILE RFILE's
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
@ -112,12 +112,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
chmoder.chmod(&files)
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::CHANGES)
.long(options::CHANGES)

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/chown.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
[[bin]]

View file

@ -14,7 +14,7 @@ use uucore::perms::{chown_base, options, IfFrom};
use uucore::error::{FromIo, UResult, USimpleError};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use std::fs;
use std::os::unix::fs::MetadataExt;
@ -63,12 +63,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
)
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information."),
)
.arg(
Arg::new(options::verbosity::CHANGES)
.short('c')

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/chroot.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries"] }
[[bin]]

View file

@ -10,11 +10,11 @@
mod error;
use crate::error::ChrootError;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::ffi::CString;
use std::io::Error;
use std::path::Path;
use std::process::Command;
use std::process;
use uucore::error::{set_exit_code, UResult};
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
use uucore::{entries, format_usage, InvalidEncodingHandling};
@ -77,7 +77,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// NOTE: Tests can only trigger code beyond this point if they're invoked with root permissions
set_context(newroot, &matches)?;
let pstatus = match Command::new(chroot_command).args(chroot_args).status() {
let pstatus = match process::Command::new(chroot_command)
.args(chroot_args)
.status()
{
Ok(status) => status,
Err(e) => return Err(ChrootError::CommandFailed(command[0].to_string(), e).into()),
};
@ -91,12 +94,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::NEWROOT)
.hide(true)

View file

@ -55,25 +55,25 @@ impl UError for ChrootError {
impl Display for ChrootError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ChrootError::CannotEnter(s, e) => write!(f, "cannot chroot to {}: {}", s.quote(), e,),
ChrootError::CommandFailed(s, e) => {
Self::CannotEnter(s, e) => write!(f, "cannot chroot to {}: {}", s.quote(), e,),
Self::CommandFailed(s, e) => {
write!(f, "failed to run command {}: {}", s.to_string().quote(), e,)
}
ChrootError::InvalidUserspec(s) => write!(f, "invalid userspec: {}", s.quote(),),
ChrootError::MissingNewRoot => write!(
Self::InvalidUserspec(s) => write!(f, "invalid userspec: {}", s.quote(),),
Self::MissingNewRoot => write!(
f,
"Missing operand: NEWROOT\nTry '{} --help' for more information.",
uucore::execution_phrase(),
),
ChrootError::NoSuchGroup(s) => write!(f, "no such group: {}", s.maybe_quote(),),
ChrootError::NoSuchDirectory(s) => write!(
Self::NoSuchGroup(s) => write!(f, "no such group: {}", s.maybe_quote(),),
Self::NoSuchDirectory(s) => write!(
f,
"cannot change root directory to {}: no such directory",
s.quote(),
),
ChrootError::SetGidFailed(s, e) => write!(f, "cannot set gid to {}: {}", s, e),
ChrootError::SetGroupsFailed(e) => write!(f, "cannot set groups: {}", e),
ChrootError::SetUserFailed(s, e) => {
Self::SetGidFailed(s, e) => write!(f, "cannot set gid to {}: {}", s, e),
Self::SetGroupsFailed(e) => write!(f, "cannot set groups: {}", e),
Self::SetUserFailed(s, e) => {
write!(f, "cannot set user to {}: {}", s.maybe_quote(), e)
}
}

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/cksum.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -6,7 +6,7 @@
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) fname
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs::File;
use std::io::{self, stdin, BufReader, Read};
use std::path::Path;
@ -140,13 +140,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.about(SUMMARY)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::FILE)
.hide(true)

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/comm.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -15,7 +15,7 @@ use uucore::error::FromIo;
use uucore::error::UResult;
use uucore::{format_usage, InvalidEncodingHandling};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
static ABOUT: &str = "compare two sorted files line by line";
static LONG_HELP: &str = "";
@ -143,13 +143,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.after_help(LONG_HELP)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::COLUMN_1)
.short('1')

View file

@ -19,9 +19,9 @@ edition = "2018"
path = "src/cp.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
filetime = "0.2"
libc = "0.2.85"
libc = "0.2.121"
quick-error = "2.0.1"
selinux = { version="0.2", optional=true }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] }

View file

@ -28,7 +28,7 @@ use winapi::um::fileapi::GetFileInformationByHandle;
use std::borrow::Cow;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use filetime::FileTime;
#[cfg(unix)]
use libc::mkfifo;
@ -296,7 +296,7 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[
Attribute::Timestamps,
];
pub fn uu_app<'a>() -> App<'a> {
pub fn uu_app<'a>() -> Command<'a> {
const MODE_ARGS: &[&str] = &[
options::LINK,
options::REFLINK,
@ -304,17 +304,23 @@ pub fn uu_app<'a>() -> App<'a> {
options::ATTRIBUTES_ONLY,
options::COPY_CONTENTS,
];
App::new(uucore::util_name())
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(Arg::new(options::TARGET_DIRECTORY)
.short('t')
.conflicts_with(options::NO_TARGET_DIRECTORY)
.long(options::TARGET_DIRECTORY)
.value_name(options::TARGET_DIRECTORY)
.takes_value(true)
.validator(|s| {
if Path::new(s).is_dir() {
return Ok(());
}
Err(format!("'{}' is not a directory", s))
})
.help("copy all SOURCE arguments into target-directory"))
.arg(Arg::new(options::NO_TARGET_DIRECTORY)
.short('T')
@ -389,7 +395,7 @@ pub fn uu_app<'a>() -> App<'a> {
.long(options::PRESERVE)
.takes_value(true)
.multiple_occurrences(true)
.use_delimiter(true)
.use_value_delimiter(true)
.possible_values(PRESERVABLE_ATTRIBUTES)
.min_values(0)
.value_name("ATTR_LIST")
@ -469,7 +475,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
LONG_HELP,
backup_control::BACKUP_CONTROL_LONG_HELP
))
.get_matches_from(args);
.try_get_matches_from(args)?;
let options = Options::from_matches(&matches)?;
@ -1087,8 +1093,8 @@ fn copy_directory(
impl OverwriteMode {
fn verify(&self, path: &Path) -> CopyResult<()> {
match *self {
OverwriteMode::NoClobber => Err(Error::NotAllFilesCopied),
OverwriteMode::Interactive(_) => {
Self::NoClobber => Err(Error::NotAllFilesCopied),
Self::Interactive(_) => {
if prompt_yes!("{}: overwrite {}? ", uucore::util_name(), path.quote()) {
Ok(())
} else {
@ -1098,7 +1104,7 @@ impl OverwriteMode {
)))
}
}
OverwriteMode::Clobber(_) => Ok(()),
Self::Clobber(_) => Ok(()),
}
}
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/csplit.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
thiserror = "1.0"
regex = "1.0.0"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "fs"] }

View file

@ -12,7 +12,7 @@ use std::{
io::{BufRead, BufWriter, Write},
};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use regex::Regex;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
@ -746,12 +746,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::SUFFIX_FORMAT)
.short('b')

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/cut.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
memchr = "2"
bstr = "0.2"

View file

@ -11,7 +11,7 @@
extern crate uucore;
use bstr::io::BufReadExt;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs::File;
use std::io::{stdin, stdout, BufReader, BufWriter, Read, Write};
use std::path::Path;
@ -533,14 +533,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.override_usage(format_usage(USAGE))
.about(SUMMARY)
.after_help(LONG_HELP)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::BYTES)
.short('b')

View file

@ -16,7 +16,7 @@ path = "src/date.rs"
[dependencies]
chrono = "^0.4.11"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[target.'cfg(unix)'.dependencies]

View file

@ -11,7 +11,7 @@
use chrono::{DateTime, FixedOffset, Local, Offset, Utc};
#[cfg(windows)]
use chrono::{Datelike, Timelike};
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
use libc::{clock_settime, timespec, CLOCK_REALTIME};
use std::fs::File;
@ -254,12 +254,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(OPT_DATE)
.short('d')

View file

@ -16,14 +16,11 @@ path = "src/dd.rs"
[dependencies]
byte-unit = "4.0"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
gcd = "2.0"
libc = "0.2"
uucore = { version=">=0.0.8", package="uucore", path="../../uucore" }
[dev-dependencies]
tempfile = "3"
[target.'cfg(target_os = "linux")'.dependencies]
signal-hook = "0.3.9"

View file

@ -4,7 +4,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore ctable, outfile
// spell-checker:ignore ctable, outfile, iseek, oseek
use std::error::Error;
@ -120,6 +120,8 @@ pub mod options {
pub const COUNT: &str = "count";
pub const SKIP: &str = "skip";
pub const SEEK: &str = "seek";
pub const ISEEK: &str = "iseek";
pub const OSEEK: &str = "oseek";
pub const STATUS: &str = "status";
pub const CONV: &str = "conv";
pub const IFLAG: &str = "iflag";

View file

@ -5,7 +5,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable
mod datastructures;
use datastructures::*;
@ -34,7 +34,7 @@ use std::sync::mpsc;
use std::thread;
use std::time;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use gcd::Gcd;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
@ -60,7 +60,9 @@ impl Input<io::Stdin> {
let print_level = parseargs::parse_status_level(matches)?;
let cflags = parseargs::parse_conv_flag_input(matches)?;
let iflags = parseargs::parse_iflags(matches)?;
let skip = parseargs::parse_skip_amt(&ibs, &iflags, matches)?;
let skip = parseargs::parse_seek_skip_amt(&ibs, iflags.skip_bytes, matches, options::SKIP)?;
let iseek =
parseargs::parse_seek_skip_amt(&ibs, iflags.skip_bytes, matches, options::ISEEK)?;
let count = parseargs::parse_count(&iflags, matches)?;
let mut i = Self {
@ -73,7 +75,9 @@ impl Input<io::Stdin> {
iflags,
};
if let Some(amt) = skip {
// The --skip and --iseek flags are additive. On a stream, they discard bytes.
let amt = skip.unwrap_or(0) + iseek.unwrap_or(0);
if amt > 0 {
if let Err(e) = i.read_skip(amt) {
if let io::ErrorKind::UnexpectedEof = e.kind() {
show_error!("'standard input': cannot skip to specified offset");
@ -131,7 +135,9 @@ impl Input<File> {
let print_level = parseargs::parse_status_level(matches)?;
let cflags = parseargs::parse_conv_flag_input(matches)?;
let iflags = parseargs::parse_iflags(matches)?;
let skip = parseargs::parse_skip_amt(&ibs, &iflags, matches)?;
let skip = parseargs::parse_seek_skip_amt(&ibs, iflags.skip_bytes, matches, options::SKIP)?;
let iseek =
parseargs::parse_seek_skip_amt(&ibs, iflags.skip_bytes, matches, options::ISEEK)?;
let count = parseargs::parse_count(&iflags, matches)?;
if let Some(fname) = matches.value_of(options::INFILE) {
@ -148,7 +154,9 @@ impl Input<File> {
.map_err_context(|| "failed to open input file".to_string())?
};
if let Some(amt) = skip {
// The --skip and --iseek flags are additive. On a file, they seek.
let amt = skip.unwrap_or(0) + iseek.unwrap_or(0);
if amt > 0 {
src.seek(io::SeekFrom::Start(amt))
.map_err_context(|| "failed to seek in input file".to_string())?;
}
@ -292,12 +300,16 @@ impl OutputTrait for Output<io::Stdout> {
let obs = parseargs::parse_obs(matches)?;
let cflags = parseargs::parse_conv_flag_output(matches)?;
let oflags = parseargs::parse_oflags(matches)?;
let seek = parseargs::parse_seek_amt(&obs, &oflags, matches)?;
let seek = parseargs::parse_seek_skip_amt(&obs, oflags.seek_bytes, matches, options::SEEK)?;
let oseek =
parseargs::parse_seek_skip_amt(&obs, oflags.seek_bytes, matches, options::OSEEK)?;
let mut dst = io::stdout();
// The --seek and --oseek flags are additive.
let amt = seek.unwrap_or(0) + oseek.unwrap_or(0);
// stdout is not seekable, so we just write null bytes.
if let Some(amt) = seek {
if amt > 0 {
io::copy(&mut io::repeat(0u8).take(amt as u64), &mut dst)
.map_err_context(|| String::from("write error"))?;
}
@ -508,7 +520,9 @@ impl OutputTrait for Output<File> {
let obs = parseargs::parse_obs(matches)?;
let cflags = parseargs::parse_conv_flag_output(matches)?;
let oflags = parseargs::parse_oflags(matches)?;
let seek = parseargs::parse_seek_amt(&obs, &oflags, matches)?;
let seek = parseargs::parse_seek_skip_amt(&obs, oflags.seek_bytes, matches, options::SEEK)?;
let oseek =
parseargs::parse_seek_skip_amt(&obs, oflags.seek_bytes, matches, options::OSEEK)?;
if let Some(fname) = matches.value_of(options::OUTFILE) {
let mut dst = open_dst(Path::new(&fname), &cflags, &oflags)
@ -522,7 +536,9 @@ impl OutputTrait for Output<File> {
// Instead, we suppress the error by calling
// `Result::ok()`. This matches the behavior of GNU `dd`
// when given the command-line argument `of=/dev/null`.
let i = seek.unwrap_or(0);
// The --seek and --oseek flags are additive.
let i = seek.unwrap_or(0) + oseek.unwrap_or(0);
if !cflags.notrunc {
dst.set_len(i).ok();
}
@ -730,11 +746,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::INFILE)
.long(options::INFILE)
@ -807,6 +823,24 @@ pub fn uu_app<'a>() -> App<'a> {
.value_name("N")
.help("(alternatively seek=N) seeks N obs-sized records into output before beginning copy/convert operations. See oflag=seek_bytes if seeking N bytes is preferred. Multiplier strings permitted.")
)
.arg(
Arg::new(options::ISEEK)
.long(options::ISEEK)
.overrides_with(options::ISEEK)
.takes_value(true)
.require_equals(true)
.value_name("N")
.help("(alternatively iseek=N) seeks N obs-sized records into input before beginning copy/convert operations. See iflag=seek_bytes if seeking N bytes is preferred. Multiplier strings permitted.")
)
.arg(
Arg::new(options::OSEEK)
.long(options::OSEEK)
.overrides_with(options::OSEEK)
.takes_value(true)
.require_equals(true)
.value_name("N")
.help("(alternatively oseek=N) seeks N obs-sized records into output before beginning copy/convert operations. See oflag=seek_bytes if seeking N bytes is preferred. Multiplier strings permitted.")
)
.arg(
Arg::new(options::COUNT)
.long(options::COUNT)
@ -846,8 +880,8 @@ Printing performance stats is also triggered by the INFO signal (where supported
.long(options::CONV)
.takes_value(true)
.multiple_occurrences(true)
.use_delimiter(true)
.require_delimiter(true)
.use_value_delimiter(true)
.require_value_delimiter(true)
.multiple_values(true)
.require_equals(true)
.value_name("CONV")
@ -887,8 +921,8 @@ Conversion Flags:
.long(options::IFLAG)
.takes_value(true)
.multiple_occurrences(true)
.use_delimiter(true)
.require_delimiter(true)
.use_value_delimiter(true)
.require_value_delimiter(true)
.multiple_values(true)
.require_equals(true)
.value_name("FLAG")
@ -917,8 +951,8 @@ General-Flags
.long(options::OFLAG)
.takes_value(true)
.multiple_occurrences(true)
.use_delimiter(true)
.require_delimiter(true)
.use_value_delimiter(true)
.require_value_delimiter(true)
.multiple_values(true)
.require_equals(true)
.value_name("FLAG")

View file

@ -4,7 +4,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore ctty, ctable, iconvflags, oconvflags parseargs
// spell-checker:ignore ctty, ctable, iseek, oseek, iconvflags, oconvflags parseargs
#[cfg(test)]
mod unit_tests;
@ -100,16 +100,16 @@ impl std::fmt::Display for ParseError {
Self::StatusLevelNotRecognized(arg) => {
write!(f, "status=LEVEL not recognized -> {}", arg)
}
ParseError::BsOutOfRange => {
Self::BsOutOfRange => {
write!(f, "bs=N cannot fit into memory")
}
ParseError::IbsOutOfRange => {
Self::IbsOutOfRange => {
write!(f, "ibs=N cannot fit into memory")
}
ParseError::ObsOutOfRange => {
Self::ObsOutOfRange => {
write!(f, "obs=N cannot fit into memory")
}
ParseError::CbsOutOfRange => {
Self::CbsOutOfRange => {
write!(f, "cbs=N cannot fit into memory")
}
Self::Unimplemented(arg) => {
@ -740,15 +740,15 @@ pub fn parse_oflags(matches: &Matches) -> Result<OFlags, ParseError> {
Ok(oflags)
}
/// Parse the amount of the input file to skip.
pub fn parse_skip_amt(
pub fn parse_seek_skip_amt(
ibs: &usize,
iflags: &IFlags,
bytes: bool,
matches: &Matches,
option: &str,
) -> Result<Option<u64>, ParseError> {
if let Some(amt) = matches.value_of(options::SKIP) {
if let Some(amt) = matches.value_of(option) {
let n = parse_bytes_with_opt_multiplier(amt)?;
if iflags.skip_bytes {
if bytes {
Ok(Some(n))
} else {
Ok(Some(*ibs as u64 * n))
@ -758,24 +758,6 @@ pub fn parse_skip_amt(
}
}
/// Parse the amount of the output file to seek.
pub fn parse_seek_amt(
obs: &usize,
oflags: &OFlags,
matches: &Matches,
) -> Result<Option<u64>, ParseError> {
if let Some(amt) = matches.value_of(options::SEEK) {
let n = parse_bytes_with_opt_multiplier(amt)?;
if oflags.seek_bytes {
Ok(Some(n))
} else {
Ok(Some(*obs as u64 * n))
}
} else {
Ok(None)
}
}
/// Parse the value of count=N and the type of N implied by iflags
pub fn parse_count(iflags: &IFlags, matches: &Matches) -> Result<Option<CountType>, ParseError> {
if let Some(amt) = matches.value_of(options::COUNT) {

View file

@ -1,4 +1,4 @@
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat
// spell-checker:ignore fname, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, btotal, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rposition, rremain, rsofar, rstat, sigusr, sigval, wlen, wstat
use super::*;
@ -112,6 +112,8 @@ fn test_all_top_level_args_no_leading_dashes() {
String::from("count=2"),
String::from("skip=2"),
String::from("seek=2"),
String::from("iseek=2"),
String::from("oseek=2"),
String::from("status=progress"),
String::from("conv=ascii,ucase"),
String::from("iflag=count_bytes,skip_bytes"),
@ -140,13 +142,25 @@ fn test_all_top_level_args_no_leading_dashes() {
);
assert_eq!(
200,
parse_skip_amt(&100, &IFlags::default(), &matches)
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::SKIP)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_amt(&100, &OFlags::default(), &matches)
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::SEEK)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::ISEEK)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::OSEEK)
.unwrap()
.unwrap()
);
@ -197,6 +211,8 @@ fn test_all_top_level_args_with_leading_dashes() {
String::from("--count=2"),
String::from("--skip=2"),
String::from("--seek=2"),
String::from("--iseek=2"),
String::from("--oseek=2"),
String::from("--status=progress"),
String::from("--conv=ascii,ucase"),
String::from("--iflag=count_bytes,skip_bytes"),
@ -225,13 +241,25 @@ fn test_all_top_level_args_with_leading_dashes() {
);
assert_eq!(
200,
parse_skip_amt(&100, &IFlags::default(), &matches)
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::SKIP)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_amt(&100, &OFlags::default(), &matches)
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::SEEK)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::ISEEK)
.unwrap()
.unwrap()
);
assert_eq!(
200,
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::OSEEK)
.unwrap()
.unwrap()
);
@ -303,10 +331,10 @@ fn test_status_level_noxfer() {
fn test_multiple_flags_options() {
let args = vec![
String::from("dd"),
String::from("--iflag=fullblock,directory"),
String::from("--iflag=fullblock,count_bytes"),
String::from("--iflag=skip_bytes"),
String::from("--oflag=direct"),
String::from("--oflag=dsync"),
String::from("--oflag=append"),
String::from("--oflag=seek_bytes"),
String::from("--conv=ascii,ucase"),
String::from("--conv=unblock"),
];
@ -315,13 +343,13 @@ fn test_multiple_flags_options() {
// iflag
let iflags = parse_flag_list::<Flag>(options::IFLAG, &matches).unwrap();
assert_eq!(
vec![Flag::FullBlock, Flag::Directory, Flag::SkipBytes],
vec![Flag::FullBlock, Flag::CountBytes, Flag::SkipBytes],
iflags
);
// oflag
let oflags = parse_flag_list::<Flag>(options::OFLAG, &matches).unwrap();
assert_eq!(vec![Flag::Direct, Flag::Dsync], oflags);
assert_eq!(vec![Flag::Append, Flag::SeekBytes], oflags);
// conv
let conv = parse_flag_list::<ConvFlag>(options::CONV, &matches).unwrap();
@ -349,6 +377,10 @@ fn test_override_multiple_options() {
String::from("--skip=2"),
String::from("--seek=0"),
String::from("--seek=2"),
String::from("--iseek=0"),
String::from("--iseek=2"),
String::from("--oseek=0"),
String::from("--oseek=2"),
String::from("--status=none"),
String::from("--status=noxfer"),
String::from("--count=512"),
@ -381,7 +413,7 @@ fn test_override_multiple_options() {
// skip
assert_eq!(
200,
parse_skip_amt(&100, &IFlags::default(), &matches)
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::SKIP)
.unwrap()
.unwrap()
);
@ -389,7 +421,23 @@ fn test_override_multiple_options() {
// seek
assert_eq!(
200,
parse_seek_amt(&100, &OFlags::default(), &matches)
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::SEEK)
.unwrap()
.unwrap()
);
// iseek
assert_eq!(
200,
parse_seek_skip_amt(&100, IFlags::default().skip_bytes, &matches, options::ISEEK)
.unwrap()
.unwrap()
);
// oseek
assert_eq!(
200,
parse_seek_skip_amt(&100, OFlags::default().seek_bytes, &matches, options::OSEEK)
.unwrap()
.unwrap()
);
@ -685,7 +733,7 @@ mod test_64bit_arch {
#[test]
#[should_panic]
fn test_overflow_panic() {
let bs_str = format!("{}KiB", usize::MAX);
let bs_str = format!("{}KiB", u64::MAX);
parse_bytes_with_opt_multiplier(&bs_str).unwrap();
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/df.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
number_prefix = "0.4"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["libc", "fsext"] }

View file

@ -15,7 +15,7 @@ use uucore::error::{UResult, USimpleError};
use uucore::format_usage;
use uucore::fsext::{read_fs_list, MountInfo};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use std::fmt;
use std::path::Path;
@ -29,9 +29,9 @@ static ABOUT: &str = "Show information about the file system on which each FILE
or all file systems by default.";
const USAGE: &str = "{} [OPTION]... [FILE]...";
static OPT_HELP: &str = "help";
static OPT_ALL: &str = "all";
static OPT_BLOCKSIZE: &str = "blocksize";
static OPT_DIRECT: &str = "direct";
static OPT_TOTAL: &str = "total";
static OPT_HUMAN_READABLE: &str = "human-readable";
static OPT_HUMAN_READABLE_2: &str = "human-readable-2";
@ -230,39 +230,49 @@ fn filter_mount_list(vmi: Vec<MountInfo>, opt: &Options) -> Vec<MountInfo> {
result
}
/// Assign 1 `MountInfo` entry to each path
/// `lofs` entries are skipped and dummy mount points are skipped
/// Only the longest matching prefix for that path is considered
/// `lofs` is for Solaris style loopback filesystem and is present in Solaris and FreeBSD.
/// It works similar to symlinks
fn get_point_list(vmi: &[MountInfo], paths: &[String]) -> Vec<MountInfo> {
/// Get all currently mounted filesystems.
///
/// `opt` excludes certain filesystems from consideration; see
/// [`Options`] for more information.
fn get_all_filesystems(opt: &Options) -> Vec<Filesystem> {
// The list of all mounted filesystems.
//
// Filesystems excluded by the command-line options are
// not considered.
let mounts: Vec<MountInfo> = filter_mount_list(read_fs_list(), opt);
// Convert each `MountInfo` into a `Filesystem`, which contains
// both the mount information and usage information.
mounts.into_iter().filter_map(Filesystem::new).collect()
}
/// For each path, get the filesystem that contains that path.
fn get_named_filesystems<P>(paths: &[P]) -> Vec<Filesystem>
where
P: AsRef<Path>,
{
// The list of all mounted filesystems.
//
// Filesystems marked as `dummy` or of type "lofs" are not
// considered. The "lofs" filesystem is a loopback
// filesystem present on Solaris and FreeBSD systems. It
// is similar to a symbolic link.
let mounts: Vec<MountInfo> = read_fs_list()
.into_iter()
.filter(|mi| mi.fs_type != "lofs" && !mi.dummy)
.collect();
// Convert each path into a `Filesystem`, which contains
// both the mount information and usage information.
paths
.iter()
.map(|p| {
vmi.iter()
.filter(|mi| mi.fs_type.ne("lofs"))
.filter(|mi| !mi.dummy)
.filter(|mi| p.starts_with(&mi.mount_dir))
.max_by_key(|mi| mi.mount_dir.len())
.unwrap()
.clone()
})
.collect::<Vec<MountInfo>>()
.filter_map(|p| Filesystem::from_path(&mounts, p))
.collect()
}
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let matches = uu_app().get_matches_from(args);
// Canonicalize the input_paths and then convert to string
let paths = matches
.values_of(OPT_PATHS)
.unwrap_or_default()
.map(Path::new)
.filter_map(|v| v.canonicalize().ok())
.filter_map(|v| v.into_os_string().into_string().ok())
.collect::<Vec<_>>();
#[cfg(windows)]
{
if matches.is_present(OPT_INODES) {
@ -273,27 +283,31 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let opt = Options::from(&matches).map_err(|e| USimpleError::new(1, format!("{}", e)))?;
let mounts = read_fs_list();
let op_mount_points: Vec<MountInfo> = if paths.is_empty() {
// Get all entries
filter_mount_list(mounts, &opt)
} else {
// Get Point for each input_path
get_point_list(&mounts, &paths)
// Get the list of filesystems to display in the output table.
let filesystems: Vec<Filesystem> = match matches.values_of(OPT_PATHS) {
None => get_all_filesystems(&opt),
Some(paths) => {
let paths: Vec<&str> = paths.collect();
get_named_filesystems(&paths)
}
};
let data: Vec<Row> = op_mount_points
.into_iter()
.filter_map(Filesystem::new)
.filter(|fs| fs.usage.blocks != 0 || opt.show_all_fs || opt.show_listed_fs)
.map(Into::into)
.collect();
// The running total of filesystem sizes and usage.
//
// This accumulator is computed in case we need to display the
// total counts in the last row of the table.
let mut total = Row::new("total");
println!("{}", Header::new(&opt));
let mut total = Row::new("total");
for row in data {
println!("{}", DisplayRow::new(&row, &opt));
total += row;
for filesystem in filesystems {
// If the filesystem is not empty, or if the options require
// showing all filesystems, then print the data as a row in
// the output table.
if opt.show_all_fs || opt.show_listed_fs || filesystem.usage.blocks > 0 {
let row = Row::from(filesystem);
println!("{}", DisplayRow::new(&row, &opt));
total += row;
}
}
if opt.show_total {
println!("{}", DisplayRow::new(&total, &opt));
@ -302,12 +316,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(OPT_HELP)
.long(OPT_HELP)
.help("Print help information."),
)
.arg(
Arg::new(OPT_ALL)
.short('a')
@ -324,11 +343,6 @@ pub fn uu_app<'a>() -> App<'a> {
'-BM' prints sizes in units of 1,048,576 bytes",
),
)
.arg(
Arg::new(OPT_DIRECT)
.long("direct")
.help("show statistics for a file instead of mount point"),
)
.arg(
Arg::new(OPT_TOTAL)
.long("total")
@ -371,7 +385,7 @@ pub fn uu_app<'a>() -> App<'a> {
Arg::new(OPT_OUTPUT)
.long("output")
.takes_value(true)
.use_delimiter(true)
.use_value_delimiter(true)
.possible_values(OUTPUT_FIELD_LIST)
.default_missing_values(&OUTPUT_FIELD_LIST)
.default_values(&["source", "size", "used", "avail", "pcent", "target"])
@ -412,8 +426,10 @@ pub fn uu_app<'a>() -> App<'a> {
Arg::new(OPT_EXCLUDE_TYPE)
.short('x')
.long("exclude-type")
.allow_invalid_utf8(true)
.takes_value(true)
.use_delimiter(true)
.use_value_delimiter(true)
.multiple_occurrences(true)
.help("limit listing to file systems not of type TYPE"),
)
.arg(Arg::new(OPT_PATHS).multiple_occurrences(true))

View file

@ -7,7 +7,7 @@
//! A [`Filesystem`] struct represents a device containing a
//! filesystem mounted at a particular directory. It also includes
//! information on amount of space available and amount of space used.
#[cfg(windows)]
// spell-checker:ignore canonicalized
use std::path::Path;
#[cfg(unix)]
@ -30,6 +30,40 @@ pub(crate) struct Filesystem {
pub usage: FsUsage,
}
/// Find the mount info that best matches a given filesystem path.
///
/// This function returns the element of `mounts` on which `path` is
/// mounted. If there are no matches, this function returns
/// [`None`]. If there are two or more matches, then the single
/// [`MountInfo`] with the longest mount directory is returned.
///
/// If `canonicalize` is `true`, then the `path` is canonicalized
/// before checking whether it matches any mount directories.
///
/// # See also
///
/// * [`Path::canonicalize`]
/// * [`MountInfo::mount_dir`]
fn mount_info_from_path<P>(
mounts: &[MountInfo],
path: P,
// This is really only used for testing purposes.
canonicalize: bool,
) -> Option<&MountInfo>
where
P: AsRef<Path>,
{
// TODO Refactor this function with `Stater::find_mount_point()`
// in the `stat` crate.
let path = if canonicalize {
path.as_ref().canonicalize().ok()?
} else {
path.as_ref().to_path_buf()
};
let matches = mounts.iter().filter(|mi| path.starts_with(&mi.mount_dir));
matches.max_by_key(|mi| mi.mount_dir.len())
}
impl Filesystem {
// TODO: resolve uuid in `mount_info.dev_name` if exists
pub(crate) fn new(mount_info: MountInfo) -> Option<Self> {
@ -52,4 +86,106 @@ impl Filesystem {
let usage = FsUsage::new(Path::new(&_stat_path));
Some(Self { mount_info, usage })
}
/// Find and create the filesystem that best matches a given path.
///
/// This function returns a new `Filesystem` derived from the
/// element of `mounts` on which `path` is mounted. If there are
/// no matches, this function returns [`None`]. If there are two
/// or more matches, then the single [`Filesystem`] with the
/// longest mount directory is returned.
///
/// The `path` is canonicalized before checking whether it matches
/// any mount directories.
///
/// # See also
///
/// * [`Path::canonicalize`]
/// * [`MountInfo::mount_dir`]
///
pub(crate) fn from_path<P>(mounts: &[MountInfo], path: P) -> Option<Self>
where
P: AsRef<Path>,
{
let canonicalize = true;
let mount_info = mount_info_from_path(mounts, path, canonicalize)?;
// TODO Make it so that we do not need to clone the `mount_info`.
let mount_info = (*mount_info).clone();
Self::new(mount_info)
}
}
#[cfg(test)]
mod tests {
mod mount_info_from_path {
use uucore::fsext::MountInfo;
use crate::filesystem::mount_info_from_path;
// Create a fake `MountInfo` with the given directory name.
fn mount_info(mount_dir: &str) -> MountInfo {
MountInfo {
dev_id: Default::default(),
dev_name: Default::default(),
fs_type: Default::default(),
mount_dir: String::from(mount_dir),
mount_option: Default::default(),
mount_root: Default::default(),
remote: Default::default(),
dummy: Default::default(),
}
}
// Check whether two `MountInfo` instances are equal.
fn mount_info_eq(m1: &MountInfo, m2: &MountInfo) -> bool {
m1.dev_id == m2.dev_id
&& m1.dev_name == m2.dev_name
&& m1.fs_type == m2.fs_type
&& m1.mount_dir == m2.mount_dir
&& m1.mount_option == m2.mount_option
&& m1.mount_root == m2.mount_root
&& m1.remote == m2.remote
&& m1.dummy == m2.dummy
}
#[test]
fn test_empty_mounts() {
assert!(mount_info_from_path(&[], "/", false).is_none());
}
#[test]
fn test_exact_match() {
let mounts = [mount_info("/foo")];
let actual = mount_info_from_path(&mounts, "/foo", false).unwrap();
assert!(mount_info_eq(actual, &mounts[0]));
}
#[test]
fn test_prefix_match() {
let mounts = [mount_info("/foo")];
let actual = mount_info_from_path(&mounts, "/foo/bar", false).unwrap();
assert!(mount_info_eq(actual, &mounts[0]));
}
#[test]
fn test_multiple_matches() {
let mounts = [mount_info("/foo"), mount_info("/foo/bar")];
let actual = mount_info_from_path(&mounts, "/foo/bar", false).unwrap();
assert!(mount_info_eq(actual, &mounts[1]));
}
#[test]
fn test_no_match() {
let mounts = [mount_info("/foo")];
assert!(mount_info_from_path(&mounts, "/bar", false).is_none());
}
#[test]
fn test_partial_match() {
let mounts = [mount_info("/foo/bar")];
assert!(mount_info_from_path(&mounts, "/foo/baz", false).is_none());
}
}
}

View file

@ -39,8 +39,8 @@ pub(crate) struct Row {
/// Number of used bytes.
bytes_used: u64,
/// Number of free bytes.
bytes_free: u64,
/// Number of available bytes.
bytes_avail: u64,
/// Percentage of bytes that are used, given as a float between 0 and 1.
///
@ -78,7 +78,7 @@ impl Row {
fs_mount: "-".into(),
bytes: 0,
bytes_used: 0,
bytes_free: 0,
bytes_avail: 0,
bytes_usage: None,
#[cfg(target_os = "macos")]
bytes_capacity: None,
@ -106,7 +106,7 @@ impl AddAssign for Row {
fs_mount: "-".into(),
bytes,
bytes_used,
bytes_free: self.bytes_free + rhs.bytes_free,
bytes_avail: self.bytes_avail + rhs.bytes_avail,
bytes_usage: if bytes == 0 {
None
} else {
@ -139,7 +139,6 @@ impl From<Filesystem> for Row {
blocksize,
blocks,
bfree,
#[cfg(target_os = "macos")]
bavail,
files,
ffree,
@ -151,7 +150,7 @@ impl From<Filesystem> for Row {
fs_mount: mount_dir,
bytes: blocksize * blocks,
bytes_used: blocksize * (blocks - bfree),
bytes_free: blocksize * bfree,
bytes_avail: blocksize * bavail,
bytes_usage: if blocks == 0 {
None
} else {
@ -236,7 +235,7 @@ impl fmt::Display for DisplayRow<'_> {
Column::Source => write!(f, "{0: <16} ", self.row.fs_device)?,
Column::Size => write!(f, "{0: >12} ", self.scaled(self.row.bytes)?)?,
Column::Used => write!(f, "{0: >12} ", self.scaled(self.row.bytes_used)?)?,
Column::Avail => write!(f, "{0: >12} ", self.scaled(self.row.bytes_free)?)?,
Column::Avail => write!(f, "{0: >12} ", self.scaled(self.row.bytes_avail)?)?,
Column::Pcent => {
write!(f, "{0: >5} ", DisplayRow::percentage(self.row.bytes_usage))?;
}
@ -413,7 +412,7 @@ mod tests {
bytes: 100,
bytes_used: 25,
bytes_free: 75,
bytes_avail: 75,
bytes_usage: Some(0.25),
#[cfg(target_os = "macos")]
@ -444,7 +443,7 @@ mod tests {
bytes: 100,
bytes_used: 25,
bytes_free: 75,
bytes_avail: 75,
bytes_usage: Some(0.25),
#[cfg(target_os = "macos")]
@ -475,7 +474,7 @@ mod tests {
bytes: 100,
bytes_used: 25,
bytes_free: 75,
bytes_avail: 75,
bytes_usage: Some(0.25),
#[cfg(target_os = "macos")]
@ -506,7 +505,7 @@ mod tests {
bytes: 4000,
bytes_used: 1000,
bytes_free: 3000,
bytes_avail: 3000,
bytes_usage: Some(0.25),
#[cfg(target_os = "macos")]
@ -537,7 +536,7 @@ mod tests {
bytes: 4096,
bytes_used: 1024,
bytes_free: 3072,
bytes_avail: 3072,
bytes_usage: Some(0.25),
#[cfg(target_os = "macos")]
@ -567,7 +566,7 @@ mod tests {
bytes: 100,
bytes_used: 25,
bytes_free: 75,
bytes_avail: 75,
bytes_usage: Some(0.251),
#[cfg(target_os = "macos")]

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/dircolors.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
glob = "0.3.0"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -13,7 +13,7 @@ use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError};
@ -154,13 +154,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.after_help(LONG_HELP)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::BOURNE_SHELL)
.long("sh")

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/dirname.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -5,7 +5,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::path::Path;
use uucore::display::print_verbatim;
use uucore::error::{UResult, UUsageError};
@ -76,12 +76,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.about(ABOUT)
.version(crate_version!())
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::ZERO)
.long(options::ZERO)

View file

@ -16,7 +16,7 @@ path = "src/du.rs"
[dependencies]
chrono = "^0.4.11"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[target.'cfg(target_os = "windows")'.dependencies]

View file

@ -10,7 +10,7 @@ extern crate uucore;
use chrono::prelude::DateTime;
use chrono::Local;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use std::collections::HashSet;
use std::env;
use std::fs;
@ -47,6 +47,7 @@ use winapi::um::winbase::GetFileInformationByHandleEx;
use winapi::um::winnt::{FILE_ID_128, ULONGLONG};
mod options {
pub const HELP: &str = "help";
pub const NULL: &str = "0";
pub const ALL: &str = "all";
pub const APPARENT_SIZE: &str = "apparent-size";
@ -617,13 +618,18 @@ fn parse_depth(max_depth_str: Option<&str>, summarize: bool) -> UResult<Option<u
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.after_help(LONG_HELP)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::HELP)
.long(options::HELP)
.help("Print help information.")
)
.arg(
Arg::new(options::ALL)
.short('a')

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/echo.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -6,7 +6,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::io::{self, Write};
use std::iter::Peekable;
use std::str::Chars;
@ -126,15 +126,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.map_err_context(|| "could not write to stdout".to_string())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
// TrailingVarArg specifies the final positional argument is a VarArg
// and it doesn't attempts the parse any further args.
// Final argument must have multiple(true) or the usage string equivalent.
.setting(AppSettings::TrailingVarArg)
.setting(AppSettings::AllowHyphenValues)
.setting(AppSettings::InferLongArgs)
.trailing_var_arg(true)
.allow_hyphen_values(true)
.infer_long_args(true)
.version(crate_version!())
.about(SUMMARY)
.after_help(AFTER_HELP)

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/env.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
rust-ini = "0.17.0"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

14
src/uu/env/src/env.rs vendored
View file

@ -16,13 +16,13 @@ extern crate clap;
#[macro_use]
extern crate uucore;
use clap::{App, AppSettings, Arg};
use clap::{Arg, Command};
use ini::Ini;
use std::borrow::Cow;
use std::env;
use std::io::{self, Write};
use std::iter::Iterator;
use std::process::Command;
use std::process;
use uucore::display::Quotable;
use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::format_usage;
@ -121,15 +121,15 @@ fn build_command<'a, 'b>(args: &'a mut Vec<&'b str>) -> (Cow<'b, str>, &'a [&'b
(progname, &args[..])
}
pub fn uu_app<'a>() -> App<'a> {
App::new(crate_name!())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(crate_name!())
.version(crate_version!())
.author(crate_authors!())
.about(crate_description!())
.override_usage(format_usage(USAGE))
.after_help(AFTER_HELP)
.setting(AppSettings::AllowExternalSubcommands)
.setting(AppSettings::InferLongArgs)
.allow_external_subcommands(true)
.infer_long_args(true)
.arg(Arg::new("ignore-environment")
.short('i')
.long("ignore-environment")
@ -307,7 +307,7 @@ fn run_env(args: impl uucore::Args) -> UResult<()> {
* standard library contains many checks and fail-safes to ensure the process ends up being
* created. This is much simpler than dealing with the hassles of calling execvp directly.
*/
match Command::new(&*prog).args(args).status() {
match process::Command::new(&*prog).args(args).status() {
Ok(exit) if !exit.success() => return Err(exit.code().unwrap().into()),
Err(ref err) if err.kind() == io::ErrorKind::NotFound => return Err(127.into()),
Err(_) => return Err(126.into()),

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/expand.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
unicode-width = "0.1.5"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -12,7 +12,7 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use std::fs::File;
use std::io::{stdin, stdout, BufRead, BufReader, BufWriter, Read, Write};
use std::str::from_utf8;
@ -176,13 +176,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
expand(&Options::new(&matches)).map_err_context(|| "failed to write output".to_string())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.after_help(LONG_HELP)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::INITIAL)
.long(options::INITIAL)

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/expr.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
num-bigint = "0.4.0"
num-traits = "0.2.14"
onig = { version = "~6.3", default-features = false }

View file

@ -5,7 +5,7 @@
//* For the full copyright and license information, please view the LICENSE
//* file that was distributed with this source code.
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use uucore::error::{UResult, USimpleError};
use uucore::InvalidEncodingHandling;
@ -19,12 +19,12 @@ static USAGE: &str = r#"
expr [EXPRESSION]
expr [OPTIONS]"#;
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(USAGE)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(VERSION)
.long(VERSION)

View file

@ -65,7 +65,7 @@ impl Token {
}
}
fn is_a_close_paren(&self) -> bool {
matches!(*self, Token::ParClose)
matches!(*self, Self::ParClose)
}
}

View file

@ -15,7 +15,7 @@ edition = "2018"
num-traits = "0.2.13" # used in src/numerics.rs, which is included by build.rs
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
coz = { version = "0.1.3", optional = true }
num-traits = "0.2.13" # Needs at least version 0.2.13 for "OverflowingAdd"
rand = { version = "0.8", features = ["small_rng"] }
@ -23,7 +23,7 @@ smallvec = "1.7" # TODO(nicoo): Use `union` feature, requires Rust 1.49 or late
uucore = { version = ">=0.0.8", package = "uucore", path = "../../uucore" }
[dev-dependencies]
paste = "0.1.18"
paste = "1.0.6"
quickcheck = "1.0.3"
[[bin]]

View file

@ -14,7 +14,7 @@ use std::fmt::Write as FmtWrite;
use std::io::{self, stdin, stdout, BufRead, Write};
mod factor;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
pub use factor::*;
use uucore::display::Quotable;
use uucore::error::UResult;
@ -77,10 +77,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(Arg::new(options::NUMBER).multiple_occurrences(true))
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/false.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -4,7 +4,7 @@
// *
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
use clap::{App, AppSettings, Arg};
use clap::{Arg, Command};
use std::io::Write;
use uucore::error::{set_exit_code, UResult};
@ -18,7 +18,7 @@ the program will also return `1`.
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let mut app = uu_app();
let mut command = uu_app();
// Mirror GNU options, always return `1`. In particular even the 'successful' cases of no-op,
// and the interrupted display of help and version should return `1`. Also, we return Ok in all
@ -26,11 +26,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// and unwind through the standard library allocation handling machinery.
set_exit_code(1);
if let Ok(matches) = app.try_get_matches_from_mut(args) {
if let Ok(matches) = command.try_get_matches_from_mut(args) {
let error = if matches.index_of("help").is_some() {
app.print_long_help()
command.print_long_help()
} else if matches.index_of("version").is_some() {
writeln!(std::io::stdout(), "{}", app.render_version())
writeln!(std::io::stdout(), "{}", command.render_version())
} else {
Ok(())
};
@ -45,12 +45,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(clap::crate_version!())
.about(ABOUT)
// We provide our own help and version options, to ensure maximum compatibility with GNU.
.setting(AppSettings::DisableHelpFlag | AppSettings::DisableVersionFlag)
.disable_help_flag(true)
.disable_version_flag(true)
.arg(
Arg::new("help")
.long("help")

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/fmt.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
unicode-width = "0.1.5"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }

View file

@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::cmp;
use std::fs::File;
use std::io::{stdin, stdout, Write};
@ -218,12 +218,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(OPT_CROWN_MARGIN)
.short('c')

View file

@ -412,7 +412,7 @@ fn compute_demerits(delta_len: isize, stretch: isize, wlen: isize, prev_rat: f32
let bad_linelen = if ratio.abs() > 1.0f32 {
BAD_INFTY
} else {
(BAD_MULT * ratio.powf(3f32).abs()) as i64
(BAD_MULT * ratio.powi(3).abs()) as i64
};
// we penalize lines ending in really short words
@ -421,12 +421,12 @@ fn compute_demerits(delta_len: isize, stretch: isize, wlen: isize, prev_rat: f32
} else {
(DL_MULT
* ((stretch - wlen) as f32 / (stretch - 1) as f32)
.powf(3f32)
.powi(3)
.abs()) as i64
};
// we penalize lines that have very different ratios from previous lines
let bad_delta_r = (DR_MULT * (((ratio - prev_rat) / 2.0).powf(3f32)).abs()) as i64;
let bad_delta_r = (DR_MULT * (((ratio - prev_rat) / 2.0).powi(3)).abs()) as i64;
let demerits = i64::pow(1 + bad_linelen + bad_wordlen + bad_delta_r, 2);

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/fold.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -7,7 +7,7 @@
// spell-checker:ignore (ToDOs) ncount routput
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs::File;
use std::io::{stdin, BufRead, BufReader, Read};
use std::path::Path;
@ -63,13 +63,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
fold(&files, bytes, spaces, width)
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.override_usage(format_usage(USAGE))
.about(SUMMARY)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::BYTES)
.long(options::BYTES)

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/groups.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "process"] }
[[bin]]

View file

@ -26,7 +26,7 @@ use uucore::{
format_usage,
};
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
mod options {
pub const USERS: &str = "USERNAME";
@ -50,9 +50,9 @@ impl UError for GroupsError {}
impl Display for GroupsError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
GroupsError::GetGroupsFailed => write!(f, "failed to fetch groups"),
GroupsError::GroupNotFound(gid) => write!(f, "cannot find name for group ID {}", gid),
GroupsError::UserNotFound(user) => write!(f, "{}: no such user", user.quote()),
Self::GetGroupsFailed => write!(f, "failed to fetch groups"),
Self::GroupNotFound(gid) => write!(f, "cannot find name for group ID {}", gid),
Self::UserNotFound(user) => write!(f, "{}: no such user", user.quote()),
}
}
}
@ -102,12 +102,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::USERS)
.multiple_occurrences(true)

View file

@ -16,13 +16,11 @@ path = "src/hashsum.rs"
[dependencies]
digest = "0.10.1"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
hex = "0.4.3"
libc = "0.2.42"
memchr = "2"
md-5 = "0.10.1"
regex = "1.0.1"
regex-syntax = "0.6.7"
sha1 = "0.10.1"
sha2 = "0.10.2"
sha3 = "0.10.1"

View file

@ -274,7 +274,7 @@ mod tests {
use crate::digest::DigestWriter;
// Writing "\r" in one call to `write()`, and then "\n" in another.
let mut digest = Box::new(md5::Context::new()) as Box<dyn Digest>;
let mut digest = Box::new(md5::Md5::new()) as Box<dyn Digest>;
let mut writer_crlf = DigestWriter::new(&mut digest, false);
writer_crlf.write_all(&[b'\r']).unwrap();
writer_crlf.write_all(&[b'\n']).unwrap();
@ -282,7 +282,7 @@ mod tests {
let result_crlf = digest.result_str();
// We expect "\r\n" to be replaced with "\n" in text mode on Windows.
let mut digest = Box::new(md5::Context::new()) as Box<dyn Digest>;
let mut digest = Box::new(md5::Md5::new()) as Box<dyn Digest>;
let mut writer_lf = DigestWriter::new(&mut digest, false);
writer_lf.write_all(&[b'\n']).unwrap();
writer_lf.finalize();

View file

@ -20,7 +20,7 @@ mod digest;
use self::digest::Digest;
use self::digest::DigestWriter;
use clap::{App, AppSettings, Arg, ArgMatches};
use clap::{Arg, ArgMatches, Command};
use hex::encode;
use md5::Md5;
use regex::Regex;
@ -297,13 +297,13 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
// Default binary in Windows, text mode otherwise
let binary_flag_default = cfg!(windows);
let app = uu_app(&binary_name);
let command = uu_app(&binary_name);
// FIXME: this should use try_get_matches_from() and crash!(), but at the moment that just
// causes "error: " to be printed twice (once from crash!() and once from clap). With
// the current setup, the name of the utility is not printed, but I think this is at
// least somewhat better from a user's perspective.
let matches = app.get_matches_from(args);
let matches = command.get_matches_from(args);
let (name, algo, bits) = detect_algo(&binary_name, &matches);
@ -340,7 +340,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app_common<'a>() -> App<'a> {
pub fn uu_app_common<'a>() -> Command<'a> {
#[cfg(windows)]
const BINARY_HELP: &str = "read in binary mode (default)";
#[cfg(not(windows))]
@ -349,10 +349,10 @@ pub fn uu_app_common<'a>() -> App<'a> {
const TEXT_HELP: &str = "read in text mode";
#[cfg(not(windows))]
const TEXT_HELP: &str = "read in text mode (default)";
App::new(uucore::util_name())
Command::new(uucore::util_name())
.version(crate_version!())
.about("Compute and check message digests.")
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new("binary")
.short('b')
@ -419,8 +419,8 @@ pub fn uu_app_common<'a>() -> App<'a> {
)
}
pub fn uu_app_custom<'a>() -> App<'a> {
let mut app = uu_app_common();
pub fn uu_app_custom<'a>() -> Command<'a> {
let mut command = uu_app_common();
let algorithms = &[
("md5", "work with MD5"),
("sha1", "work with SHA1"),
@ -446,14 +446,14 @@ pub fn uu_app_custom<'a>() -> App<'a> {
];
for (name, desc) in algorithms {
app = app.arg(Arg::new(*name).long(name).help(*desc));
command = command.arg(Arg::new(*name).long(name).help(*desc));
}
app
command
}
// hashsum is handled differently in build.rs, therefore this is not the same
// as in other utilities.
fn uu_app<'a>(binary_name: &str) -> App<'a> {
fn uu_app<'a>(binary_name: &str) -> Command<'a> {
if !is_custom_binary(binary_name) {
uu_app_custom()
} else {
@ -473,8 +473,8 @@ impl UError for HashsumError {}
impl std::fmt::Display for HashsumError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
HashsumError::InvalidRegex => write!(f, "invalid regular expression"),
HashsumError::InvalidFormat => Ok(()),
Self::InvalidRegex => write!(f, "invalid regular expression"),
Self::InvalidFormat => Ok(()),
}
}
}

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/head.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
memchr = "2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }

View file

@ -5,7 +5,7 @@
// spell-checker:ignore (vars) zlines BUFWRITER seekable
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use std::convert::{TryFrom, TryInto};
use std::ffi::OsString;
use std::io::{self, BufWriter, ErrorKind, Read, Seek, SeekFrom, Write};
@ -41,12 +41,12 @@ mod take;
use take::take_all_but;
use take::take_lines;
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::BYTES_NAME)
.short('c')

View file

@ -15,8 +15,8 @@ edition = "2018"
path = "src/hostid.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.121"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -7,7 +7,7 @@
// spell-checker:ignore (ToDO) gethostid
use clap::{crate_version, App, AppSettings};
use clap::{crate_version, Command};
use libc::c_long;
use uucore::{error::UResult, format_usage};
@ -26,12 +26,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
}
fn hostid() {

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/hostname.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
hostname = { version = "0.3", features = ["set"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["wide"] }
winapi = { version="0.3", features=["sysinfoapi", "winsock2"] }

View file

@ -11,7 +11,7 @@ use std::collections::hash_set::HashSet;
use std::net::ToSocketAddrs;
use std::str;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use uucore::{
error::{FromIo, UResult},
@ -71,12 +71,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(OPT_DOMAIN)
.short('d')

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/id.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["entries", "process"] }
selinux = { version="0.2", optional = true }

View file

@ -39,7 +39,7 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::ffi::CStr;
use uucore::display::Quotable;
use uucore::entries::{self, Group, Locate, Passwd};
@ -341,12 +341,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Ok(())
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::OPT_AUDIT)
.short('A')

View file

@ -18,15 +18,12 @@ edition = "2018"
path = "src/install.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
filetime = "0.2"
file_diff = "1.0.0"
libc = ">= 0.2"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs", "mode", "perms", "entries"] }
[dev-dependencies]
time = "0.1.40"
[[bin]]
name = "install"
path = "src/main.rs"

View file

@ -12,7 +12,7 @@ mod mode;
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use clap::{crate_version, Arg, ArgMatches, Command};
use file_diff::diff;
use filetime::{set_file_times, FileTime};
use uucore::backup_control::{self, BackupMode};
@ -30,7 +30,7 @@ use std::fs;
use std::fs::File;
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::process;
const DEFAULT_MODE: u32 = 0o755;
const DEFAULT_STRIP_PROGRAM: &str = "strip";
@ -188,12 +188,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
backup_control::arguments::backup()
)
@ -585,7 +585,7 @@ fn copy(from: &Path, to: &Path, b: &Behavior) -> UResult<()> {
}
if b.strip && cfg!(not(windows)) {
match Command::new(&b.strip_program).arg(to).output() {
match process::Command::new(&b.strip_program).arg(to).output() {
Ok(o) => {
if !o.status.success() {
return Err(InstallError::StripProgramFailed(

View file

@ -15,7 +15,7 @@ edition = "2018"
path = "src/join.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
memchr = "2"

View file

@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use memchr::{memchr3_iter, memchr_iter};
use std::cmp::Ordering;
use std::convert::From;
@ -697,8 +697,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(NAME)
pub fn uu_app<'a>() -> Command<'a> {
Command::new(NAME)
.version(crate_version!())
.about(
"For each pair of input lines with identical join fields, write a line to
@ -706,7 +706,7 @@ standard output. The default join field is the first, delimited by blanks.
When FILE1 or FILE2 (not both) is -, read standard input.",
)
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new("a")
.short('a')

View file

@ -15,8 +15,8 @@ edition = "2018"
path = "src/kill.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
libc = "0.2.121"
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["signals"] }
[[bin]]

View file

@ -10,7 +10,7 @@
#[macro_use]
extern crate uucore;
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use libc::{c_int, pid_t};
use std::io::Error;
use uucore::display::Quotable;
@ -78,12 +78,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::LIST)
.short('l')

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/link.rs"
[dependencies]
libc = "0.2.42"
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore" }
[[bin]]

View file

@ -4,7 +4,7 @@
// *
// * For the full copyright and license information, please view the LICENSE
// * file that was distributed with this source code.
use clap::{crate_version, App, AppSettings, Arg};
use clap::{crate_version, Arg, Command};
use std::fs::hard_link;
use std::path::Path;
use uucore::display::Quotable;
@ -33,12 +33,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
.map_err_context(|| format!("cannot create link {} to {}", new.quote(), old.quote()))
}
pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
pub fn uu_app<'a>() -> Command<'a> {
Command::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.infer_long_args(true)
.arg(
Arg::new(options::FILES)
.hide(true)

View file

@ -15,8 +15,7 @@ edition = "2018"
path = "src/ln.rs"
[dependencies]
clap = { version = "3.0", features = ["wrap_help", "cargo"] }
libc = "0.2.42"
clap = { version = "3.1", features = ["wrap_help", "cargo"] }
uucore = { version=">=0.0.11", package="uucore", path="../../uucore", features=["fs"] }
[[bin]]

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