Merge branch 'main' into cp-lb

This commit is contained in:
Sylvestre Ledru
2022-03-03 23:02:57 +01:00
committed by GitHub
130 changed files with 2194 additions and 1531 deletions
+14 -1
View File
@@ -5,7 +5,7 @@ name: CICD
# spell-checker:ignore (jargon) SHAs deps dequote softprops subshell toolchain
# spell-checker:ignore (names) CodeCOV MacOS MinGW Peltoche rivy
# spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot gmake grcov halium lcov libssl mkdir popd printf pushd rsync rustc rustfmt rustup shopt xargs
# spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend pell runtest tempfile testsuite uutils DESTDIR sizemulti
# spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils gnueabihf issuecomment maint nullglob onexitbegin onexitend pell runtest tempfile testsuite uutils DESTDIR sizemulti Swatinem
# ToDO: [2021-06; rivy] change from `cargo-tree` to `cargo tree` once MSRV is >= 1.45
@@ -37,6 +37,7 @@ jobs:
- { os: windows-latest , features: feat_os_windows }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -94,6 +95,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -157,6 +159,7 @@ jobs:
- { os: windows-latest , features: feat_os_windows }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -214,6 +217,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -265,6 +269,7 @@ jobs:
# - { os: windows-latest , features: feat_os_windows }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -309,6 +314,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -385,6 +391,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Install `rust` toolchain
uses: actions-rs/toolchain@v1
with:
@@ -409,6 +416,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Install `rust` toolchain
uses: actions-rs/toolchain@v1
with:
@@ -436,6 +444,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Install dependencies
shell: bash
run: |
@@ -497,6 +506,7 @@ jobs:
- { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize workflow variables
id: vars
shell: bash
@@ -745,6 +755,7 @@ jobs:
- { os: ubuntu-latest }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Install/setup prerequisites
shell: bash
run: |
@@ -780,6 +791,7 @@ jobs:
mem: 2048
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Prepare, build and test
## spell-checker:ignore (ToDO) sshfs usesh vmactions
uses: vmactions/freebsd-vm@v0.1.5
@@ -848,6 +860,7 @@ jobs:
- { os: windows-latest , features: windows }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
# - name: Reattach HEAD ## may be needed for accurate code coverage info
# run: git checkout ${{ github.head_ref }}
- name: Initialize workflow variables
+4
View File
@@ -1,5 +1,7 @@
name: FixPR
# spell-checker:ignore Swatinem
# Trigger automated fixes for PRs being merged (with associated commits)
# ToDO: [2021-06; rivy] change from `cargo-tree` to `cargo tree` once MSRV is >= 1.45
@@ -27,6 +29,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize job variables
id: vars
shell: bash
@@ -98,6 +101,7 @@ jobs:
- { os: ubuntu-latest , features: feat_os_unix }
steps:
- uses: actions/checkout@v2
- uses: Swatinem/rust-cache@v1
- name: Initialize job variables
id: vars
shell: bash
+78 -1
View File
@@ -67,7 +67,7 @@ jobs:
run: |
## Install dependencies
sudo apt-get update
sudo apt-get install autoconf autopoint bison texinfo gperf gcc g++ gdb python-pyinotify jq
sudo apt-get install autoconf autopoint bison texinfo gperf gcc g++ gdb python-pyinotify jq valgrind libexpect-perl
- name: Add various locales
shell: bash
run: |
@@ -197,3 +197,80 @@ jobs:
else
echo "::warning ::Skipping test summary comparison; no prior reference summary is available."
fi
gnu_coverage:
name: Run GNU tests with coverage
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
steps:
- name: Checkout code uutil
uses: actions/checkout@v2
with:
path: 'uutils'
- name: Checkout GNU coreutils
uses: actions/checkout@v2
with:
repository: 'coreutils/coreutils'
path: 'gnu'
ref: 'v9.0'
submodules: recursive
- name: Install `rust` toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
default: true
profile: minimal # minimal component installation (ie, no documentation)
components: rustfmt
- name: Install dependencies
run: |
sudo apt update
sudo apt install autoconf autopoint bison texinfo gperf gcc g++ gdb python-pyinotify jq valgrind libexpect-perl -y
- name: Add various locales
run: |
echo "Before:"
locale -a
## Some tests fail with 'cannot change locale (en_US.ISO-8859-1): No such file or directory'
## Some others need a French locale
sudo locale-gen
sudo locale-gen fr_FR
sudo locale-gen fr_FR.UTF-8
sudo update-locale
echo "After:"
locale -a
- name: Build binaries
env:
CARGO_INCREMENTAL: "0"
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
RUSTDOCFLAGS: "-Cpanic=abort"
run: |
cd uutils
UU_MAKE_PROFILE=debug bash util/build-gnu.sh
- name: Run GNU tests
run: bash uutils/util/run-gnu-test.sh
- name: "`grcov` ~ install"
uses: actions-rs/install@v0.1
with:
crate: grcov
version: latest
use-tool-cache: false
- name: Generate coverage data (via `grcov`)
id: coverage
run: |
## Generate coverage data
cd uutils
COVERAGE_REPORT_DIR="target/debug"
COVERAGE_REPORT_FILE="${COVERAGE_REPORT_DIR}/lcov.info"
mkdir -p "${COVERAGE_REPORT_DIR}"
sudo chown -R "$(whoami)" "${COVERAGE_REPORT_DIR}"
# display coverage files
grcov . --output-type files --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()" | sort --unique
# generate coverage report
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"
echo ::set-output name=report::${COVERAGE_REPORT_FILE}
- name: Upload coverage results (to Codecov.io)
uses: codecov/codecov-action@v2
with:
file: ${{ steps.coverage.outputs.report }}
flags: gnutests
name: gnutests
working-directory: uutils
Generated
+35 -25
View File
@@ -652,11 +652,12 @@ dependencies = [
[[package]]
name = "crypto-common"
version = "0.1.1"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0"
checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
@@ -719,13 +720,12 @@ checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "digest"
version = "0.10.1"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b"
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
dependencies = [
"block-buffer",
"crypto-common",
"generic-array",
"subtle",
]
@@ -957,9 +957,9 @@ dependencies = [
[[package]]
name = "hex"
version = "0.2.0"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hex-literal"
@@ -1128,10 +1128,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "md5"
version = "0.3.8"
name = "md-5"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48"
checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582"
dependencies = [
"digest",
]
[[package]]
name = "memchr"
@@ -1331,9 +1334,9 @@ checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "onig"
version = "4.3.3"
version = "6.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8518fcb2b1b8c2f45f0ad499df4fda6087fc3475ca69a185c173b8315d2fb383"
checksum = "67ddfe2c93bb389eea6e6d713306880c7f6dcc99a75b659ce145d962c861b225"
dependencies = [
"bitflags",
"lazy_static",
@@ -1343,9 +1346,9 @@ dependencies = [
[[package]]
name = "onig_sys"
version = "69.1.0"
version = "69.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388410bf5fa341f10e58e6db3975f4bea1ac30247dd79d37a9e5ced3cb4cc3b0"
checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e"
dependencies = [
"cc",
"pkg-config",
@@ -1807,6 +1810,12 @@ dependencies = [
"webpki",
]
[[package]]
name = "rustversion"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "same-file"
version = "1.0.6"
@@ -1880,9 +1889,9 @@ dependencies = [
[[package]]
name = "sha1"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cc229fb94bcb689ffc39bd4ded842f6ff76885efede7c6d1ffb62582878bea"
checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
@@ -1891,9 +1900,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec"
checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
@@ -1902,9 +1911,9 @@ dependencies = [
[[package]]
name = "sha3"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f935e31cf406e8c0e96c2815a5516181b7004ae8c5f296293221e9b1e356bd"
checksum = "881bf8156c87b6301fc5ca6b27f11eeb2761224c7081e69b409d5a1951a70c86"
dependencies = [
"digest",
"keccak",
@@ -2000,19 +2009,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
version = "0.21.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb"
[[package]]
name = "strum_macros"
version = "0.21.1"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38"
dependencies = [
"heck",
"proc-macro2",
"quote 1.0.14",
"rustversion",
"syn",
]
@@ -2617,7 +2627,7 @@ dependencies = [
"digest",
"hex",
"libc",
"md5",
"md-5",
"memchr 2.4.1",
"regex",
"regex-syntax",
+2 -2
View File
@@ -21,7 +21,7 @@ Running GNU tests
At the end you should have uutils, gnu and gnulib checked out next to each other.
- Run `cd uutils && ./util/build-gnu.sh && cd ..` to get everything ready (this may take a while)
- Finally, you can run `tests with bash uutils/util/run-gnu-test.sh <test>`. Instead of `<test>` insert the test you want to run, e.g. `tests/misc/wc-proc`.
- Finally, you can run tests with `bash uutils/util/run-gnu-test.sh <test>`. Instead of `<test>` insert the test you want to run, e.g. `tests/misc/wc-proc.sh`.
Code Coverage Report Generation
@@ -33,7 +33,7 @@ Code coverage report can be generated using [grcov](https://github.com/mozilla/g
### Using Nightly Rust
To generate [gcov-based](https://github.com/mozilla/grcov#example-how-to-generate-gcda-files-for-cc) coverage report
To generate [gcov-based](https://github.com/mozilla/grcov#example-how-to-generate-gcda-files-for-a-rust-project) coverage report
```bash
$ export CARGO_INCREMENTAL=0
+2 -2
View File
@@ -94,7 +94,7 @@ fn write_usage(w: &mut impl Write, app: &mut App, name: &str) -> io::Result<()>
.filter(|l| !l.is_empty())
.collect::<Vec<_>>()
.join("\n");
usage = usage.replace(app.get_name(), name);
usage = usage.replace(uucore::execution_phrase(), name);
writeln!(w, "{}", usage)?;
writeln!(w, "```")
}
@@ -204,7 +204,7 @@ fn write_options(w: &mut impl Write, app: &App) -> io::Result<()> {
writeln!(
w,
"<dd>\n\n{}\n\n</dd>",
arg.get_help().unwrap_or_default().replace("\n", "<br />")
arg.get_help().unwrap_or_default().replace('\n', "<br />")
)?;
}
writeln!(w, "</dl>\n")
+3 -6
View File
@@ -22,16 +22,13 @@ to attempt to recover from any other non-alphabet bytes in the
encoded stream.
";
fn usage() -> String {
format!("{0} [OPTION]... [FILE]", uucore::execution_phrase())
}
const USAGE: &str = "{} [OPTION]... [FILE]";
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let format = Format::Base32;
let usage = usage();
let config: base_common::Config = base_common::parse_base_cmd_args(args, ABOUT, &usage)?;
let config: base_common::Config = base_common::parse_base_cmd_args(args, ABOUT, USAGE)?;
// Create a reference to stdin so we can return a locked stdin from
// parse_base_cmd_args
@@ -48,5 +45,5 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
}
pub fn uu_app<'a>() -> App<'a> {
base_common::base_app(ABOUT)
base_common::base_app(ABOUT, USAGE)
}
+4 -3
View File
@@ -12,7 +12,7 @@ use std::io::{stdout, Read, Write};
use uucore::display::Quotable;
use uucore::encoding::{wrap_print, Data, Format};
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, InvalidEncodingHandling};
use std::fs::File;
use std::io::{BufReader, Stdin};
@@ -86,17 +86,18 @@ impl Config {
}
pub fn parse_base_cmd_args(args: impl uucore::Args, about: &str, usage: &str) -> UResult<Config> {
let app = base_app(about).override_usage(usage);
let app = base_app(about, usage);
let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
Config::from(&app.get_matches_from(arg_list))
}
pub fn base_app(about: &str) -> App {
pub fn base_app<'a>(about: &'a str, usage: &'a str) -> App<'a> {
App::new(uucore::util_name())
.version(crate_version!())
.about(about)
.override_usage(format_usage(usage))
.setting(AppSettings::InferLongArgs)
// Format arguments.
.arg(
+2 -5
View File
@@ -23,16 +23,13 @@ to attempt to recover from any other non-alphabet bytes in the
encoded stream.
";
fn usage() -> String {
format!("{0} [OPTION]... [FILE]", uucore::execution_phrase())
}
const USAGE: &str = "{0} [OPTION]... [FILE]";
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let format = Format::Base64;
let usage = usage();
let config: base_common::Config = base_common::parse_base_cmd_args(args, ABOUT, &usage)?;
let config: base_common::Config = base_common::parse_base_cmd_args(args, ABOUT, USAGE)?;
// Create a reference to stdin so we can return a locked stdin from
// parse_base_cmd_args
+5 -10
View File
@@ -11,18 +11,13 @@ use clap::{crate_version, App, AppSettings, Arg};
use std::path::{is_separator, PathBuf};
use uucore::display::Quotable;
use uucore::error::{UResult, UUsageError};
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, InvalidEncodingHandling};
static SUMMARY: &str = "Print NAME with any leading directory components removed
If specified, also remove a trailing SUFFIX";
fn usage() -> String {
format!(
"{0} NAME [SUFFIX]
{0} OPTION... NAME...",
uucore::execution_phrase()
)
}
const USAGE: &str = "{} NAME [SUFFIX]
{} OPTION... NAME...";
pub mod options {
pub static MULTIPLE: &str = "multiple";
@@ -36,11 +31,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let usage = usage();
//
// Argument parsing
//
let matches = uu_app().override_usage(&usage[..]).get_matches_from(args);
let matches = uu_app().get_matches_from(args);
// too few arguments
if !matches.is_present(options::NAME) {
@@ -97,6 +91,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.version(crate_version!())
.about(SUMMARY)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::MULTIPLE)
+3 -6
View File
@@ -38,12 +38,10 @@ const ENCODINGS: &[(&str, Format)] = &[
("z85", Format::Z85),
];
fn usage() -> String {
format!("{0} [OPTION]... [FILE]", uucore::execution_phrase())
}
const USAGE: &str = "{} [OPTION]... [FILE]";
pub fn uu_app<'a>() -> App<'a> {
let mut app = base_common::base_app(ABOUT);
let mut app = base_common::base_app(ABOUT, USAGE);
for encoding in ENCODINGS {
app = app.arg(Arg::new(encoding.0).long(encoding.0));
}
@@ -51,8 +49,7 @@ pub fn uu_app<'a>() -> App<'a> {
}
fn parse_cmd_args(args: impl uucore::Args) -> UResult<(Config, Format)> {
let usage = usage();
let matches = uu_app().override_usage(&usage[..]).get_matches_from(
let matches = uu_app().get_matches_from(
args.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any(),
);
+3 -3
View File
@@ -36,10 +36,10 @@ use std::net::Shutdown;
use std::os::unix::fs::FileTypeExt;
#[cfg(unix)]
use unix_socket::UnixStream;
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, InvalidEncodingHandling};
static NAME: &str = "cat";
static SYNTAX: &str = "[OPTION]... [FILE]...";
static USAGE: &str = "{} [OPTION]... [FILE]...";
static SUMMARY: &str = "Concatenate FILE(s), or standard input, to standard output
With no FILE, or when FILE is -, read standard input.";
@@ -243,7 +243,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.name(NAME)
.version(crate_version!())
.override_usage(SYNTAX)
.override_usage(format_usage(USAGE))
.about(SUMMARY)
.setting(AppSettings::InferLongArgs)
.arg(
+7 -12
View File
@@ -3,6 +3,7 @@
#![allow(clippy::upper_case_acronyms)]
use uucore::error::{UResult, USimpleError, UUsageError};
use uucore::format_usage;
use uucore::{display::Quotable, show_error, show_warning};
use clap::{App, AppSettings, Arg};
@@ -22,6 +23,10 @@ use errors::*;
static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Change the SELinux security context of each FILE to CONTEXT. \n\
With --reference, change the security context of each FILE to that of RFILE.";
const USAGE: &str = "\
{} [OPTION]... CONTEXT FILE... \n \
{} [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE... \n \
{} [OPTION]... --reference=RFILE FILE...";
pub mod options {
pub static VERBOSE: &str = "verbose";
@@ -52,20 +57,9 @@ pub mod options {
}
}
fn get_usage() -> String {
format!(
"{0} [OPTION]... CONTEXT FILE... \n \
{0} [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE... \n \
{0} [OPTION]... --reference=RFILE FILE...",
uucore::execution_phrase()
)
}
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = get_usage();
let config = uu_app().override_usage(usage.as_ref());
let config = uu_app();
let options = match parse_command_line(config, args) {
Ok(r) => r,
@@ -164,6 +158,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.version(VERSION)
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::dereference::DEREFERENCE)
+6 -15
View File
@@ -10,6 +10,7 @@
use uucore::display::Quotable;
pub use uucore::entries;
use uucore::error::{FromIo, UResult, USimpleError};
use uucore::format_usage;
use uucore::perms::{chown_base, options, IfFrom};
use clap::{App, AppSettings, Arg, ArgMatches};
@@ -20,12 +21,9 @@ use std::os::unix::fs::MetadataExt;
static ABOUT: &str = "Change the group of each FILE to GROUP.";
static VERSION: &str = env!("CARGO_PKG_VERSION");
fn get_usage() -> String {
format!(
"{0} [OPTION]... GROUP FILE...\n {0} [OPTION]... --reference=RFILE FILE...",
uucore::execution_phrase()
)
}
const USAGE: &str = "\
{} [OPTION]... GROUP FILE...\n \
{} [OPTION]... --reference=RFILE FILE...";
fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option<u32>, Option<u32>, IfFrom)> {
let dest_gid = if let Some(file) = matches.value_of(options::REFERENCE) {
@@ -53,21 +51,14 @@ fn parse_gid_and_uid(matches: &ArgMatches) -> UResult<(Option<u32>, Option<u32>,
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = get_usage();
chown_base(
uu_app().override_usage(&usage[..]),
args,
options::ARG_GROUP,
parse_gid_and_uid,
true,
)
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())
.version(VERSION)
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::verbosity::CHANGES)
+7 -14
View File
@@ -17,7 +17,7 @@ use uucore::fs::display_permissions_unix;
use uucore::libc::mode_t;
#[cfg(not(windows))]
use uucore::mode;
use uucore::{show_error, InvalidEncodingHandling};
use uucore::{format_usage, show_error, InvalidEncodingHandling};
use walkdir::WalkDir;
static ABOUT: &str = "Change the mode of each FILE to MODE.
@@ -35,14 +35,10 @@ mod options {
pub const FILE: &str = "FILE";
}
fn usage() -> String {
format!(
"{0} [OPTION]... MODE[,MODE]... FILE...
or: {0} [OPTION]... OCTAL-MODE FILE...
or: {0} [OPTION]... --reference=RFILE FILE...",
uucore::execution_phrase()
)
}
const USAGE: &str = "\
{} [OPTION]... MODE[,MODE]... FILE...
{} [OPTION]... OCTAL-MODE FILE...
{} [OPTION]... --reference=RFILE FILE...";
fn get_long_usage() -> String {
String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.")
@@ -58,13 +54,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
let mode_had_minus_prefix = mode::strip_minus_from_mode(&mut args);
let usage = usage();
let after_help = get_long_usage();
let matches = uu_app()
.override_usage(&usage[..])
.after_help(&after_help[..])
.get_matches_from(args);
let matches = uu_app().after_help(&after_help[..]).get_matches_from(args);
let changes = matches.is_present(options::CHANGES);
let quiet = matches.is_present(options::QUIET);
@@ -125,6 +117,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::CHANGES)
+6 -9
View File
@@ -9,6 +9,7 @@
use uucore::display::Quotable;
pub use uucore::entries::{self, Group, Locate, Passwd};
use uucore::format_usage;
use uucore::perms::{chown_base, options, IfFrom};
use uucore::error::{FromIo, UResult, USimpleError};
@@ -20,12 +21,9 @@ use std::os::unix::fs::MetadataExt;
static ABOUT: &str = "change file owner and group";
fn get_usage() -> String {
format!(
"{0} [OPTION]... [OWNER][:[GROUP]] FILE...\n{0} [OPTION]... --reference=RFILE FILE...",
uucore::execution_phrase()
)
}
const USAGE: &str = "\
{} [OPTION]... [OWNER][:[GROUP]] FILE...
{} [OPTION]... --reference=RFILE FILE...";
fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult<(Option<u32>, Option<u32>, IfFrom)> {
let filter = if let Some(spec) = matches.value_of(options::FROM) {
@@ -56,10 +54,8 @@ fn parse_gid_uid_and_filter(matches: &ArgMatches) -> UResult<(Option<u32>, Optio
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = get_usage();
chown_base(
uu_app().override_usage(&usage[..]),
uu_app(),
args,
options::ARG_OWNER,
parse_gid_uid_and_filter,
@@ -71,6 +67,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::verbosity::CHANGES)
+3 -3
View File
@@ -17,10 +17,10 @@ use std::path::Path;
use std::process::Command;
use uucore::error::{set_exit_code, UResult};
use uucore::libc::{self, chroot, setgid, setgroups, setuid};
use uucore::{entries, InvalidEncodingHandling};
use uucore::{entries, format_usage, InvalidEncodingHandling};
static ABOUT: &str = "Run COMMAND with root directory set to NEWROOT.";
static SYNTAX: &str = "[OPTION]... NEWROOT [COMMAND [ARG]...]";
static USAGE: &str = "{} [OPTION]... NEWROOT [COMMAND [ARG]...]";
mod options {
pub const NEWROOT: &str = "newroot";
@@ -95,7 +95,7 @@ pub fn uu_app<'a>() -> App<'a> {
App::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(SYNTAX)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::NEWROOT)
+3 -3
View File
@@ -12,15 +12,15 @@ use std::io::{self, stdin, BufReader, Read};
use std::path::Path;
use uucore::display::Quotable;
use uucore::error::{FromIo, UResult};
use uucore::show;
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, show};
// NOTE: CRC_TABLE_LEN *must* be <= 256 as we cast 0..CRC_TABLE_LEN to u8
const CRC_TABLE_LEN: usize = 256;
const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table();
const NAME: &str = "cksum";
const SYNTAX: &str = "[OPTIONS] [FILE]...";
const USAGE: &str = "{} [OPTIONS] [FILE]...";
const SUMMARY: &str = "Print CRC and size for each file";
const fn generate_crc_table() -> [u32; CRC_TABLE_LEN] {
@@ -145,7 +145,7 @@ pub fn uu_app<'a>() -> App<'a> {
.name(NAME)
.version(crate_version!())
.about(SUMMARY)
.override_usage(SYNTAX)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::FILE)
+4 -7
View File
@@ -13,12 +13,13 @@ use std::io::{self, stdin, BufRead, BufReader, Stdin};
use std::path::Path;
use uucore::error::FromIo;
use uucore::error::UResult;
use uucore::InvalidEncodingHandling;
use uucore::{format_usage, InvalidEncodingHandling};
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
static ABOUT: &str = "compare two sorted files line by line";
static LONG_HELP: &str = "";
const USAGE: &str = "{} [OPTION]... FILE1 FILE2";
mod options {
pub const COLUMN_1: &str = "1";
@@ -30,10 +31,6 @@ mod options {
pub const FILE_2: &str = "FILE2";
}
fn usage() -> String {
format!("{} [OPTION]... FILE1 FILE2", uucore::execution_phrase())
}
fn mkdelim(col: usize, opts: &ArgMatches) -> String {
let mut s = String::new();
let delim = opts.value_of(options::DELIMITER).unwrap();
@@ -132,12 +129,11 @@ fn open_file(name: &str) -> io::Result<LineReader> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = usage();
let args = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
let matches = uu_app().override_usage(&usage[..]).get_matches_from(args);
let matches = uu_app().get_matches_from(args);
let filename1 = matches.value_of(options::FILE_1).unwrap();
let filename2 = matches.value_of(options::FILE_2).unwrap();
let mut f1 = open_file(filename1).map_err_context(|| filename1.to_string())?;
@@ -152,6 +148,7 @@ pub fn uu_app<'a>() -> App<'a> {
.version(crate_version!())
.about(ABOUT)
.after_help(LONG_HELP)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(
Arg::new(options::COLUMN_1)
+82 -33
View File
@@ -19,6 +19,7 @@ extern crate quick_error;
extern crate uucore;
use uucore::display::Quotable;
use uucore::format_usage;
use uucore::fs::FileInformation;
#[cfg(windows)]
use winapi::um::fileapi::CreateFileW;
@@ -29,6 +30,8 @@ use std::borrow::Cow;
use clap::{crate_version, App, AppSettings, Arg, ArgMatches};
use filetime::FileTime;
#[cfg(unix)]
use libc::mkfifo;
use quick_error::ResultExt;
use std::collections::HashSet;
use std::env;
@@ -42,6 +45,10 @@ use std::fs::OpenOptions;
use std::io;
use std::io::{stdin, stdout, Write};
use std::mem;
#[cfg(unix)]
use std::os::unix::ffi::OsStrExt;
#[cfg(unix)]
use std::os::unix::fs::{FileTypeExt, PermissionsExt};
#[cfg(target_os = "linux")]
use std::os::unix::io::AsRawFd;
#[cfg(windows)]
@@ -54,9 +61,6 @@ use uucore::error::{set_exit_code, ExitCode, UError, UResult};
use uucore::fs::{canonicalize, MissingHandling, ResolveMode};
use walkdir::WalkDir;
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;
#[cfg(target_os = "linux")]
ioctl!(write ficlone with 0x94, 9; std::os::raw::c_int);
@@ -149,7 +153,7 @@ pub type Target = PathBuf;
pub type TargetSlice = Path;
/// Specifies whether when overwrite files
#[derive(Clone, Eq, PartialEq)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum ClobberMode {
Force,
RemoveDestination,
@@ -157,7 +161,7 @@ pub enum ClobberMode {
}
/// Specifies whether when overwrite files
#[derive(Clone, Eq, PartialEq)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum OverwriteMode {
/// [Default] Always overwrite existing files
Clobber(ClobberMode),
@@ -230,14 +234,10 @@ static ABOUT: &str = "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.";
static LONG_HELP: &str = "";
static EXIT_ERR: i32 = 1;
fn usage() -> String {
format!(
"{0} [OPTION]... [-T] SOURCE DEST
{0} [OPTION]... SOURCE... DIRECTORY
{0} [OPTION]... -t DIRECTORY SOURCE...",
uucore::execution_phrase()
)
}
const USAGE: &str = "\
{} [OPTION]... [-T] SOURCE DEST
{} [OPTION]... SOURCE... DIRECTORY
{} [OPTION]... -t DIRECTORY SOURCE...";
// Argument constants
mod options {
@@ -297,9 +297,17 @@ static DEFAULT_ATTRIBUTES: &[Attribute] = &[
];
pub fn uu_app<'a>() -> App<'a> {
const MODE_ARGS: &[&str] = &[
options::LINK,
options::REFLINK,
options::SYMBOLIC_LINK,
options::ATTRIBUTES_ONLY,
options::COPY_CONTENTS,
];
App::new(uucore::util_name())
.version(crate_version!())
.about(ABOUT)
.override_usage(format_usage(USAGE))
.setting(AppSettings::InferLongArgs)
.arg(Arg::new(options::TARGET_DIRECTORY)
.short('t')
@@ -316,17 +324,17 @@ pub fn uu_app<'a>() -> App<'a> {
.arg(Arg::new(options::INTERACTIVE)
.short('i')
.long(options::INTERACTIVE)
.conflicts_with(options::NO_CLOBBER)
.overrides_with(options::NO_CLOBBER)
.help("ask before overwriting files"))
.arg(Arg::new(options::LINK)
.short('l')
.long(options::LINK)
.overrides_with(options::REFLINK)
.overrides_with_all(MODE_ARGS)
.help("hard-link files instead of copying"))
.arg(Arg::new(options::NO_CLOBBER)
.short('n')
.long(options::NO_CLOBBER)
.conflicts_with(options::INTERACTIVE)
.overrides_with(options::INTERACTIVE)
.help("don't overwrite a file that already exists"))
.arg(Arg::new(options::RECURSIVE)
.short('r')
@@ -346,8 +354,7 @@ pub fn uu_app<'a>() -> App<'a> {
.arg(Arg::new(options::SYMBOLIC_LINK)
.short('s')
.long(options::SYMBOLIC_LINK)
.conflicts_with(options::LINK)
.overrides_with(options::REFLINK)
.overrides_with_all(MODE_ARGS)
.help("make symbolic links instead of copying"))
.arg(Arg::new(options::FORCE)
.short('f')
@@ -357,9 +364,9 @@ pub fn uu_app<'a>() -> App<'a> {
Currently not implemented for Windows."))
.arg(Arg::new(options::REMOVE_DESTINATION)
.long(options::REMOVE_DESTINATION)
.conflicts_with(options::FORCE)
.overrides_with(options::FORCE)
.help("remove each existing destination file before attempting to open it \
(contrast with --force). On Windows, current only works for writeable files."))
(contrast with --force). On Windows, currently only works for writeable files."))
.arg(backup_control::arguments::backup())
.arg(backup_control::arguments::backup_no_args())
.arg(backup_control::arguments::suffix())
@@ -372,11 +379,11 @@ pub fn uu_app<'a>() -> App<'a> {
.long(options::REFLINK)
.takes_value(true)
.value_name("WHEN")
.overrides_with_all(MODE_ARGS)
.help("control clone/CoW copies. See below"))
.arg(Arg::new(options::ATTRIBUTES_ONLY)
.long(options::ATTRIBUTES_ONLY)
.conflicts_with(options::COPY_CONTENTS)
.overrides_with(options::REFLINK)
.overrides_with_all(MODE_ARGS)
.help("Don't copy the file data, just the attributes"))
.arg(Arg::new(options::PRESERVE)
.long(options::PRESERVE)
@@ -386,7 +393,7 @@ pub fn uu_app<'a>() -> App<'a> {
.possible_values(PRESERVABLE_ATTRIBUTES)
.min_values(0)
.value_name("ATTR_LIST")
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::NO_PRESERVE])
.overrides_with_all(&[options::ARCHIVE, options::PRESERVE_DEFAULT_ATTRIBUTES, options::NO_PRESERVE])
// -d sets this option
// --archive sets this option
.help("Preserve the specified attributes (default: mode, ownership (unix only), timestamps), \
@@ -394,13 +401,13 @@ pub fn uu_app<'a>() -> App<'a> {
.arg(Arg::new(options::PRESERVE_DEFAULT_ATTRIBUTES)
.short('p')
.long(options::PRESERVE_DEFAULT_ATTRIBUTES)
.conflicts_with_all(&[options::PRESERVE, options::NO_PRESERVE, options::ARCHIVE])
.overrides_with_all(&[options::PRESERVE, options::NO_PRESERVE, options::ARCHIVE])
.help("same as --preserve=mode,ownership(unix only),timestamps"))
.arg(Arg::new(options::NO_PRESERVE)
.long(options::NO_PRESERVE)
.takes_value(true)
.value_name("ATTR_LIST")
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::ARCHIVE])
.overrides_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::ARCHIVE])
.help("don't preserve the specified attributes"))
.arg(Arg::new(options::PARENTS)
.long(options::PARENTS)
@@ -409,18 +416,18 @@ pub fn uu_app<'a>() -> App<'a> {
.arg(Arg::new(options::NO_DEREFERENCE)
.short('P')
.long(options::NO_DEREFERENCE)
.conflicts_with(options::DEREFERENCE)
.overrides_with(options::DEREFERENCE)
// -d sets this option
.help("never follow symbolic links in SOURCE"))
.arg(Arg::new(options::DEREFERENCE)
.short('L')
.long(options::DEREFERENCE)
.conflicts_with(options::NO_DEREFERENCE)
.overrides_with(options::NO_DEREFERENCE)
.help("always follow symbolic links in SOURCE"))
.arg(Arg::new(options::ARCHIVE)
.short('a')
.long(options::ARCHIVE)
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::NO_PRESERVE])
.overrides_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::NO_PRESERVE])
.help("Same as -dR --preserve=all"))
.arg(Arg::new(options::NO_DEREFERENCE_PRESERVE_LINKS)
.short('d')
@@ -433,7 +440,7 @@ pub fn uu_app<'a>() -> App<'a> {
// TODO: implement the following args
.arg(Arg::new(options::COPY_CONTENTS)
.long(options::COPY_CONTENTS)
.conflicts_with(options::ATTRIBUTES_ONLY)
.overrides_with(options::ATTRIBUTES_ONLY)
.help("NotImplemented: copy contents of special files when recursive"))
.arg(Arg::new(options::SPARSE)
.long(options::SPARSE)
@@ -456,14 +463,12 @@ pub fn uu_app<'a>() -> App<'a> {
#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let usage = usage();
let matches = uu_app()
.after_help(&*format!(
"{}\n{}",
LONG_HELP,
backup_control::BACKUP_CONTROL_LONG_HELP
))
.override_usage(&usage[..])
.get_matches_from(args);
let options = Options::from_matches(&matches)?;
@@ -969,6 +974,16 @@ fn copy_directory(
return copy_file(root, target, options, symlinked_files);
}
// check if root is a prefix of target
if path_has_prefix(target, root)? {
return Err(format!(
"cannot copy a directory, {}, into itself, {}",
root.quote(),
target.quote()
)
.into());
}
let current_dir =
env::current_dir().unwrap_or_else(|e| crash!(1, "failed to get current directory {}", e));
@@ -1388,12 +1403,23 @@ fn copy_helper(
let parent = dest.parent().unwrap_or(dest);
fs::create_dir_all(parent)?;
}
let is_symlink = fs::symlink_metadata(&source)?.file_type().is_symlink();
let file_type = fs::symlink_metadata(&source)?.file_type();
let is_symlink = file_type.is_symlink();
#[cfg(unix)]
let is_fifo = file_type.is_fifo();
#[cfg(not(unix))]
let is_fifo = false;
if source.as_os_str() == "/dev/null" {
/* workaround a limitation of fs::copy
* https://github.com/rust-lang/rust/issues/79390
*/
File::create(dest).context(dest.display().to_string())?;
} else if is_fifo && options.recursive {
#[cfg(unix)]
copy_fifo(dest, options.overwrite)?;
} else if is_symlink {
copy_link(source, dest, symlinked_files)?;
} else if options.reflink_mode != ReflinkMode::Never {
@@ -1413,6 +1439,23 @@ fn copy_helper(
Ok(())
}
// "Copies" a FIFO by creating a new one. This workaround is because Rust's
// built-in fs::copy does not handle FIFOs (see rust-lang/rust/issues/79390).
#[cfg(unix)]
fn copy_fifo(dest: &Path, overwrite: OverwriteMode) -> CopyResult<()> {
if dest.exists() {
overwrite.verify(dest)?;
fs::remove_file(&dest)?;
}
let name = CString::new(dest.as_os_str().as_bytes()).unwrap();
let err = unsafe { mkfifo(name.as_ptr(), 0o666) };
if err == -1 {
return Err(format!("cannot create fifo {}: File exists", dest.quote()).into());
}
Ok(())
}
fn copy_link(
source: &Path,
dest: &Path,
@@ -1496,7 +1539,6 @@ fn copy_on_write_macos(
// Extract paths in a form suitable to be passed to a syscall.
// The unwrap() is safe because they come from the command-line and so contain non nul
// character.
use std::os::unix::ffi::OsStrExt;
let src = CString::new(source.as_os_str().as_bytes()).unwrap();
let dst = CString::new(dest.as_os_str().as_bytes()).unwrap();
@@ -1582,6 +1624,13 @@ pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> io::Result<bool> {
Ok(pathbuf1 == pathbuf2)
}
pub fn path_has_prefix(p1: &Path, p2: &Path) -> io::Result<bool> {
let pathbuf1 = canonicalize(p1, MissingHandling::Normal, ResolveMode::Logical)?;
let pathbuf2 = canonicalize(p2, MissingHandling::Normal, ResolveMode::Logical)?;
Ok(pathbuf1.starts_with(pathbuf2))
}
#[test]
fn test_cp_localize_to_target() {
assert!(

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