mirror of
https://github.com/uutils/coreutils
synced 2024-12-14 23:32:39 +00:00
Merge branch 'main' into dependabot/cargo/blake3-1.3.2
This commit is contained in:
commit
13fac01d31
322 changed files with 3527 additions and 2674 deletions
85
.github/workflows/CICD.yml
vendored
85
.github/workflows/CICD.yml
vendored
|
@ -1,11 +1,11 @@
|
|||
name: CICD
|
||||
|
||||
# spell-checker:ignore (acronyms) CICD MSVC musl
|
||||
# spell-checker:ignore (abbrev/names) CICD CodeCOV MacOS MinGW MSVC musl
|
||||
# spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic Dwarnings RUSTDOCFLAGS RUSTFLAGS Zpanic
|
||||
# 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 multisize Swatinem
|
||||
# spell-checker:ignore (people) Peltoche rivy
|
||||
# spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot fdesc fdescfs gmake grcov halium lcov libssl mkdir popd printf pushd rsync rustc rustfmt rustup shopt utmpdump xargs
|
||||
# spell-checker:ignore (misc) aarch alnum armhf bindir busytest coreutils defconfig DESTDIR gecos gnueabihf issuecomment maint multisize nullglob onexitbegin onexitend pell runtest Swatinem tempfile testsuite toybox uutils
|
||||
|
||||
env:
|
||||
PROJECT_NAME: coreutils
|
||||
|
@ -50,7 +50,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# failure mode
|
||||
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
|
||||
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
|
||||
|
@ -102,7 +102,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# failure mode
|
||||
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
|
||||
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
|
||||
|
@ -116,6 +116,7 @@ jobs:
|
|||
outputs CARGO_FEATURES_OPTION
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt}
|
||||
rustup toolchain install stable -c rustfmt --profile minimal
|
||||
rustup default stable
|
||||
|
@ -150,7 +151,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# failure mode
|
||||
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
|
||||
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
|
||||
|
@ -170,11 +171,13 @@ jobs:
|
|||
- name: Install/setup prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
## Install/setup prerequisites
|
||||
case '${{ matrix.job.os }}' in
|
||||
macos-latest) brew install coreutils ;; # needed for show-utils.sh
|
||||
esac
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable -c clippy --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -206,7 +209,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# failure mode
|
||||
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
|
||||
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
|
||||
|
@ -257,7 +260,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# failure mode
|
||||
unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in
|
||||
''|0|f|false|n|no|off) FAULT_TYPE=warning ;;
|
||||
|
@ -276,6 +279,7 @@ jobs:
|
|||
outputs CARGO_UTILITY_LIST_OPTIONS
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable -c clippy --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -299,7 +303,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# target-specific options
|
||||
# * CARGO_FEATURES_OPTION
|
||||
unset CARGO_FEATURES_OPTION
|
||||
|
@ -307,6 +311,7 @@ jobs:
|
|||
outputs CARGO_FEATURES_OPTION
|
||||
- name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }})
|
||||
run: |
|
||||
## Install `rust` toolchain (v${{ env.RUST_MIN_SRV }})
|
||||
rustup toolchain install ${{ env.RUST_MIN_SRV }} --profile minimal
|
||||
rustup default ${{ env.RUST_MIN_SRV }}
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -347,6 +352,7 @@ jobs:
|
|||
run: cargo test -v ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -p uucore -p coreutils
|
||||
env:
|
||||
RUSTFLAGS: "-Awarnings --cfg unsound_local_offset"
|
||||
RUST_BACKTRACE: "1"
|
||||
|
||||
deps:
|
||||
name: Dependencies
|
||||
|
@ -360,6 +366,7 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -383,6 +390,7 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -394,6 +402,8 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
make test
|
||||
env:
|
||||
RUST_BACKTRACE: "1"
|
||||
|
||||
|
||||
build_rust_stable:
|
||||
|
@ -412,11 +422,14 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Test
|
||||
run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||
env:
|
||||
RUST_BACKTRACE: "1"
|
||||
|
||||
build_rust_nightly:
|
||||
name: Build/nightly
|
||||
|
@ -434,11 +447,14 @@ jobs:
|
|||
- uses: actions/checkout@v3
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install nightly --profile minimal
|
||||
rustup default nightly
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: Test
|
||||
run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||
env:
|
||||
RUST_BACKTRACE: "1"
|
||||
|
||||
compute_size:
|
||||
name: Binary sizes
|
||||
|
@ -459,26 +475,29 @@ jobs:
|
|||
sudo apt-get install jq
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rustup toolchain install stable --profile minimal
|
||||
rustup default stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "`make install`"
|
||||
shell: bash
|
||||
run: |
|
||||
## `make install`
|
||||
make install DESTDIR=target/size-release/
|
||||
make install MULTICALL=y DESTDIR=target/size-multi-release/
|
||||
# strip the results
|
||||
strip target/size*/usr/local/bin/*
|
||||
- name: "Compute sizes"
|
||||
- name: Compute uutil release sizes
|
||||
shell: bash
|
||||
run: |
|
||||
## Compute uutil release sizes
|
||||
SIZE=$(du -s target/size-release/usr/local/bin/|awk '{print $1}')
|
||||
SIZEMULTI=$(du -s target/size-multi-release/usr/local/bin/|awk '{print $1}')
|
||||
SIZE_MULTI=$(du -s target/size-multi-release/usr/local/bin/|awk '{print $1}')
|
||||
jq -n \
|
||||
--arg date "$(date --rfc-email)" \
|
||||
--arg sha "$GITHUB_SHA" \
|
||||
--arg size "$SIZE" \
|
||||
--arg multisize "$SIZEMULTI" \
|
||||
--arg multisize "$SIZE_MULTI" \
|
||||
'{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
@ -526,7 +545,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# toolchain
|
||||
TOOLCHAIN="stable" ## default to "stable" toolchain
|
||||
# * specify alternate/non-default TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: GH:rust-lang/rust#47048, GH:rust-lang/rust#53454, GH:rust-lang/cargo#6754)
|
||||
|
@ -546,7 +565,7 @@ jobs:
|
|||
REF_NAME=${GITHUB_REF#refs/*/}
|
||||
unset REF_BRANCH ; case "${GITHUB_REF}" in refs/heads/*) REF_BRANCH=${GITHUB_REF#refs/heads/} ;; esac;
|
||||
unset REF_TAG ; case "${GITHUB_REF}" in refs/tags/*) REF_TAG=${GITHUB_REF#refs/tags/} ;; esac;
|
||||
REF_SHAS=${GITHUB_SHA:0:8}
|
||||
REF_SHAS=${GITHUB_SHA:0:10}
|
||||
outputs REF_NAME REF_BRANCH REF_TAG REF_SHAS
|
||||
# parse target
|
||||
unset TARGET_ARCH
|
||||
|
@ -597,7 +616,7 @@ jobs:
|
|||
# ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml")
|
||||
if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then
|
||||
cargo install --version 0.2.1 cross
|
||||
printf "[build.env]\npassthrough = [\"CI\"]\n" > Cross.toml
|
||||
printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\"]\n" > Cross.toml
|
||||
fi
|
||||
# * test only library and/or binaries for arm-type targets
|
||||
unset CARGO_TEST_OPTIONS ; case '${{ matrix.job.target }}' in aarch64-* | arm-*) CARGO_TEST_OPTIONS="--bins" ;; esac;
|
||||
|
@ -645,6 +664,7 @@ jobs:
|
|||
esac
|
||||
- name: rust toolchain ~ install
|
||||
run: |
|
||||
## rust toolchain ~ install
|
||||
rustup toolchain install ${{ env.RUST_MIN_SRV }} -t ${{ matrix.job.target }} --profile minimal
|
||||
rustup default ${{ env.RUST_MIN_SRV }}
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -655,7 +675,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## Dependent VARs setup
|
||||
outputs() { step_id="dep_vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# * determine sub-crate utility list
|
||||
UTILITY_LIST="$(./util/show-utils.sh ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }})"
|
||||
echo UTILITY_LIST=${UTILITY_LIST}
|
||||
|
@ -687,18 +707,25 @@ jobs:
|
|||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
## Build
|
||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} build --release \
|
||||
--target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||
- name: Test
|
||||
shell: bash
|
||||
run: |
|
||||
## Test
|
||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \
|
||||
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
|
||||
env:
|
||||
RUST_BACKTRACE: "1"
|
||||
- name: Test individual utilities
|
||||
shell: bash
|
||||
run: |
|
||||
## Test individual utilities
|
||||
${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \
|
||||
${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||
env:
|
||||
RUST_BACKTRACE: "1"
|
||||
- name: Archive executable artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
@ -771,10 +798,11 @@ jobs:
|
|||
run: |
|
||||
## Install/setup prerequisites
|
||||
make prepare-busytest
|
||||
- name: "Run BusyBox test suite"
|
||||
- name: Run BusyBox test suite
|
||||
id: summary
|
||||
shell: bash
|
||||
run: |
|
||||
## Run BusyBox test suite
|
||||
set -v
|
||||
cp .busybox-config target/debug/.config
|
||||
## Run BusyBox test suite
|
||||
|
@ -835,16 +863,20 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
echo "TEST_SUMMARY_FILE=toybox-result.json" >> $GITHUB_OUTPUT
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
TEST_SUMMARY_FILE="toybox-result.json"
|
||||
outputs TEST_SUMMARY_FILE
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: rust toolchain ~ install
|
||||
run: |
|
||||
## rust toolchain ~ install
|
||||
rustup toolchain install ${{ env.RUST_MIN_SRV }} --profile minimal
|
||||
rustup default ${{ env.RUST_MIN_SRV }}
|
||||
- name: "Build coreutils as multiple binaries"
|
||||
- name: Build coreutils as multiple binaries
|
||||
shell: bash
|
||||
run: |
|
||||
## Build individual uutil binaries
|
||||
set -v
|
||||
make
|
||||
- name: Install/setup prerequisites
|
||||
|
@ -852,12 +884,12 @@ jobs:
|
|||
run: |
|
||||
## Install/setup prerequisites
|
||||
make toybox-src
|
||||
- name: "Run Toybox test suite"
|
||||
- name: Run Toybox test suite
|
||||
id: summary
|
||||
shell: bash
|
||||
run: |
|
||||
set -v
|
||||
## Run Toybox test suite
|
||||
set -v
|
||||
cd tmp/toybox-*/
|
||||
make defconfig
|
||||
make tests &> tmp.log || true
|
||||
|
@ -1023,6 +1055,7 @@ jobs:
|
|||
cd "${WORKSPACE}"
|
||||
unset FAULT
|
||||
cargo build || FAULT=1
|
||||
export RUST_BACKTRACE=1
|
||||
if (test -z "\$FAULT"); then cargo test --features '${{ matrix.job.features }}' || FAULT=1 ; fi
|
||||
if (test -z "\$FAULT"); then cargo test --all-features -p uucore || FAULT=1 ; fi
|
||||
# Clean to avoid to rsync back the files
|
||||
|
@ -1050,7 +1083,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# toolchain
|
||||
TOOLCHAIN="nightly" ## default to "nightly" toolchain (required for certain required unstable compiler flags) ## !maint: refactor when stable channel has needed support
|
||||
# * specify gnu-type TOOLCHAIN for windows; `grcov` requires gnu-style code coverage data files
|
||||
|
@ -1093,6 +1126,7 @@ jobs:
|
|||
esac
|
||||
- name: rust toolchain ~ install
|
||||
run: |
|
||||
## rust toolchain ~ install
|
||||
rustup toolchain install ${{ steps.vars.outputs.TOOLCHAIN }} --profile minimal
|
||||
rustup default ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -1101,7 +1135,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## Dependent VARs setup
|
||||
outputs() { step_id="dep_vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# * determine sub-crate utility list
|
||||
UTILITY_LIST="$(./util/show-utils.sh ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }})"
|
||||
CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)"
|
||||
|
@ -1113,6 +1147,7 @@ jobs:
|
|||
RUSTC_WRAPPER: ""
|
||||
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
RUSTDOCFLAGS: "-Cpanic=abort"
|
||||
RUST_BACKTRACE: "1"
|
||||
# RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- name: Test
|
||||
run: cargo test ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} --no-fail-fast
|
||||
|
@ -1121,6 +1156,7 @@ jobs:
|
|||
RUSTC_WRAPPER: ""
|
||||
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
RUSTDOCFLAGS: "-Cpanic=abort"
|
||||
RUST_BACKTRACE: "1"
|
||||
# RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- name: Test individual utilities
|
||||
run: cargo test --no-fail-fast ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||
|
@ -1129,6 +1165,7 @@ jobs:
|
|||
RUSTC_WRAPPER: ""
|
||||
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
RUSTDOCFLAGS: "-Cpanic=abort"
|
||||
RUST_BACKTRACE: "1"
|
||||
# RUSTUP_TOOLCHAIN: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||
- name: "`grcov` ~ install"
|
||||
id: build_grcov
|
||||
|
|
6
.github/workflows/FixPR.yml
vendored
6
.github/workflows/FixPR.yml
vendored
|
@ -32,12 +32,13 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# surface MSRV from CICD workflow
|
||||
RUST_MIN_SRV=$(grep -P "^\s+RUST_MIN_SRV:" .github/workflows/CICD.yml | grep -Po "(?<=\x22)\d+[.]\d+(?:[.]\d+)?(?=\x22)" )
|
||||
outputs RUST_MIN_SRV
|
||||
- name: Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }})
|
||||
run: |
|
||||
## Install `rust` toolchain (v${{ steps.vars.outputs.RUST_MIN_SRV }})
|
||||
rustup toolchain install ${{ steps.vars.outputs.RUST_MIN_SRV }} --profile minimal
|
||||
rustup default ${{ steps.vars.outputs.RUST_MIN_SRV }}
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
|
@ -94,7 +95,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# target-specific options
|
||||
# * CARGO_FEATURES_OPTION
|
||||
CARGO_FEATURES_OPTION='' ;
|
||||
|
@ -102,6 +103,7 @@ jobs:
|
|||
outputs CARGO_FEATURES_OPTION
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt}
|
||||
rustup toolchain install stable -c rustfmt --profile minimal
|
||||
rustup default stable
|
||||
|
|
25
.github/workflows/GnuTests.yml
vendored
25
.github/workflows/GnuTests.yml
vendored
|
@ -1,6 +1,11 @@
|
|||
name: GnuTests
|
||||
|
||||
# spell-checker:ignore (names) gnulib ; (jargon) submodules ; (people) Dawid Dziurla * dawidd ; (utils) autopoint chksum gperf pyinotify shopt texinfo ; (vars) FILESET SUBDIRS XPASS
|
||||
# spell-checker:ignore (abbrev/names) CodeCov gnulib GnuTests
|
||||
# spell-checker:ignore (jargon) submodules
|
||||
# spell-checker:ignore (libs/utils) autopoint chksum gperf lcov libexpect pyinotify shopt texinfo valgrind
|
||||
# spell-checker:ignore (options) Ccodegen Coverflow Cpanic Zpanic
|
||||
# spell-checker:ignore (people) Dawid Dziurla * dawidd
|
||||
# spell-checker:ignore (vars) FILESET SUBDIRS XPASS
|
||||
|
||||
# * note: to run a single test => `REPO/util/run-gnu-test.sh PATH/TO/TEST/SCRIPT`
|
||||
|
||||
|
@ -23,7 +28,7 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
## VARs setup
|
||||
outputs() { step_id="vars"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
# * config
|
||||
path_GNU="gnu"
|
||||
path_GNU_tests="${path_GNU}/tests"
|
||||
|
@ -67,6 +72,7 @@ jobs:
|
|||
path: "${{ steps.vars.outputs.path_reference }}"
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt}
|
||||
rustup toolchain install stable -c rustfmt --profile minimal
|
||||
rustup default stable
|
||||
|
@ -79,6 +85,7 @@ jobs:
|
|||
- name: Add various locales
|
||||
shell: bash
|
||||
run: |
|
||||
## Add various locales
|
||||
echo "Before:"
|
||||
locale -a
|
||||
## Some tests fail with 'cannot change locale (en_US.ISO-8859-1): No such file or directory'
|
||||
|
@ -103,27 +110,31 @@ jobs:
|
|||
- name: Run GNU tests
|
||||
shell: bash
|
||||
run: |
|
||||
## Run GNU tests
|
||||
path_GNU='${{ steps.vars.outputs.path_GNU }}'
|
||||
path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}'
|
||||
bash "${path_UUTILS}/util/run-gnu-test.sh"
|
||||
- name: Run GNU root tests
|
||||
shell: bash
|
||||
run: |
|
||||
## Run GNU root tests
|
||||
path_GNU='${{ steps.vars.outputs.path_GNU }}'
|
||||
path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}'
|
||||
bash "${path_UUTILS}/util/run-gnu-test.sh" run-root
|
||||
- name: Extract testing info into JSON
|
||||
shell: bash
|
||||
run : |
|
||||
## Extract testing info into JSON
|
||||
path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}'
|
||||
python ${path_UUTILS}/util/gnu-json-result.py ${{ steps.vars.outputs.path_GNU_tests }} > ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}
|
||||
- name: Extract/summarize testing info
|
||||
id: summary
|
||||
shell: bash
|
||||
run: |
|
||||
path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}'
|
||||
## Extract/summarize testing info
|
||||
outputs() { step_id="summary"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; }
|
||||
#
|
||||
path_UUTILS='${{ steps.vars.outputs.path_UUTILS }}'
|
||||
#
|
||||
SUITE_LOG_FILE='${{ steps.vars.outputs.SUITE_LOG_FILE }}'
|
||||
ROOT_SUITE_LOG_FILE='${{ steps.vars.outputs.ROOT_SUITE_LOG_FILE }}'
|
||||
|
@ -180,6 +191,7 @@ jobs:
|
|||
- name: Compare test failures VS reference
|
||||
shell: bash
|
||||
run: |
|
||||
## Compare test failures VS reference
|
||||
have_new_failures=""
|
||||
REF_LOG_FILE='${{ steps.vars.outputs.path_reference }}/test-logs/test-suite.log'
|
||||
REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json'
|
||||
|
@ -254,6 +266,7 @@ jobs:
|
|||
if: success() || failure() # run regardless of prior step success/failure
|
||||
shell: bash
|
||||
run: |
|
||||
## Compare test summary VS reference
|
||||
REF_SUMMARY_FILE='${{ steps.vars.outputs.path_reference }}/test-summary/gnu-result.json'
|
||||
if test -f "${REF_SUMMARY_FILE}"; then
|
||||
echo "Reference SHA1/ID: $(sha1sum -- "${REF_SUMMARY_FILE}")"
|
||||
|
@ -280,15 +293,18 @@ jobs:
|
|||
submodules: recursive
|
||||
- name: Install `rust` toolchain
|
||||
run: |
|
||||
## Install `rust` toolchain
|
||||
rm -f "${HOME}/.cargo/bin/"{rustfmt,cargo-fmt}
|
||||
rustup toolchain install nightly -c rustfmt --profile minimal
|
||||
rustup default nightly
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
## Install dependencies
|
||||
sudo apt update
|
||||
sudo apt install autoconf autopoint bison texinfo gperf gcc g++ gdb python3-pyinotify jq valgrind libexpect-perl -y
|
||||
- name: Add various locales
|
||||
run: |
|
||||
## Add various locales
|
||||
echo "Before:"
|
||||
locale -a
|
||||
## Some tests fail with 'cannot change locale (en_US.ISO-8859-1): No such file or directory'
|
||||
|
@ -305,6 +321,7 @@ jobs:
|
|||
RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
|
||||
RUSTDOCFLAGS: "-Cpanic=abort"
|
||||
run: |
|
||||
## Build binaries
|
||||
cd uutils
|
||||
UU_MAKE_PROFILE=debug bash util/build-gnu.sh
|
||||
- name: Run GNU tests
|
||||
|
|
218
Cargo.lock
generated
218
Cargo.lock
generated
|
@ -326,7 +326,7 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
|||
|
||||
[[package]]
|
||||
name = "coreutils"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
|
@ -1633,9 +1633,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
|||
|
||||
[[package]]
|
||||
name = "platform-info"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4278b2b54a23c9a91d5bae9b09e21d566f8b23890491951160b05d64f29d1d8b"
|
||||
checksum = "4e7c23cfae725ae06d9e43010153fa77bdfa8c827bf08fe4beeb2a3514e6be12"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
|
@ -2328,7 +2328,7 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
|||
|
||||
[[package]]
|
||||
name = "uu_arch"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"platform-info",
|
||||
|
@ -2337,7 +2337,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_base32"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2345,7 +2345,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_base64"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"uu_base32",
|
||||
"uucore",
|
||||
|
@ -2353,7 +2353,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_basename"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2361,7 +2361,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_basenc"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uu_base32",
|
||||
|
@ -2370,7 +2370,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_cat"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
|
@ -2381,7 +2381,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_chcon"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"fts-sys",
|
||||
|
@ -2393,7 +2393,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_chgrp"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2401,7 +2401,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_chmod"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2410,7 +2410,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_chown"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2418,7 +2418,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_chroot"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2426,7 +2426,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_cksum"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2434,7 +2434,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_comm"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2442,7 +2442,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_cp"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"exacl",
|
||||
|
@ -2458,7 +2458,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_csplit"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"regex",
|
||||
|
@ -2468,7 +2468,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_cut"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bstr",
|
||||
|
@ -2479,7 +2479,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_date"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
|
@ -2490,7 +2490,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_dd"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"gcd",
|
||||
|
@ -2501,7 +2501,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_df"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"unicode-width",
|
||||
|
@ -2510,7 +2510,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_dir"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uu_ls",
|
||||
|
@ -2519,7 +2519,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_dircolors"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2527,7 +2527,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_dirname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2535,7 +2535,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_du"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
|
@ -2546,7 +2546,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_echo"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2554,7 +2554,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_env"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nix",
|
||||
|
@ -2564,7 +2564,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_expand"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"unicode-width",
|
||||
|
@ -2573,7 +2573,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_expr"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"num-bigint",
|
||||
|
@ -2584,7 +2584,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_factor"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"coz",
|
||||
|
@ -2598,7 +2598,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_false"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2606,7 +2606,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_fmt"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"unicode-width",
|
||||
|
@ -2615,7 +2615,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_fold"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2623,7 +2623,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_groups"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2631,7 +2631,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_hashsum"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"blake3",
|
||||
|
@ -2649,7 +2649,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_head"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"memchr",
|
||||
|
@ -2658,7 +2658,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_hostid"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2667,7 +2667,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_hostname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"hostname",
|
||||
|
@ -2677,7 +2677,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_id"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"selinux",
|
||||
|
@ -2686,7 +2686,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_install"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"file_diff",
|
||||
|
@ -2698,7 +2698,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_join"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"memchr",
|
||||
|
@ -2707,7 +2707,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_kill"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nix",
|
||||
|
@ -2716,7 +2716,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_link"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2724,7 +2724,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_ln"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2732,7 +2732,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_logname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2741,7 +2741,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_ls"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
|
@ -2759,7 +2759,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_mkdir"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2767,7 +2767,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_mkfifo"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2776,7 +2776,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_mknod"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2785,7 +2785,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_mktemp"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"rand",
|
||||
|
@ -2795,7 +2795,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_more"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
|
@ -2808,7 +2808,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_mv"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"fs_extra",
|
||||
|
@ -2818,7 +2818,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_nice"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2828,7 +2828,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_nl"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"regex",
|
||||
|
@ -2837,7 +2837,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_nohup"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
|
@ -2847,7 +2847,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_nproc"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2857,7 +2857,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_numfmt"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2865,7 +2865,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_od"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"clap",
|
||||
|
@ -2875,7 +2875,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_paste"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2883,7 +2883,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_pathchk"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2892,7 +2892,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_pinky"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2900,7 +2900,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_pr"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"itertools",
|
||||
|
@ -2912,7 +2912,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_printenv"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2920,7 +2920,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_printf"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2928,7 +2928,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_ptx"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"regex",
|
||||
|
@ -2937,7 +2937,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_pwd"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2945,7 +2945,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_readlink"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2953,7 +2953,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_realpath"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2961,7 +2961,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_relpath"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -2969,7 +2969,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_rm"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2981,7 +2981,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_rmdir"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -2990,7 +2990,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_runcon"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3001,7 +3001,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_seq"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"clap",
|
||||
|
@ -3012,7 +3012,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_shred"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"rand",
|
||||
|
@ -3021,7 +3021,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_shuf"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"memchr",
|
||||
|
@ -3032,7 +3032,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_sleep"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3040,7 +3040,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_sort"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"binary-heap-plus",
|
||||
"clap",
|
||||
|
@ -3059,7 +3059,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_split"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"memchr",
|
||||
|
@ -3068,7 +3068,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_stat"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3076,7 +3076,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_stdbuf"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"tempfile",
|
||||
|
@ -3086,7 +3086,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_stdbuf_libstdbuf"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"cpp",
|
||||
"cpp_build",
|
||||
|
@ -3096,7 +3096,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_stty"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nix",
|
||||
|
@ -3105,7 +3105,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_sum"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3113,7 +3113,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_sync"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3124,7 +3124,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tac"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"memchr",
|
||||
|
@ -3135,7 +3135,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tail"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
|
@ -3151,7 +3151,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tee"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3161,7 +3161,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_test"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3171,7 +3171,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_timeout"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3181,7 +3181,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_touch"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"filetime",
|
||||
|
@ -3192,7 +3192,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tr"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"nom",
|
||||
|
@ -3201,7 +3201,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_true"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3209,7 +3209,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_truncate"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3217,7 +3217,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tsort"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3225,7 +3225,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_tty"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
|
@ -3235,7 +3235,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_uname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"platform-info",
|
||||
|
@ -3244,7 +3244,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_unexpand"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"unicode-width",
|
||||
|
@ -3253,7 +3253,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_uniq"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"strum",
|
||||
|
@ -3263,7 +3263,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_unlink"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3271,7 +3271,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_uptime"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
|
@ -3280,7 +3280,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_users"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3288,7 +3288,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_vdir"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uu_ls",
|
||||
|
@ -3297,7 +3297,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_wc"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"bytecount",
|
||||
"clap",
|
||||
|
@ -3310,7 +3310,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_who"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"uucore",
|
||||
|
@ -3318,7 +3318,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_whoami"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3328,7 +3328,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uu_yes"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"libc",
|
||||
|
@ -3338,7 +3338,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uucore"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"data-encoding",
|
||||
|
@ -3363,7 +3363,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "uucore_procs"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
250
Cargo.toml
250
Cargo.toml
|
@ -5,7 +5,7 @@
|
|||
|
||||
[package]
|
||||
name = "coreutils"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust"
|
||||
|
@ -30,6 +30,20 @@ windows = [ "feat_os_windows" ]
|
|||
## project-specific feature shortcodes
|
||||
nightly = []
|
||||
test_unimplemented = []
|
||||
# * only build `uudoc` when `--feature uudoc` is activated
|
||||
uudoc = ["zip"]
|
||||
## features
|
||||
# "feat_acl" == enable support for ACLs (access control lists; by using`--features feat_acl`)
|
||||
# NOTE:
|
||||
# * On linux, the posix-acl/acl-sys crate requires `libacl` headers and shared library to be accessible in the C toolchain at compile time.
|
||||
# * On FreeBSD and macOS this is not required.
|
||||
feat_acl = ["cp/feat_acl"]
|
||||
# "feat_selinux" == enable support for SELinux Security Context (by using `--features feat_selinux`)
|
||||
# NOTE:
|
||||
# * The selinux(-sys) crate requires `libselinux` headers and shared library to be accessible in the C toolchain at compile time.
|
||||
# * Running a uutils compiled with `feat_selinux` requires an SELinux enabled Kernel at run time.
|
||||
feat_selinux = ["cp/selinux", "id/selinux", "ls/selinux", "selinux", "feat_require_selinux"]
|
||||
##
|
||||
## feature sets
|
||||
## (common/core and Tier1) feature sets
|
||||
# "feat_common_core" == baseline core set of utilities which can be built/run on most targets
|
||||
|
@ -115,13 +129,15 @@ feat_Tier1 = [
|
|||
"nproc",
|
||||
"sync",
|
||||
"touch",
|
||||
"uname",
|
||||
"whoami",
|
||||
]
|
||||
## (primary platforms) feature sets
|
||||
# "feat_os_macos" == set of utilities which can be built/run on the MacOS platform
|
||||
feat_os_macos = [
|
||||
"feat_os_unix", ## == a modern/usual *nix platform
|
||||
"feat_require_hostid",
|
||||
#
|
||||
"feat_require_unix_hostid",
|
||||
]
|
||||
# "feat_os_unix" == set of utilities which can be built/run on modern/usual *nix platforms
|
||||
feat_os_unix = [
|
||||
|
@ -141,31 +157,21 @@ feat_os_unix_gnueabihf = [
|
|||
"feat_Tier1",
|
||||
#
|
||||
"feat_require_unix",
|
||||
"feat_require_unix_hostid",
|
||||
"feat_require_unix_utmpx",
|
||||
"feat_require_hostid",
|
||||
]
|
||||
# "feat_os_unix_musl" == set of utilities which can be built/run on targets binding to the "musl" library (ref: <https://musl.libc.org/about.html>)
|
||||
feat_os_unix_musl = [
|
||||
"feat_Tier1",
|
||||
#
|
||||
"feat_require_unix",
|
||||
"feat_require_hostid",
|
||||
"feat_require_unix_hostid",
|
||||
]
|
||||
feat_os_unix_android = [
|
||||
"feat_Tier1",
|
||||
#
|
||||
"feat_require_unix",
|
||||
]
|
||||
# "feat_selinux" == set of utilities providing support for SELinux Security Context if enabled with `--features feat_selinux`.
|
||||
# NOTE:
|
||||
# The selinux(-sys) crate requires `libselinux` headers and shared library to be accessible in the C toolchain at compile time.
|
||||
# Running a uutils compiled with `feat_selinux` requires an SELinux enabled Kernel at run time.
|
||||
feat_selinux = ["cp/selinux", "id/selinux", "ls/selinux", "selinux", "feat_require_selinux"]
|
||||
# "feat_acl" == set of utilities providing support for acl (access control lists) if enabled with `--features feat_acl`.
|
||||
# NOTE:
|
||||
# On linux, the posix-acl/acl-sys crate requires `libacl` headers and shared library to be accessible in the C toolchain at compile time.
|
||||
# On FreeBSD and macOS this is not required.
|
||||
feat_acl = ["cp/feat_acl"]
|
||||
## feature sets with requirements (restricting cross-platform availability)
|
||||
#
|
||||
# ** NOTE: these `feat_require_...` sets should be minimized as much as possible to encourage cross-platform availability of utilities
|
||||
|
@ -194,7 +200,6 @@ feat_require_unix = [
|
|||
"stty",
|
||||
"timeout",
|
||||
"tty",
|
||||
"uname",
|
||||
]
|
||||
# "feat_require_unix_utmpx" == set of utilities requiring unix utmp/utmpx support
|
||||
# * ref: <https://wiki.musl-libc.org/faq.html#Q:-Why-is-the-utmp/wtmp-functionality-only-implemented-as-stubs?>
|
||||
|
@ -204,8 +209,8 @@ feat_require_unix_utmpx = [
|
|||
"users",
|
||||
"who",
|
||||
]
|
||||
# "feat_require_hostid" == set of utilities requiring gethostid in libc (only some unixes provide)
|
||||
feat_require_hostid = [
|
||||
# "feat_require_unix_hostid" == set of utilities requiring gethostid in libc (only some unixes provide)
|
||||
feat_require_unix_hostid = [
|
||||
"hostid",
|
||||
]
|
||||
# "feat_require_selinux" == set of utilities depending on SELinux.
|
||||
|
@ -256,7 +261,6 @@ feat_os_windows_legacy = [
|
|||
##
|
||||
# * bypass/override ~ translate 'test' feature name to avoid dependency collision with rust core 'test' crate (o/w surfaces as compiler errors during testing)
|
||||
test = [ "uu_test" ]
|
||||
uudoc = [ "zip" ]
|
||||
|
||||
[workspace]
|
||||
|
||||
|
@ -267,113 +271,113 @@ once_cell = "1.13.1"
|
|||
phf = "0.11.1"
|
||||
selinux = { version="0.3", optional = true }
|
||||
textwrap = { version="0.16.0", features=["terminal_size"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="src/uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="src/uucore" }
|
||||
zip = { version = "0.6.3", optional=true, default_features=false, features=["deflate"] }
|
||||
# * uutils
|
||||
uu_test = { optional=true, version="0.0.16", package="uu_test", path="src/uu/test" }
|
||||
uu_test = { optional=true, version="0.0.17", package="uu_test", path="src/uu/test" }
|
||||
#
|
||||
arch = { optional=true, version="0.0.16", package="uu_arch", path="src/uu/arch" }
|
||||
base32 = { optional=true, version="0.0.16", package="uu_base32", path="src/uu/base32" }
|
||||
base64 = { optional=true, version="0.0.16", package="uu_base64", path="src/uu/base64" }
|
||||
basename = { optional=true, version="0.0.16", package="uu_basename", path="src/uu/basename" }
|
||||
basenc = { optional=true, version="0.0.16", package="uu_basenc", path="src/uu/basenc" }
|
||||
cat = { optional=true, version="0.0.16", package="uu_cat", path="src/uu/cat" }
|
||||
chcon = { optional=true, version="0.0.16", package="uu_chcon", path="src/uu/chcon" }
|
||||
chgrp = { optional=true, version="0.0.16", package="uu_chgrp", path="src/uu/chgrp" }
|
||||
chmod = { optional=true, version="0.0.16", package="uu_chmod", path="src/uu/chmod" }
|
||||
chown = { optional=true, version="0.0.16", package="uu_chown", path="src/uu/chown" }
|
||||
chroot = { optional=true, version="0.0.16", package="uu_chroot", path="src/uu/chroot" }
|
||||
cksum = { optional=true, version="0.0.16", package="uu_cksum", path="src/uu/cksum" }
|
||||
comm = { optional=true, version="0.0.16", package="uu_comm", path="src/uu/comm" }
|
||||
cp = { optional=true, version="0.0.16", package="uu_cp", path="src/uu/cp" }
|
||||
csplit = { optional=true, version="0.0.16", package="uu_csplit", path="src/uu/csplit" }
|
||||
cut = { optional=true, version="0.0.16", package="uu_cut", path="src/uu/cut" }
|
||||
date = { optional=true, version="0.0.16", package="uu_date", path="src/uu/date" }
|
||||
dd = { optional=true, version="0.0.16", package="uu_dd", path="src/uu/dd" }
|
||||
df = { optional=true, version="0.0.16", package="uu_df", path="src/uu/df" }
|
||||
dir = { optional=true, version="0.0.16", package="uu_dir", path="src/uu/dir" }
|
||||
dircolors= { optional=true, version="0.0.16", package="uu_dircolors", path="src/uu/dircolors" }
|
||||
dirname = { optional=true, version="0.0.16", package="uu_dirname", path="src/uu/dirname" }
|
||||
du = { optional=true, version="0.0.16", package="uu_du", path="src/uu/du" }
|
||||
echo = { optional=true, version="0.0.16", package="uu_echo", path="src/uu/echo" }
|
||||
env = { optional=true, version="0.0.16", package="uu_env", path="src/uu/env" }
|
||||
expand = { optional=true, version="0.0.16", package="uu_expand", path="src/uu/expand" }
|
||||
expr = { optional=true, version="0.0.16", package="uu_expr", path="src/uu/expr" }
|
||||
factor = { optional=true, version="0.0.16", package="uu_factor", path="src/uu/factor" }
|
||||
false = { optional=true, version="0.0.16", package="uu_false", path="src/uu/false" }
|
||||
fmt = { optional=true, version="0.0.16", package="uu_fmt", path="src/uu/fmt" }
|
||||
fold = { optional=true, version="0.0.16", package="uu_fold", path="src/uu/fold" }
|
||||
groups = { optional=true, version="0.0.16", package="uu_groups", path="src/uu/groups" }
|
||||
hashsum = { optional=true, version="0.0.16", package="uu_hashsum", path="src/uu/hashsum" }
|
||||
head = { optional=true, version="0.0.16", package="uu_head", path="src/uu/head" }
|
||||
hostid = { optional=true, version="0.0.16", package="uu_hostid", path="src/uu/hostid" }
|
||||
hostname = { optional=true, version="0.0.16", package="uu_hostname", path="src/uu/hostname" }
|
||||
id = { optional=true, version="0.0.16", package="uu_id", path="src/uu/id" }
|
||||
install = { optional=true, version="0.0.16", package="uu_install", path="src/uu/install" }
|
||||
join = { optional=true, version="0.0.16", package="uu_join", path="src/uu/join" }
|
||||
kill = { optional=true, version="0.0.16", package="uu_kill", path="src/uu/kill" }
|
||||
link = { optional=true, version="0.0.16", package="uu_link", path="src/uu/link" }
|
||||
ln = { optional=true, version="0.0.16", package="uu_ln", path="src/uu/ln" }
|
||||
ls = { optional=true, version="0.0.16", package="uu_ls", path="src/uu/ls" }
|
||||
logname = { optional=true, version="0.0.16", package="uu_logname", path="src/uu/logname" }
|
||||
mkdir = { optional=true, version="0.0.16", package="uu_mkdir", path="src/uu/mkdir" }
|
||||
mkfifo = { optional=true, version="0.0.16", package="uu_mkfifo", path="src/uu/mkfifo" }
|
||||
mknod = { optional=true, version="0.0.16", package="uu_mknod", path="src/uu/mknod" }
|
||||
mktemp = { optional=true, version="0.0.16", package="uu_mktemp", path="src/uu/mktemp" }
|
||||
more = { optional=true, version="0.0.16", package="uu_more", path="src/uu/more" }
|
||||
mv = { optional=true, version="0.0.16", package="uu_mv", path="src/uu/mv" }
|
||||
nice = { optional=true, version="0.0.16", package="uu_nice", path="src/uu/nice" }
|
||||
nl = { optional=true, version="0.0.16", package="uu_nl", path="src/uu/nl" }
|
||||
nohup = { optional=true, version="0.0.16", package="uu_nohup", path="src/uu/nohup" }
|
||||
nproc = { optional=true, version="0.0.16", package="uu_nproc", path="src/uu/nproc" }
|
||||
numfmt = { optional=true, version="0.0.16", package="uu_numfmt", path="src/uu/numfmt" }
|
||||
od = { optional=true, version="0.0.16", package="uu_od", path="src/uu/od" }
|
||||
paste = { optional=true, version="0.0.16", package="uu_paste", path="src/uu/paste" }
|
||||
pathchk = { optional=true, version="0.0.16", package="uu_pathchk", path="src/uu/pathchk" }
|
||||
pinky = { optional=true, version="0.0.16", package="uu_pinky", path="src/uu/pinky" }
|
||||
pr = { optional=true, version="0.0.16", package="uu_pr", path="src/uu/pr" }
|
||||
printenv = { optional=true, version="0.0.16", package="uu_printenv", path="src/uu/printenv" }
|
||||
printf = { optional=true, version="0.0.16", package="uu_printf", path="src/uu/printf" }
|
||||
ptx = { optional=true, version="0.0.16", package="uu_ptx", path="src/uu/ptx" }
|
||||
pwd = { optional=true, version="0.0.16", package="uu_pwd", path="src/uu/pwd" }
|
||||
readlink = { optional=true, version="0.0.16", package="uu_readlink", path="src/uu/readlink" }
|
||||
realpath = { optional=true, version="0.0.16", package="uu_realpath", path="src/uu/realpath" }
|
||||
relpath = { optional=true, version="0.0.16", package="uu_relpath", path="src/uu/relpath" }
|
||||
rm = { optional=true, version="0.0.16", package="uu_rm", path="src/uu/rm" }
|
||||
rmdir = { optional=true, version="0.0.16", package="uu_rmdir", path="src/uu/rmdir" }
|
||||
runcon = { optional=true, version="0.0.16", package="uu_runcon", path="src/uu/runcon" }
|
||||
seq = { optional=true, version="0.0.16", package="uu_seq", path="src/uu/seq" }
|
||||
shred = { optional=true, version="0.0.16", package="uu_shred", path="src/uu/shred" }
|
||||
shuf = { optional=true, version="0.0.16", package="uu_shuf", path="src/uu/shuf" }
|
||||
sleep = { optional=true, version="0.0.16", package="uu_sleep", path="src/uu/sleep" }
|
||||
sort = { optional=true, version="0.0.16", package="uu_sort", path="src/uu/sort" }
|
||||
split = { optional=true, version="0.0.16", package="uu_split", path="src/uu/split" }
|
||||
stat = { optional=true, version="0.0.16", package="uu_stat", path="src/uu/stat" }
|
||||
stdbuf = { optional=true, version="0.0.16", package="uu_stdbuf", path="src/uu/stdbuf" }
|
||||
stty = { optional=true, version="0.0.16", package="uu_stty", path="src/uu/stty" }
|
||||
sum = { optional=true, version="0.0.16", package="uu_sum", path="src/uu/sum" }
|
||||
sync = { optional=true, version="0.0.16", package="uu_sync", path="src/uu/sync" }
|
||||
tac = { optional=true, version="0.0.16", package="uu_tac", path="src/uu/tac" }
|
||||
tail = { optional=true, version="0.0.16", package="uu_tail", path="src/uu/tail" }
|
||||
tee = { optional=true, version="0.0.16", package="uu_tee", path="src/uu/tee" }
|
||||
timeout = { optional=true, version="0.0.16", package="uu_timeout", path="src/uu/timeout" }
|
||||
touch = { optional=true, version="0.0.16", package="uu_touch", path="src/uu/touch" }
|
||||
tr = { optional=true, version="0.0.16", package="uu_tr", path="src/uu/tr" }
|
||||
true = { optional=true, version="0.0.16", package="uu_true", path="src/uu/true" }
|
||||
truncate = { optional=true, version="0.0.16", package="uu_truncate", path="src/uu/truncate" }
|
||||
tsort = { optional=true, version="0.0.16", package="uu_tsort", path="src/uu/tsort" }
|
||||
tty = { optional=true, version="0.0.16", package="uu_tty", path="src/uu/tty" }
|
||||
uname = { optional=true, version="0.0.16", package="uu_uname", path="src/uu/uname" }
|
||||
unexpand = { optional=true, version="0.0.16", package="uu_unexpand", path="src/uu/unexpand" }
|
||||
uniq = { optional=true, version="0.0.16", package="uu_uniq", path="src/uu/uniq" }
|
||||
unlink = { optional=true, version="0.0.16", package="uu_unlink", path="src/uu/unlink" }
|
||||
uptime = { optional=true, version="0.0.16", package="uu_uptime", path="src/uu/uptime" }
|
||||
users = { optional=true, version="0.0.16", package="uu_users", path="src/uu/users" }
|
||||
vdir = { optional=true, version="0.0.16", package="uu_vdir", path="src/uu/vdir" }
|
||||
wc = { optional=true, version="0.0.16", package="uu_wc", path="src/uu/wc" }
|
||||
who = { optional=true, version="0.0.16", package="uu_who", path="src/uu/who" }
|
||||
whoami = { optional=true, version="0.0.16", package="uu_whoami", path="src/uu/whoami" }
|
||||
yes = { optional=true, version="0.0.16", package="uu_yes", path="src/uu/yes" }
|
||||
arch = { optional=true, version="0.0.17", package="uu_arch", path="src/uu/arch" }
|
||||
base32 = { optional=true, version="0.0.17", package="uu_base32", path="src/uu/base32" }
|
||||
base64 = { optional=true, version="0.0.17", package="uu_base64", path="src/uu/base64" }
|
||||
basename = { optional=true, version="0.0.17", package="uu_basename", path="src/uu/basename" }
|
||||
basenc = { optional=true, version="0.0.17", package="uu_basenc", path="src/uu/basenc" }
|
||||
cat = { optional=true, version="0.0.17", package="uu_cat", path="src/uu/cat" }
|
||||
chcon = { optional=true, version="0.0.17", package="uu_chcon", path="src/uu/chcon" }
|
||||
chgrp = { optional=true, version="0.0.17", package="uu_chgrp", path="src/uu/chgrp" }
|
||||
chmod = { optional=true, version="0.0.17", package="uu_chmod", path="src/uu/chmod" }
|
||||
chown = { optional=true, version="0.0.17", package="uu_chown", path="src/uu/chown" }
|
||||
chroot = { optional=true, version="0.0.17", package="uu_chroot", path="src/uu/chroot" }
|
||||
cksum = { optional=true, version="0.0.17", package="uu_cksum", path="src/uu/cksum" }
|
||||
comm = { optional=true, version="0.0.17", package="uu_comm", path="src/uu/comm" }
|
||||
cp = { optional=true, version="0.0.17", package="uu_cp", path="src/uu/cp" }
|
||||
csplit = { optional=true, version="0.0.17", package="uu_csplit", path="src/uu/csplit" }
|
||||
cut = { optional=true, version="0.0.17", package="uu_cut", path="src/uu/cut" }
|
||||
date = { optional=true, version="0.0.17", package="uu_date", path="src/uu/date" }
|
||||
dd = { optional=true, version="0.0.17", package="uu_dd", path="src/uu/dd" }
|
||||
df = { optional=true, version="0.0.17", package="uu_df", path="src/uu/df" }
|
||||
dir = { optional=true, version="0.0.17", package="uu_dir", path="src/uu/dir" }
|
||||
dircolors= { optional=true, version="0.0.17", package="uu_dircolors", path="src/uu/dircolors" }
|
||||
dirname = { optional=true, version="0.0.17", package="uu_dirname", path="src/uu/dirname" }
|
||||
du = { optional=true, version="0.0.17", package="uu_du", path="src/uu/du" }
|
||||
echo = { optional=true, version="0.0.17", package="uu_echo", path="src/uu/echo" }
|
||||
env = { optional=true, version="0.0.17", package="uu_env", path="src/uu/env" }
|
||||
expand = { optional=true, version="0.0.17", package="uu_expand", path="src/uu/expand" }
|
||||
expr = { optional=true, version="0.0.17", package="uu_expr", path="src/uu/expr" }
|
||||
factor = { optional=true, version="0.0.17", package="uu_factor", path="src/uu/factor" }
|
||||
false = { optional=true, version="0.0.17", package="uu_false", path="src/uu/false" }
|
||||
fmt = { optional=true, version="0.0.17", package="uu_fmt", path="src/uu/fmt" }
|
||||
fold = { optional=true, version="0.0.17", package="uu_fold", path="src/uu/fold" }
|
||||
groups = { optional=true, version="0.0.17", package="uu_groups", path="src/uu/groups" }
|
||||
hashsum = { optional=true, version="0.0.17", package="uu_hashsum", path="src/uu/hashsum" }
|
||||
head = { optional=true, version="0.0.17", package="uu_head", path="src/uu/head" }
|
||||
hostid = { optional=true, version="0.0.17", package="uu_hostid", path="src/uu/hostid" }
|
||||
hostname = { optional=true, version="0.0.17", package="uu_hostname", path="src/uu/hostname" }
|
||||
id = { optional=true, version="0.0.17", package="uu_id", path="src/uu/id" }
|
||||
install = { optional=true, version="0.0.17", package="uu_install", path="src/uu/install" }
|
||||
join = { optional=true, version="0.0.17", package="uu_join", path="src/uu/join" }
|
||||
kill = { optional=true, version="0.0.17", package="uu_kill", path="src/uu/kill" }
|
||||
link = { optional=true, version="0.0.17", package="uu_link", path="src/uu/link" }
|
||||
ln = { optional=true, version="0.0.17", package="uu_ln", path="src/uu/ln" }
|
||||
ls = { optional=true, version="0.0.17", package="uu_ls", path="src/uu/ls" }
|
||||
logname = { optional=true, version="0.0.17", package="uu_logname", path="src/uu/logname" }
|
||||
mkdir = { optional=true, version="0.0.17", package="uu_mkdir", path="src/uu/mkdir" }
|
||||
mkfifo = { optional=true, version="0.0.17", package="uu_mkfifo", path="src/uu/mkfifo" }
|
||||
mknod = { optional=true, version="0.0.17", package="uu_mknod", path="src/uu/mknod" }
|
||||
mktemp = { optional=true, version="0.0.17", package="uu_mktemp", path="src/uu/mktemp" }
|
||||
more = { optional=true, version="0.0.17", package="uu_more", path="src/uu/more" }
|
||||
mv = { optional=true, version="0.0.17", package="uu_mv", path="src/uu/mv" }
|
||||
nice = { optional=true, version="0.0.17", package="uu_nice", path="src/uu/nice" }
|
||||
nl = { optional=true, version="0.0.17", package="uu_nl", path="src/uu/nl" }
|
||||
nohup = { optional=true, version="0.0.17", package="uu_nohup", path="src/uu/nohup" }
|
||||
nproc = { optional=true, version="0.0.17", package="uu_nproc", path="src/uu/nproc" }
|
||||
numfmt = { optional=true, version="0.0.17", package="uu_numfmt", path="src/uu/numfmt" }
|
||||
od = { optional=true, version="0.0.17", package="uu_od", path="src/uu/od" }
|
||||
paste = { optional=true, version="0.0.17", package="uu_paste", path="src/uu/paste" }
|
||||
pathchk = { optional=true, version="0.0.17", package="uu_pathchk", path="src/uu/pathchk" }
|
||||
pinky = { optional=true, version="0.0.17", package="uu_pinky", path="src/uu/pinky" }
|
||||
pr = { optional=true, version="0.0.17", package="uu_pr", path="src/uu/pr" }
|
||||
printenv = { optional=true, version="0.0.17", package="uu_printenv", path="src/uu/printenv" }
|
||||
printf = { optional=true, version="0.0.17", package="uu_printf", path="src/uu/printf" }
|
||||
ptx = { optional=true, version="0.0.17", package="uu_ptx", path="src/uu/ptx" }
|
||||
pwd = { optional=true, version="0.0.17", package="uu_pwd", path="src/uu/pwd" }
|
||||
readlink = { optional=true, version="0.0.17", package="uu_readlink", path="src/uu/readlink" }
|
||||
realpath = { optional=true, version="0.0.17", package="uu_realpath", path="src/uu/realpath" }
|
||||
relpath = { optional=true, version="0.0.17", package="uu_relpath", path="src/uu/relpath" }
|
||||
rm = { optional=true, version="0.0.17", package="uu_rm", path="src/uu/rm" }
|
||||
rmdir = { optional=true, version="0.0.17", package="uu_rmdir", path="src/uu/rmdir" }
|
||||
runcon = { optional=true, version="0.0.17", package="uu_runcon", path="src/uu/runcon" }
|
||||
seq = { optional=true, version="0.0.17", package="uu_seq", path="src/uu/seq" }
|
||||
shred = { optional=true, version="0.0.17", package="uu_shred", path="src/uu/shred" }
|
||||
shuf = { optional=true, version="0.0.17", package="uu_shuf", path="src/uu/shuf" }
|
||||
sleep = { optional=true, version="0.0.17", package="uu_sleep", path="src/uu/sleep" }
|
||||
sort = { optional=true, version="0.0.17", package="uu_sort", path="src/uu/sort" }
|
||||
split = { optional=true, version="0.0.17", package="uu_split", path="src/uu/split" }
|
||||
stat = { optional=true, version="0.0.17", package="uu_stat", path="src/uu/stat" }
|
||||
stdbuf = { optional=true, version="0.0.17", package="uu_stdbuf", path="src/uu/stdbuf" }
|
||||
stty = { optional=true, version="0.0.17", package="uu_stty", path="src/uu/stty" }
|
||||
sum = { optional=true, version="0.0.17", package="uu_sum", path="src/uu/sum" }
|
||||
sync = { optional=true, version="0.0.17", package="uu_sync", path="src/uu/sync" }
|
||||
tac = { optional=true, version="0.0.17", package="uu_tac", path="src/uu/tac" }
|
||||
tail = { optional=true, version="0.0.17", package="uu_tail", path="src/uu/tail" }
|
||||
tee = { optional=true, version="0.0.17", package="uu_tee", path="src/uu/tee" }
|
||||
timeout = { optional=true, version="0.0.17", package="uu_timeout", path="src/uu/timeout" }
|
||||
touch = { optional=true, version="0.0.17", package="uu_touch", path="src/uu/touch" }
|
||||
tr = { optional=true, version="0.0.17", package="uu_tr", path="src/uu/tr" }
|
||||
true = { optional=true, version="0.0.17", package="uu_true", path="src/uu/true" }
|
||||
truncate = { optional=true, version="0.0.17", package="uu_truncate", path="src/uu/truncate" }
|
||||
tsort = { optional=true, version="0.0.17", package="uu_tsort", path="src/uu/tsort" }
|
||||
tty = { optional=true, version="0.0.17", package="uu_tty", path="src/uu/tty" }
|
||||
uname = { optional=true, version="0.0.17", package="uu_uname", path="src/uu/uname" }
|
||||
unexpand = { optional=true, version="0.0.17", package="uu_unexpand", path="src/uu/unexpand" }
|
||||
uniq = { optional=true, version="0.0.17", package="uu_uniq", path="src/uu/uniq" }
|
||||
unlink = { optional=true, version="0.0.17", package="uu_unlink", path="src/uu/unlink" }
|
||||
uptime = { optional=true, version="0.0.17", package="uu_uptime", path="src/uu/uptime" }
|
||||
users = { optional=true, version="0.0.17", package="uu_users", path="src/uu/users" }
|
||||
vdir = { optional=true, version="0.0.17", package="uu_vdir", path="src/uu/vdir" }
|
||||
wc = { optional=true, version="0.0.17", package="uu_wc", path="src/uu/wc" }
|
||||
who = { optional=true, version="0.0.17", package="uu_who", path="src/uu/who" }
|
||||
whoami = { optional=true, version="0.0.17", package="uu_whoami", path="src/uu/whoami" }
|
||||
yes = { optional=true, version="0.0.17", package="uu_yes", path="src/uu/yes" }
|
||||
|
||||
# this breaks clippy linting with: "tests/by-util/test_factor_benches.rs: No such file or directory (os error 2)"
|
||||
# factor_benches = { optional = true, version = "0.0.0", package = "uu_factor_benches", path = "tests/benches/factor" }
|
||||
|
@ -396,7 +400,7 @@ sha1 = { version="0.10", features=["std"] }
|
|||
tempfile = "3"
|
||||
time = {version="0.3", features=["local-offset"]}
|
||||
unindent = "0.1"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="src/uucore", features=["entries", "process"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="src/uucore", features=["entries", "process", "signals"] }
|
||||
walkdir = "2.2"
|
||||
atty = "0.2"
|
||||
hex-literal = "0.3.1"
|
||||
|
|
|
@ -33,3 +33,7 @@ We provide a simple implementation of `more`, which is not part of GNU
|
|||
coreutils. We do not aim for full compatibility with the `more` utility from
|
||||
`util-linux`. Features from more modern pagers (like `less` and `bat`) are
|
||||
therefore welcomed.
|
||||
|
||||
## `cut`
|
||||
|
||||
`cut` can separate fields by whitespace (Space and Tab) with `-w` flag. This feature is adopted from [FreeBSD](https://www.freebsd.org/cgi/man.cgi?cut).
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_arch"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "arch ~ (uutils) display machine architecture"
|
||||
|
@ -15,9 +15,9 @@ edition = "2021"
|
|||
path = "src/arch.rs"
|
||||
|
||||
[dependencies]
|
||||
platform-info = "1.0.1"
|
||||
platform-info = "1.0.2"
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "arch"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_base32"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "base32 ~ (uutils) decode/encode input (base32-encoding)"
|
||||
|
@ -16,7 +16,7 @@ path = "src/base32.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
|
||||
[[bin]]
|
||||
name = "base32"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_base64"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "base64 ~ (uutils) decode/encode input (base64-encoding)"
|
||||
|
@ -15,8 +15,8 @@ edition = "2021"
|
|||
path = "src/base64.rs"
|
||||
|
||||
[dependencies]
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
uu_base32 = { version=">=0.0.16", package="uu_base32", path="../base32"}
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
uu_base32 = { version=">=0.0.17", package="uu_base32", path="../base32"}
|
||||
|
||||
[[bin]]
|
||||
name = "base64"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_basename"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "basename ~ (uutils) display PATHNAME with leading directory components removed"
|
||||
|
@ -16,7 +16,7 @@ path = "src/basename.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "basename"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_basenc"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "basenc ~ (uutils) decode/encode input"
|
||||
|
@ -16,8 +16,8 @@ path = "src/basenc.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
uu_base32 = { version=">=0.0.16", package="uu_base32", path="../base32"}
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features = ["encoding"] }
|
||||
uu_base32 = { version=">=0.0.17", package="uu_base32", path="../base32"}
|
||||
|
||||
[[bin]]
|
||||
name = "basenc"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_cat"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "cat ~ (uutils) concatenate and display input"
|
||||
|
@ -18,7 +18,7 @@ path = "src/cat.rs"
|
|||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
thiserror = "1.0"
|
||||
atty = "0.2"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs", "pipes"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["fs", "pipes"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
nix = { version = "0.25", default-features = false }
|
||||
|
|
|
@ -35,7 +35,6 @@ use std::os::unix::fs::FileTypeExt;
|
|||
use std::os::unix::net::UnixStream;
|
||||
use uucore::format_usage;
|
||||
|
||||
static NAME: &str = "cat";
|
||||
static USAGE: &str = "{} [OPTION]... [FILE]...";
|
||||
static ABOUT: &str = "Concatenate FILE(s), or standard input, to standard output
|
||||
With no FILE, or when FILE is -, read standard input.";
|
||||
|
@ -236,7 +235,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.override_usage(format_usage(USAGE))
|
||||
.about(ABOUT)
|
||||
|
@ -426,7 +424,7 @@ fn get_input_type(path: &str) -> CatResult<InputType> {
|
|||
ft if ft.is_file() => Ok(InputType::File),
|
||||
ft if ft.is_symlink() => Ok(InputType::SymLink),
|
||||
_ => Err(CatError::UnknownFiletype {
|
||||
ft_debug: format!("{:?}", ft),
|
||||
ft_debug: format!("{ft:?}"),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_chcon"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "chcon ~ (uutils) change file security context"
|
||||
|
|
|
@ -70,7 +70,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
return Err(r.into());
|
||||
}
|
||||
|
||||
return Err(UUsageError::new(libc::EXIT_FAILURE, format!("{}.\n", r)));
|
||||
return Err(UUsageError::new(libc::EXIT_FAILURE, format!("{r}.\n")));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -67,10 +67,10 @@ impl Error {
|
|||
|
||||
pub(crate) fn report_full_error(mut err: &dyn std::error::Error) -> String {
|
||||
let mut desc = String::with_capacity(256);
|
||||
write!(desc, "{}", err).unwrap();
|
||||
write!(desc, "{err}").unwrap();
|
||||
while let Some(source) = err.source() {
|
||||
err = source;
|
||||
write!(desc, ". {}", err).unwrap();
|
||||
write!(desc, ". {err}").unwrap();
|
||||
}
|
||||
desc
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_chgrp"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "chgrp ~ (uutils) change the group ownership of FILE"
|
||||
|
@ -16,7 +16,7 @@ path = "src/chgrp.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||
|
||||
[[bin]]
|
||||
name = "chgrp"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_chmod"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "chmod ~ (uutils) change mode of FILE"
|
||||
|
@ -17,7 +17,7 @@ path = "src/chmod.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
libc = "0.2.137"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["fs", "mode"] }
|
||||
|
||||
[[bin]]
|
||||
name = "chmod"
|
||||
|
|
|
@ -75,7 +75,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
let modes = matches.get_one::<String>(options::MODE).unwrap(); // should always be Some because required
|
||||
let cmode = if mode_had_minus_prefix {
|
||||
// clap parsing is finished, now put prefix back
|
||||
format!("-{}", modes)
|
||||
format!("-{modes}")
|
||||
} else {
|
||||
modes.to_string()
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_chown"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "chown ~ (uutils) change the ownership of FILE"
|
||||
|
@ -16,7 +16,7 @@ path = "src/chown.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs", "perms"] }
|
||||
|
||||
[[bin]]
|
||||
name = "chown"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_chroot"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "chroot ~ (uutils) run COMMAND under a new root directory"
|
||||
|
@ -16,7 +16,7 @@ path = "src/chroot.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
|
||||
[[bin]]
|
||||
name = "chroot"
|
||||
|
|
|
@ -77,8 +77,8 @@ impl Display for ChrootError {
|
|||
"cannot change root directory to {}: no such directory",
|
||||
s.quote(),
|
||||
),
|
||||
Self::SetGidFailed(s, e) => write!(f, "cannot set gid to {}: {}", s, e),
|
||||
Self::SetGroupsFailed(e) => write!(f, "cannot set groups: {}", 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)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_cksum"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "cksum ~ (uutils) display CRC and size of input"
|
||||
|
@ -16,7 +16,7 @@ path = "src/cksum.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "cksum"
|
||||
|
|
|
@ -18,7 +18,6 @@ use uucore::{format_usage, show};
|
|||
const CRC_TABLE_LEN: usize = 256;
|
||||
const CRC_TABLE: [u32; CRC_TABLE_LEN] = generate_crc_table();
|
||||
|
||||
const NAME: &str = "cksum";
|
||||
const USAGE: &str = "{} [OPTIONS] [FILE]...";
|
||||
const ABOUT: &str = "Print CRC and size for each file";
|
||||
|
||||
|
@ -124,13 +123,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
if files.is_empty() {
|
||||
let (crc, size) = cksum("-")?;
|
||||
println!("{} {}", crc, size);
|
||||
println!("{crc} {size}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for fname in &files {
|
||||
match cksum(fname.as_ref()).map_err_context(|| format!("{}", fname.maybe_quote())) {
|
||||
Ok((crc, size)) => println!("{} {} {}", crc, size, fname),
|
||||
Ok((crc, size)) => println!("{crc} {size} {fname}"),
|
||||
Err(err) => show!(err),
|
||||
};
|
||||
}
|
||||
|
@ -139,7 +138,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_comm"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "comm ~ (uutils) compare sorted inputs"
|
||||
|
@ -16,7 +16,7 @@ path = "src/comm.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "comm"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_cp"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = [
|
||||
"Jordy Dickinson <jordy.dickinson@gmail.com>",
|
||||
"Joshua S. Miller <jsmiller@uchicago.edu>",
|
||||
|
@ -24,7 +24,7 @@ filetime = "0.2"
|
|||
libc = "0.2.137"
|
||||
quick-error = "2.0.1"
|
||||
selinux = { version="0.3", optional=true }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs", "perms", "mode"] }
|
||||
walkdir = "2.2"
|
||||
indicatif = "0.17"
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ pub(crate) fn copy_directory(
|
|||
// the target directory.
|
||||
let context = match Context::new(root, target) {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(format!("failed to get current directory {}", e).into()),
|
||||
Err(e) => return Err(format!("failed to get current directory {e}").into()),
|
||||
};
|
||||
|
||||
// Traverse the contents of the directory, copying each one.
|
||||
|
@ -405,7 +405,7 @@ pub(crate) fn copy_directory(
|
|||
}
|
||||
}
|
||||
// Copy the attributes from the root directory to the target directory.
|
||||
copy_attributes(root, target, &options.preserve_attributes)?;
|
||||
copy_attributes(root, target, &options.attributes)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ use std::os::unix::ffi::OsStrExt;
|
|||
#[cfg(unix)]
|
||||
use std::os::unix::fs::{FileTypeExt, PermissionsExt};
|
||||
use std::path::{Path, PathBuf, StripPrefixError};
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
|
||||
use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
|
||||
|
@ -33,6 +32,8 @@ use indicatif::{ProgressBar, ProgressStyle};
|
|||
#[cfg(unix)]
|
||||
use libc::mkfifo;
|
||||
use quick_error::ResultExt;
|
||||
|
||||
use platform::copy_on_write;
|
||||
use uucore::backup_control::{self, BackupMode};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{set_exit_code, UClapError, UError, UResult, UUsageError};
|
||||
|
@ -41,12 +42,10 @@ use uucore::fs::{
|
|||
};
|
||||
use uucore::{crash, format_usage, prompt_yes, show_error, show_warning};
|
||||
|
||||
mod copydir;
|
||||
use crate::copydir::copy_directory;
|
||||
|
||||
mod copydir;
|
||||
mod platform;
|
||||
use platform::copy_on_write;
|
||||
|
||||
quick_error! {
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
@ -157,18 +156,51 @@ pub enum CopyMode {
|
|||
AttrOnly,
|
||||
}
|
||||
|
||||
// The ordering here determines the order in which attributes are (re-)applied.
|
||||
// In particular, Ownership must be changed first to avoid interfering with mode change.
|
||||
#[derive(Clone, Eq, PartialEq, Debug, PartialOrd, Ord)]
|
||||
pub enum Attribute {
|
||||
#[derive(Debug)]
|
||||
pub struct Attributes {
|
||||
#[cfg(unix)]
|
||||
Ownership,
|
||||
Mode,
|
||||
Timestamps,
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
Context,
|
||||
Links,
|
||||
Xattr,
|
||||
ownership: Preserve,
|
||||
mode: Preserve,
|
||||
timestamps: Preserve,
|
||||
context: Preserve,
|
||||
links: Preserve,
|
||||
xattr: Preserve,
|
||||
}
|
||||
|
||||
impl Attributes {
|
||||
pub(crate) fn max(&mut self, other: Self) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
self.ownership = self.ownership.max(other.ownership);
|
||||
}
|
||||
self.mode = self.mode.max(other.mode);
|
||||
self.timestamps = self.timestamps.max(other.timestamps);
|
||||
self.context = self.context.max(other.context);
|
||||
self.links = self.links.max(other.links);
|
||||
self.xattr = self.xattr.max(other.xattr);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Preserve {
|
||||
No,
|
||||
Yes { required: bool },
|
||||
}
|
||||
|
||||
impl Preserve {
|
||||
/// Preservation level should only increase, with no preservation being the lowest option,
|
||||
/// preserve but don't require - middle, and preserve and require - top.
|
||||
pub(crate) fn max(&self, other: Self) -> Self {
|
||||
match (self, other) {
|
||||
(Self::Yes { required: true }, _) | (_, Self::Yes { required: true }) => {
|
||||
Self::Yes { required: true }
|
||||
}
|
||||
(Self::Yes { required: false }, _) | (_, Self::Yes { required: false }) => {
|
||||
Self::Yes { required: false }
|
||||
}
|
||||
_ => Self::No,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Re-usable, extensible copy options
|
||||
|
@ -187,7 +219,7 @@ pub struct Options {
|
|||
sparse_mode: SparseMode,
|
||||
strip_trailing_slashes: bool,
|
||||
reflink_mode: ReflinkMode,
|
||||
preserve_attributes: Vec<Attribute>,
|
||||
attributes: Attributes,
|
||||
recursive: bool,
|
||||
backup_suffix: String,
|
||||
target_dir: Option<String>,
|
||||
|
@ -243,7 +275,6 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[
|
|||
"mode",
|
||||
"ownership",
|
||||
"timestamps",
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
"context",
|
||||
"links",
|
||||
"xattr",
|
||||
|
@ -254,13 +285,6 @@ static PRESERVABLE_ATTRIBUTES: &[&str] = &[
|
|||
static PRESERVABLE_ATTRIBUTES: &[&str] =
|
||||
&["mode", "timestamps", "context", "links", "xattr", "all"];
|
||||
|
||||
static DEFAULT_ATTRIBUTES: &[Attribute] = &[
|
||||
Attribute::Mode,
|
||||
#[cfg(unix)]
|
||||
Attribute::Ownership,
|
||||
Attribute::Timestamps,
|
||||
];
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
const MODE_ARGS: &[&str] = &[
|
||||
options::LINK,
|
||||
|
@ -552,7 +576,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
clap::error::ErrorKind::DisplayHelp => {
|
||||
app.print_help()?;
|
||||
}
|
||||
clap::error::ErrorKind::DisplayVersion => println!("{}", app.render_version()),
|
||||
clap::error::ErrorKind::DisplayVersion => print!("{}", app.render_version()),
|
||||
_ => return Err(Box::new(e.with_exit_code(1))),
|
||||
};
|
||||
} else if let Ok(matches) = matches {
|
||||
|
@ -627,46 +651,79 @@ impl CopyMode {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromStr for Attribute {
|
||||
type Err = Error;
|
||||
impl Attributes {
|
||||
// TODO: ownership is required if the user is root, for non-root users it's not required.
|
||||
// See: https://github.com/coreutils/coreutils/blob/master/src/copy.c#L3181
|
||||
|
||||
fn from_str(value: &str) -> CopyResult<Self> {
|
||||
Ok(match &*value.to_lowercase() {
|
||||
"mode" => Self::Mode,
|
||||
fn all() -> Self {
|
||||
Self {
|
||||
#[cfg(unix)]
|
||||
"ownership" => Self::Ownership,
|
||||
"timestamps" => Self::Timestamps,
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
"context" => Self::Context,
|
||||
"links" => Self::Links,
|
||||
"xattr" => Self::Xattr,
|
||||
ownership: Preserve::Yes { required: true },
|
||||
mode: Preserve::Yes { required: true },
|
||||
timestamps: Preserve::Yes { required: true },
|
||||
context: {
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
{
|
||||
Preserve::Yes { required: false }
|
||||
}
|
||||
#[cfg(not(feature = "feat_selinux"))]
|
||||
{
|
||||
Preserve::No
|
||||
}
|
||||
},
|
||||
links: Preserve::Yes { required: true },
|
||||
xattr: Preserve::Yes { required: false },
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
#[cfg(unix)]
|
||||
ownership: Preserve::Yes { required: true },
|
||||
mode: Preserve::Yes { required: true },
|
||||
timestamps: Preserve::Yes { required: true },
|
||||
context: Preserve::No,
|
||||
links: Preserve::No,
|
||||
xattr: Preserve::No,
|
||||
}
|
||||
}
|
||||
|
||||
fn none() -> Self {
|
||||
Self {
|
||||
#[cfg(unix)]
|
||||
ownership: Preserve::No,
|
||||
mode: Preserve::No,
|
||||
timestamps: Preserve::No,
|
||||
context: Preserve::No,
|
||||
links: Preserve::No,
|
||||
xattr: Preserve::No,
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to match string containing a parameter to preserve with the corresponding entry in the
|
||||
/// Attributes struct.
|
||||
fn try_set_from_string(&mut self, value: &str) -> Result<(), Error> {
|
||||
let preserve_yes_required = Preserve::Yes { required: true };
|
||||
|
||||
match &*value.to_lowercase() {
|
||||
"mode" => self.mode = preserve_yes_required,
|
||||
#[cfg(unix)]
|
||||
"ownership" => self.ownership = preserve_yes_required,
|
||||
"timestamps" => self.timestamps = preserve_yes_required,
|
||||
"context" => self.context = preserve_yes_required,
|
||||
"links" => self.links = preserve_yes_required,
|
||||
"xattr" => self.xattr = preserve_yes_required,
|
||||
_ => {
|
||||
return Err(Error::InvalidArgument(format!(
|
||||
"invalid attribute {}",
|
||||
value.quote()
|
||||
)));
|
||||
}
|
||||
})
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn add_all_attributes() -> Vec<Attribute> {
|
||||
use Attribute::*;
|
||||
|
||||
let attr = vec![
|
||||
#[cfg(unix)]
|
||||
Ownership,
|
||||
Mode,
|
||||
Timestamps,
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
Context,
|
||||
Links,
|
||||
Xattr,
|
||||
];
|
||||
|
||||
attr
|
||||
}
|
||||
|
||||
impl Options {
|
||||
fn from_matches(matches: &ArgMatches) -> CopyResult<Self> {
|
||||
let not_implemented_opts = vec![
|
||||
|
@ -689,7 +746,7 @@ impl Options {
|
|||
let recursive = matches.get_flag(options::RECURSIVE) || matches.get_flag(options::ARCHIVE);
|
||||
|
||||
let backup_mode = match backup_control::determine_backup_mode(matches) {
|
||||
Err(e) => return Err(Error::Backup(format!("{}", e))),
|
||||
Err(e) => return Err(Error::Backup(format!("{e}"))),
|
||||
Ok(mode) => mode,
|
||||
};
|
||||
|
||||
|
@ -710,22 +767,23 @@ impl Options {
|
|||
};
|
||||
|
||||
// Parse attributes to preserve
|
||||
let mut preserve_attributes: Vec<Attribute> = if matches.contains_id(options::PRESERVE) {
|
||||
let attributes: Attributes = if matches.contains_id(options::PRESERVE) {
|
||||
match matches.get_many::<String>(options::PRESERVE) {
|
||||
None => DEFAULT_ATTRIBUTES.to_vec(),
|
||||
None => Attributes::default(),
|
||||
Some(attribute_strs) => {
|
||||
let mut attributes = Vec::new();
|
||||
let mut attributes: Attributes = Attributes::none();
|
||||
let mut attributes_empty = true;
|
||||
for attribute_str in attribute_strs {
|
||||
attributes_empty = false;
|
||||
if attribute_str == "all" {
|
||||
attributes = add_all_attributes();
|
||||
break;
|
||||
attributes.max(Attributes::all());
|
||||
} else {
|
||||
attributes.push(Attribute::from_str(attribute_str)?);
|
||||
attributes.try_set_from_string(attribute_str)?;
|
||||
}
|
||||
}
|
||||
// `--preserve` case, use the defaults
|
||||
if attributes.is_empty() {
|
||||
DEFAULT_ATTRIBUTES.to_vec()
|
||||
if attributes_empty {
|
||||
Attributes::default()
|
||||
} else {
|
||||
attributes
|
||||
}
|
||||
|
@ -733,19 +791,27 @@ impl Options {
|
|||
}
|
||||
} else if matches.get_flag(options::ARCHIVE) {
|
||||
// --archive is used. Same as --preserve=all
|
||||
add_all_attributes()
|
||||
Attributes::all()
|
||||
} else if matches.get_flag(options::NO_DEREFERENCE_PRESERVE_LINKS) {
|
||||
vec![Attribute::Links]
|
||||
let mut attributes = Attributes::none();
|
||||
attributes.links = Preserve::Yes { required: true };
|
||||
attributes
|
||||
} else if matches.get_flag(options::PRESERVE_DEFAULT_ATTRIBUTES) {
|
||||
DEFAULT_ATTRIBUTES.to_vec()
|
||||
Attributes::default()
|
||||
} else {
|
||||
vec![]
|
||||
Attributes::none()
|
||||
};
|
||||
|
||||
// Make sure ownership is changed before other attributes,
|
||||
// as chown clears some of the permission and therefore could undo previous changes
|
||||
// if not executed first.
|
||||
preserve_attributes.sort_unstable();
|
||||
#[cfg(not(feature = "feat_selinux"))]
|
||||
if let Preserve::Yes { required } = attributes.context {
|
||||
let selinux_disabled_error =
|
||||
Error::Error("SELinux was not enabled during the compile time!".to_string());
|
||||
if required {
|
||||
return Err(selinux_disabled_error);
|
||||
} else {
|
||||
show_error_if_needed(&selinux_disabled_error);
|
||||
}
|
||||
}
|
||||
|
||||
let options = Self {
|
||||
attributes_only: matches.get_flag(options::ATTRIBUTES_ONLY),
|
||||
|
@ -799,9 +865,8 @@ impl Options {
|
|||
"never" => SparseMode::Never,
|
||||
_ => {
|
||||
return Err(Error::InvalidArgument(format!(
|
||||
"invalid argument {} for \'sparse\'",
|
||||
val
|
||||
)))
|
||||
"invalid argument {val} for \'sparse\'"
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -812,7 +877,7 @@ impl Options {
|
|||
backup_suffix,
|
||||
overwrite,
|
||||
no_target_dir,
|
||||
preserve_attributes,
|
||||
attributes,
|
||||
recursive,
|
||||
target_dir,
|
||||
progress_bar: matches.get_flag(options::PROGRESS_BAR),
|
||||
|
@ -826,12 +891,10 @@ impl Options {
|
|||
}
|
||||
|
||||
fn preserve_hard_links(&self) -> bool {
|
||||
for attribute in &self.preserve_attributes {
|
||||
if *attribute == Attribute::Links {
|
||||
return true;
|
||||
}
|
||||
match self.attributes.links {
|
||||
Preserve::No => false,
|
||||
Preserve::Yes { .. } => true,
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether to force overwriting the destination file.
|
||||
|
@ -951,6 +1014,22 @@ fn preserve_hardlinks(
|
|||
Ok(found_hard_link)
|
||||
}
|
||||
|
||||
/// When handling errors, we don't always want to show them to the user. This function handles that.
|
||||
/// If the error is printed, returns true, false otherwise.
|
||||
fn show_error_if_needed(error: &Error) -> bool {
|
||||
match error {
|
||||
// When using --no-clobber, we don't want to show
|
||||
// an error message
|
||||
Error::NotAllFilesCopied => (),
|
||||
Error::Skipped => (),
|
||||
_ => {
|
||||
show_error!("{}", error);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Copy all `sources` to `target`. Returns an
|
||||
/// `Err(Error::NotAllFilesCopied)` if at least one non-fatal error was
|
||||
/// encountered.
|
||||
|
@ -1005,15 +1084,8 @@ fn copy(sources: &[Source], target: &TargetSlice, options: &Options) -> CopyResu
|
|||
options,
|
||||
&mut symlinked_files,
|
||||
) {
|
||||
match error {
|
||||
// When using --no-clobber, we don't want to show
|
||||
// an error message
|
||||
Error::NotAllFilesCopied => (),
|
||||
Error::Skipped => (),
|
||||
_ => {
|
||||
show_error!("{}", error);
|
||||
non_fatal_errors = true;
|
||||
}
|
||||
if show_error_if_needed(&error) {
|
||||
non_fatal_errors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1100,114 +1172,138 @@ impl OverwriteMode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Handles errors for attributes preservation. If the attribute is not required, and
|
||||
/// errored, tries to show error (see `show_error_if_needed` for additional behavior details).
|
||||
/// If it's required, then the error is thrown.
|
||||
fn handle_preserve<F: Fn() -> CopyResult<()>>(p: &Preserve, f: F) -> CopyResult<()> {
|
||||
match p {
|
||||
Preserve::No => {}
|
||||
Preserve::Yes { required } => {
|
||||
let result = f();
|
||||
if *required {
|
||||
result?;
|
||||
} else if let Err(error) = result {
|
||||
show_error_if_needed(&error);
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Copy the specified attributes from one path to another.
|
||||
pub(crate) fn copy_attributes(
|
||||
source: &Path,
|
||||
dest: &Path,
|
||||
attributes: &[Attribute],
|
||||
attributes: &Attributes,
|
||||
) -> CopyResult<()> {
|
||||
for attribute in attributes {
|
||||
copy_attribute(source, dest, attribute)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_attribute(source: &Path, dest: &Path, attribute: &Attribute) -> CopyResult<()> {
|
||||
let context = &*format!("{} -> {}", source.quote(), dest.quote());
|
||||
let source_metadata = fs::symlink_metadata(source).context(context)?;
|
||||
match *attribute {
|
||||
Attribute::Mode => {
|
||||
// The `chmod()` system call that underlies the
|
||||
// `fs::set_permissions()` call is unable to change the
|
||||
// permissions of a symbolic link. In that case, we just
|
||||
// do nothing, since every symbolic link has the same
|
||||
// permissions.
|
||||
if !dest.is_symlink() {
|
||||
fs::set_permissions(dest, source_metadata.permissions()).context(context)?;
|
||||
// FIXME: Implement this for windows as well
|
||||
#[cfg(feature = "feat_acl")]
|
||||
exacl::getfacl(source, None)
|
||||
.and_then(|acl| exacl::setfacl(&[dest], &acl, None))
|
||||
.map_err(|err| Error::Error(err.to_string()))?;
|
||||
}
|
||||
|
||||
// Ownership must be changed first to avoid interfering with mode change.
|
||||
#[cfg(unix)]
|
||||
handle_preserve(&attributes.ownership, || -> CopyResult<()> {
|
||||
use std::os::unix::prelude::MetadataExt;
|
||||
use uucore::perms::wrap_chown;
|
||||
use uucore::perms::Verbosity;
|
||||
use uucore::perms::VerbosityLevel;
|
||||
|
||||
let dest_uid = source_metadata.uid();
|
||||
let dest_gid = source_metadata.gid();
|
||||
|
||||
wrap_chown(
|
||||
dest,
|
||||
&dest.symlink_metadata().context(context)?,
|
||||
Some(dest_uid),
|
||||
Some(dest_gid),
|
||||
false,
|
||||
Verbosity {
|
||||
groups_only: false,
|
||||
level: VerbosityLevel::Normal,
|
||||
},
|
||||
)
|
||||
.map_err(Error::Error)?;
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
handle_preserve(&attributes.mode, || -> CopyResult<()> {
|
||||
// The `chmod()` system call that underlies the
|
||||
// `fs::set_permissions()` call is unable to change the
|
||||
// permissions of a symbolic link. In that case, we just
|
||||
// do nothing, since every symbolic link has the same
|
||||
// permissions.
|
||||
if !dest.is_symlink() {
|
||||
fs::set_permissions(dest, source_metadata.permissions()).context(context)?;
|
||||
// FIXME: Implement this for windows as well
|
||||
#[cfg(feature = "feat_acl")]
|
||||
exacl::getfacl(source, None)
|
||||
.and_then(|acl| exacl::setfacl(&[dest], &acl, None))
|
||||
.map_err(|err| Error::Error(err.to_string()))?;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
Attribute::Ownership => {
|
||||
use std::os::unix::prelude::MetadataExt;
|
||||
use uucore::perms::wrap_chown;
|
||||
use uucore::perms::Verbosity;
|
||||
use uucore::perms::VerbosityLevel;
|
||||
|
||||
let dest_uid = source_metadata.uid();
|
||||
let dest_gid = source_metadata.gid();
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
wrap_chown(
|
||||
dest,
|
||||
&dest.symlink_metadata().context(context)?,
|
||||
Some(dest_uid),
|
||||
Some(dest_gid),
|
||||
false,
|
||||
Verbosity {
|
||||
groups_only: false,
|
||||
level: VerbosityLevel::Normal,
|
||||
},
|
||||
handle_preserve(&attributes.timestamps, || -> CopyResult<()> {
|
||||
let atime = FileTime::from_last_access_time(&source_metadata);
|
||||
let mtime = FileTime::from_last_modification_time(&source_metadata);
|
||||
if dest.is_symlink() {
|
||||
filetime::set_symlink_file_times(dest, atime, mtime)?;
|
||||
} else {
|
||||
filetime::set_file_times(dest, atime, mtime)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
handle_preserve(&attributes.context, || -> CopyResult<()> {
|
||||
let context = selinux::SecurityContext::of_path(source, false, false).map_err(|e| {
|
||||
format!(
|
||||
"failed to get security context of {}: {}",
|
||||
source.display(),
|
||||
e
|
||||
)
|
||||
.map_err(Error::Error)?;
|
||||
}
|
||||
Attribute::Timestamps => {
|
||||
let atime = FileTime::from_last_access_time(&source_metadata);
|
||||
let mtime = FileTime::from_last_modification_time(&source_metadata);
|
||||
if dest.is_symlink() {
|
||||
filetime::set_symlink_file_times(dest, atime, mtime)?;
|
||||
} else {
|
||||
filetime::set_file_times(dest, atime, mtime)?;
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "feat_selinux")]
|
||||
Attribute::Context => {
|
||||
let context = selinux::SecurityContext::of_path(source, false, false).map_err(|e| {
|
||||
})?;
|
||||
if let Some(context) = context {
|
||||
context.set_for_path(dest, false, false).map_err(|e| {
|
||||
format!(
|
||||
"failed to get security context of {}: {}",
|
||||
source.display(),
|
||||
"failed to set security context for {}: {}",
|
||||
dest.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
if let Some(context) = context {
|
||||
context.set_for_path(dest, false, false).map_err(|e| {
|
||||
format!(
|
||||
"failed to set security context for {}: {}",
|
||||
dest.display(),
|
||||
e
|
||||
)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Attribute::Links => {}
|
||||
Attribute::Xattr => {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let xattrs = xattr::list(source)?;
|
||||
for attr in xattrs {
|
||||
if let Some(attr_value) = xattr::get(source, attr.clone())? {
|
||||
xattr::set(dest, attr, &attr_value[..])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
handle_preserve(&attributes.xattr, || -> CopyResult<()> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let xattrs = xattr::list(source)?;
|
||||
for attr in xattrs {
|
||||
if let Some(attr_value) = xattr::get(source, attr.clone())? {
|
||||
xattr::set(dest, attr, &attr_value[..])?;
|
||||
}
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
// The documentation for GNU cp states:
|
||||
//
|
||||
// > Try to preserve SELinux security context and
|
||||
// > extended attributes (xattr), but ignore any failure
|
||||
// > to do that and print no corresponding diagnostic.
|
||||
//
|
||||
// so we simply do nothing here.
|
||||
//
|
||||
// TODO Silently ignore failures in the `#[cfg(unix)]`
|
||||
// block instead of terminating immediately on errors.
|
||||
}
|
||||
}
|
||||
};
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
// The documentation for GNU cp states:
|
||||
//
|
||||
// > Try to preserve SELinux security context and
|
||||
// > extended attributes (xattr), but ignore any failure
|
||||
// > to do that and print no corresponding diagnostic.
|
||||
//
|
||||
// so we simply do nothing here.
|
||||
//
|
||||
// TODO Silently ignore failures in the `#[cfg(unix)]`
|
||||
// block instead of terminating immediately on errors.
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1580,7 +1676,8 @@ fn copy_file(
|
|||
// the user does not have permission to write to the file.
|
||||
fs::set_permissions(dest, dest_permissions).ok();
|
||||
}
|
||||
copy_attributes(source, dest, &options.preserve_attributes)?;
|
||||
|
||||
copy_attributes(source, dest, &options.attributes)?;
|
||||
|
||||
if let Some(progress_bar) = progress_bar {
|
||||
progress_bar.inc(fs::metadata(source)?.len());
|
||||
|
@ -1759,7 +1856,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_aligned_ancestors() {
|
||||
let actual = aligned_ancestors(&Path::new("a/b/c"), &Path::new("d/a/b/c"));
|
||||
let actual = aligned_ancestors(Path::new("a/b/c"), Path::new("d/a/b/c"));
|
||||
let expected = vec![
|
||||
(Path::new("a"), Path::new("d/a")),
|
||||
(Path::new("a/b"), Path::new("d/a/b")),
|
||||
|
|
|
@ -69,9 +69,7 @@ pub(crate) fn copy_on_write(
|
|||
// support COW).
|
||||
match reflink_mode {
|
||||
ReflinkMode::Always => {
|
||||
return Err(
|
||||
format!("failed to clone {:?} from {:?}: {}", source, dest, error).into(),
|
||||
)
|
||||
return Err(format!("failed to clone {source:?} from {dest:?}: {error}").into())
|
||||
}
|
||||
_ => {
|
||||
if source_is_fifo {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_csplit"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "csplit ~ (uutils) Output pieces of FILE separated by PATTERN(s) to files 'xx00', 'xx01', ..., and output byte counts of each piece to standard output"
|
||||
|
@ -18,7 +18,7 @@ path = "src/csplit.rs"
|
|||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
thiserror = "1.0"
|
||||
regex = "1.7.0"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
|
||||
[[bin]]
|
||||
name = "csplit"
|
||||
|
|
|
@ -574,7 +574,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(0, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 1);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -583,7 +583,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(1, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 2);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -595,7 +595,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(input_splitter.buffer_len(), 2);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
input_splitter.rewind_buffer();
|
||||
|
@ -605,7 +605,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("bbb"));
|
||||
assert_eq!(input_splitter.buffer_len(), 1);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -613,7 +613,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("ccc"));
|
||||
assert_eq!(input_splitter.buffer_len(), 0);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -621,7 +621,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("ddd"));
|
||||
assert_eq!(input_splitter.buffer_len(), 0);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
assert!(input_splitter.next().is_none());
|
||||
|
@ -646,7 +646,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(0, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 1);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -655,7 +655,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(1, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 2);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -664,7 +664,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(2, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 3);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
input_splitter.rewind_buffer();
|
||||
|
@ -675,7 +675,7 @@ mod tests {
|
|||
assert_eq!(input_splitter.add_line_to_buffer(0, line), None);
|
||||
assert_eq!(input_splitter.buffer_len(), 3);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -683,7 +683,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("aaa"));
|
||||
assert_eq!(input_splitter.buffer_len(), 2);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -691,7 +691,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("bbb"));
|
||||
assert_eq!(input_splitter.buffer_len(), 1);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -699,7 +699,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("ccc"));
|
||||
assert_eq!(input_splitter.buffer_len(), 0);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
match input_splitter.next() {
|
||||
|
@ -707,7 +707,7 @@ mod tests {
|
|||
assert_eq!(line, String::from("ddd"));
|
||||
assert_eq!(input_splitter.buffer_len(), 0);
|
||||
}
|
||||
item => panic!("wrong item: {:?}", item),
|
||||
item => panic!("wrong item: {item:?}"),
|
||||
};
|
||||
|
||||
assert!(input_splitter.next().is_none());
|
||||
|
|
|
@ -224,35 +224,35 @@ mod tests {
|
|||
assert_eq!(patterns.len(), 5);
|
||||
match patterns.get(0) {
|
||||
Some(Pattern::UpToMatch(reg, 0, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test1.*end$");
|
||||
}
|
||||
_ => panic!("expected UpToMatch pattern"),
|
||||
};
|
||||
match patterns.get(1) {
|
||||
Some(Pattern::UpToMatch(reg, 0, ExecutePattern::Always)) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test2.*end$");
|
||||
}
|
||||
_ => panic!("expected UpToMatch pattern"),
|
||||
};
|
||||
match patterns.get(2) {
|
||||
Some(Pattern::UpToMatch(reg, 0, ExecutePattern::Times(5))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test3.*end$");
|
||||
}
|
||||
_ => panic!("expected UpToMatch pattern"),
|
||||
};
|
||||
match patterns.get(3) {
|
||||
Some(Pattern::UpToMatch(reg, 3, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test4.*end$");
|
||||
}
|
||||
_ => panic!("expected UpToMatch pattern"),
|
||||
};
|
||||
match patterns.get(4) {
|
||||
Some(Pattern::UpToMatch(reg, -3, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test5.*end$");
|
||||
}
|
||||
_ => panic!("expected UpToMatch pattern"),
|
||||
|
@ -277,35 +277,35 @@ mod tests {
|
|||
assert_eq!(patterns.len(), 5);
|
||||
match patterns.get(0) {
|
||||
Some(Pattern::SkipToMatch(reg, 0, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test1.*end$");
|
||||
}
|
||||
_ => panic!("expected SkipToMatch pattern"),
|
||||
};
|
||||
match patterns.get(1) {
|
||||
Some(Pattern::SkipToMatch(reg, 0, ExecutePattern::Always)) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test2.*end$");
|
||||
}
|
||||
_ => panic!("expected SkipToMatch pattern"),
|
||||
};
|
||||
match patterns.get(2) {
|
||||
Some(Pattern::SkipToMatch(reg, 0, ExecutePattern::Times(5))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test3.*end$");
|
||||
}
|
||||
_ => panic!("expected SkipToMatch pattern"),
|
||||
};
|
||||
match patterns.get(3) {
|
||||
Some(Pattern::SkipToMatch(reg, 3, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test4.*end$");
|
||||
}
|
||||
_ => panic!("expected SkipToMatch pattern"),
|
||||
};
|
||||
match patterns.get(4) {
|
||||
Some(Pattern::SkipToMatch(reg, -3, ExecutePattern::Times(1))) => {
|
||||
let parsed_reg = format!("{}", reg);
|
||||
let parsed_reg = format!("{reg}");
|
||||
assert_eq!(parsed_reg, "test5.*end$");
|
||||
}
|
||||
_ => panic!("expected SkipToMatch pattern"),
|
||||
|
|
|
@ -42,9 +42,7 @@ impl SplitName {
|
|||
.unwrap_or(2);
|
||||
// translate the custom format into a function
|
||||
let fn_split_name: Box<dyn Fn(usize) -> String> = match format_opt {
|
||||
None => Box::new(move |n: usize| -> String {
|
||||
format!("{}{:0width$}", prefix, n, width = n_digits)
|
||||
}),
|
||||
None => Box::new(move |n: usize| -> String { format!("{prefix}{n:0n_digits$}") }),
|
||||
Some(custom) => {
|
||||
let spec =
|
||||
Regex::new(r"(?P<ALL>%((?P<FLAG>[0#-])(?P<WIDTH>\d+)?)?(?P<TYPE>[diuoxX]))")
|
||||
|
@ -55,23 +53,23 @@ impl SplitName {
|
|||
let all = captures.name("ALL").unwrap();
|
||||
let before = custom[0..all.start()].to_owned();
|
||||
let after = custom[all.end()..].to_owned();
|
||||
let n_digits = match captures.name("WIDTH") {
|
||||
let width = match captures.name("WIDTH") {
|
||||
None => 0,
|
||||
Some(m) => m.as_str().parse::<usize>().unwrap(),
|
||||
};
|
||||
match (captures.name("FLAG"), captures.name("TYPE")) {
|
||||
(None, Some(ref t)) => match t.as_str() {
|
||||
"d" | "i" | "u" => Box::new(move |n: usize| -> String {
|
||||
format!("{}{}{}{}", prefix, before, n, after)
|
||||
format!("{prefix}{before}{n}{after}")
|
||||
}),
|
||||
"o" => Box::new(move |n: usize| -> String {
|
||||
format!("{}{}{:o}{}", prefix, before, n, after)
|
||||
format!("{prefix}{before}{n:o}{after}")
|
||||
}),
|
||||
"x" => Box::new(move |n: usize| -> String {
|
||||
format!("{}{}{:x}{}", prefix, before, n, after)
|
||||
format!("{prefix}{before}{n:x}{after}")
|
||||
}),
|
||||
"X" => Box::new(move |n: usize| -> String {
|
||||
format!("{}{}{:X}{}", prefix, before, n, after)
|
||||
format!("{prefix}{before}{n:X}{after}")
|
||||
}),
|
||||
_ => return Err(CsplitError::SuffixFormatIncorrect),
|
||||
},
|
||||
|
@ -82,47 +80,19 @@ impl SplitName {
|
|||
*/
|
||||
// decimal
|
||||
("0", "d" | "i" | "u") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:0width$}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:0width$}{after}")
|
||||
}),
|
||||
// octal
|
||||
("0", "o") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:0width$o}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:0width$o}{after}")
|
||||
}),
|
||||
// lower hexadecimal
|
||||
("0", "x") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:0width$x}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:0width$x}{after}")
|
||||
}),
|
||||
// upper hexadecimal
|
||||
("0", "X") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:0width$X}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:0width$X}{after}")
|
||||
}),
|
||||
|
||||
/*
|
||||
|
@ -130,36 +100,15 @@ impl SplitName {
|
|||
*/
|
||||
// octal
|
||||
("#", "o") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:>#width$o}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:>#width$o}{after}")
|
||||
}),
|
||||
// lower hexadecimal
|
||||
("#", "x") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:>#width$x}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:>#width$x}{after}")
|
||||
}),
|
||||
// upper hexadecimal
|
||||
("#", "X") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:>#width$X}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:>#width$X}{after}")
|
||||
}),
|
||||
|
||||
/*
|
||||
|
@ -167,47 +116,19 @@ impl SplitName {
|
|||
*/
|
||||
// decimal
|
||||
("-", "d" | "i" | "u") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:<#width$}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:<#width$}{after}")
|
||||
}),
|
||||
// octal
|
||||
("-", "o") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:<#width$o}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:<#width$o}{after}")
|
||||
}),
|
||||
// lower hexadecimal
|
||||
("-", "x") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:<#width$x}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:<#width$x}{after}")
|
||||
}),
|
||||
// upper hexadecimal
|
||||
("-", "X") => Box::new(move |n: usize| -> String {
|
||||
format!(
|
||||
"{}{}{:<#width$X}{}",
|
||||
prefix,
|
||||
before,
|
||||
n,
|
||||
after,
|
||||
width = n_digits
|
||||
)
|
||||
format!("{prefix}{before}{n:<#width$X}{after}")
|
||||
}),
|
||||
|
||||
_ => return Err(CsplitError::SuffixFormatIncorrect),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_cut"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "cut ~ (uutils) display byte/field columns of input lines"
|
||||
|
@ -16,7 +16,7 @@ path = "src/cut.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
memchr = "2"
|
||||
bstr = "1.0"
|
||||
atty = "0.2"
|
||||
|
|
|
@ -16,14 +16,15 @@ use uucore::display::Quotable;
|
|||
use uucore::error::{FromIo, UResult, USimpleError};
|
||||
|
||||
use self::searcher::Searcher;
|
||||
use matcher::{ExactMatcher, Matcher, WhitespaceMatcher};
|
||||
use uucore::ranges::Range;
|
||||
use uucore::{format_usage, show, show_error, show_if_err};
|
||||
|
||||
mod matcher;
|
||||
mod searcher;
|
||||
|
||||
static NAME: &str = "cut";
|
||||
static USAGE: &str =
|
||||
"{} [-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+";
|
||||
"{} [-d|-w] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+";
|
||||
static ABOUT: &str =
|
||||
"Prints specified byte or field columns from each line of stdin or the input files";
|
||||
static LONG_HELP: &str = "
|
||||
|
@ -85,6 +86,11 @@ static LONG_HELP: &str = "
|
|||
--delimiter (-d) option. Setting the delimiter is optional.
|
||||
If not set, a default delimiter of Tab will be used.
|
||||
|
||||
If the -w option is provided, fields will be separated by any number
|
||||
of whitespace characters (Space and Tab). The output delimiter will
|
||||
be a Tab unless explicitly specified. Only one of -d or -w option can be specified.
|
||||
This is an extension adopted from FreeBSD.
|
||||
|
||||
Optionally Filter based on delimiter
|
||||
If the --only-delimited (-s) flag is provided, only lines which
|
||||
contain the delimiter will be printed
|
||||
|
@ -111,8 +117,13 @@ struct Options {
|
|||
zero_terminated: bool,
|
||||
}
|
||||
|
||||
enum Delimiter {
|
||||
Whitespace,
|
||||
String(String), // FIXME: use char?
|
||||
}
|
||||
|
||||
struct FieldOptions {
|
||||
delimiter: String, // one char long, String because of UTF8 representation
|
||||
delimiter: Delimiter,
|
||||
out_delimiter: Option<String>,
|
||||
only_delimited: bool,
|
||||
zero_terminated: bool,
|
||||
|
@ -177,23 +188,22 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> UResult<()
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn cut_fields_delimiter<R: Read>(
|
||||
// Output delimiter is explicitly specified
|
||||
fn cut_fields_explicit_out_delim<R: Read, M: Matcher>(
|
||||
reader: R,
|
||||
matcher: &M,
|
||||
ranges: &[Range],
|
||||
delim: &str,
|
||||
only_delimited: bool,
|
||||
newline_char: u8,
|
||||
out_delim: &str,
|
||||
) -> UResult<()> {
|
||||
let mut buf_in = BufReader::new(reader);
|
||||
let mut out = stdout_writer();
|
||||
let input_delim_len = delim.len();
|
||||
|
||||
let result = buf_in.for_byte_record_with_terminator(newline_char, |line| {
|
||||
let mut fields_pos = 1;
|
||||
let mut low_idx = 0;
|
||||
let mut delim_search = Searcher::new(line, delim.as_bytes()).peekable();
|
||||
let mut delim_search = Searcher::new(matcher, line).peekable();
|
||||
let mut print_delim = false;
|
||||
|
||||
if delim_search.peek().is_none() {
|
||||
|
@ -209,13 +219,17 @@ fn cut_fields_delimiter<R: Read>(
|
|||
|
||||
for &Range { low, high } in ranges {
|
||||
if low - fields_pos > 0 {
|
||||
// current field is not in the range, so jump to the field corresponding to the
|
||||
// beginning of the range if any
|
||||
low_idx = match delim_search.nth(low - fields_pos - 1) {
|
||||
Some(index) => index + input_delim_len,
|
||||
Some((_, last)) => last,
|
||||
None => break,
|
||||
};
|
||||
}
|
||||
|
||||
// at this point, current field is the first in the range
|
||||
for _ in 0..=high - low {
|
||||
// skip printing delimiter if this is the first matching field for this line
|
||||
if print_delim {
|
||||
out.write_all(out_delim.as_bytes())?;
|
||||
} else {
|
||||
|
@ -223,15 +237,17 @@ fn cut_fields_delimiter<R: Read>(
|
|||
}
|
||||
|
||||
match delim_search.next() {
|
||||
Some(high_idx) => {
|
||||
let segment = &line[low_idx..high_idx];
|
||||
// print the current field up to the next field delim
|
||||
Some((first, last)) => {
|
||||
let segment = &line[low_idx..first];
|
||||
|
||||
out.write_all(segment)?;
|
||||
|
||||
low_idx = high_idx + input_delim_len;
|
||||
low_idx = last;
|
||||
fields_pos = high + 1;
|
||||
}
|
||||
None => {
|
||||
// this is the last field in the line, so print the rest
|
||||
let segment = &line[low_idx..];
|
||||
|
||||
out.write_all(segment)?;
|
||||
|
@ -256,32 +272,25 @@ fn cut_fields_delimiter<R: Read>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> UResult<()> {
|
||||
let newline_char = if opts.zero_terminated { b'\0' } else { b'\n' };
|
||||
if let Some(ref o_delim) = opts.out_delimiter {
|
||||
return cut_fields_delimiter(
|
||||
reader,
|
||||
ranges,
|
||||
&opts.delimiter,
|
||||
opts.only_delimited,
|
||||
newline_char,
|
||||
o_delim,
|
||||
);
|
||||
}
|
||||
|
||||
// Output delimiter is the same as input delimiter
|
||||
fn cut_fields_implicit_out_delim<R: Read, M: Matcher>(
|
||||
reader: R,
|
||||
matcher: &M,
|
||||
ranges: &[Range],
|
||||
only_delimited: bool,
|
||||
newline_char: u8,
|
||||
) -> UResult<()> {
|
||||
let mut buf_in = BufReader::new(reader);
|
||||
let mut out = stdout_writer();
|
||||
let delim_len = opts.delimiter.len();
|
||||
|
||||
let result = buf_in.for_byte_record_with_terminator(newline_char, |line| {
|
||||
let mut fields_pos = 1;
|
||||
let mut low_idx = 0;
|
||||
let mut delim_search = Searcher::new(line, opts.delimiter.as_bytes()).peekable();
|
||||
let mut delim_search = Searcher::new(matcher, line).peekable();
|
||||
let mut print_delim = false;
|
||||
|
||||
if delim_search.peek().is_none() {
|
||||
if !opts.only_delimited {
|
||||
if !only_delimited {
|
||||
out.write_all(line)?;
|
||||
if line[line.len() - 1] != newline_char {
|
||||
out.write_all(&[newline_char])?;
|
||||
|
@ -293,25 +302,21 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> URes
|
|||
|
||||
for &Range { low, high } in ranges {
|
||||
if low - fields_pos > 0 {
|
||||
if let Some(delim_pos) = delim_search.nth(low - fields_pos - 1) {
|
||||
low_idx = if print_delim {
|
||||
delim_pos
|
||||
} else {
|
||||
delim_pos + delim_len
|
||||
}
|
||||
if let Some((first, last)) = delim_search.nth(low - fields_pos - 1) {
|
||||
low_idx = if print_delim { first } else { last }
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
match delim_search.nth(high - low) {
|
||||
Some(high_idx) => {
|
||||
let segment = &line[low_idx..high_idx];
|
||||
Some((first, _)) => {
|
||||
let segment = &line[low_idx..first];
|
||||
|
||||
out.write_all(segment)?;
|
||||
|
||||
print_delim = true;
|
||||
low_idx = high_idx;
|
||||
low_idx = first;
|
||||
fields_pos = high + 1;
|
||||
}
|
||||
None => {
|
||||
|
@ -337,6 +342,44 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> URes
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> UResult<()> {
|
||||
let newline_char = if opts.zero_terminated { b'\0' } else { b'\n' };
|
||||
match opts.delimiter {
|
||||
Delimiter::String(ref delim) => {
|
||||
let matcher = ExactMatcher::new(delim.as_bytes());
|
||||
match opts.out_delimiter {
|
||||
Some(ref out_delim) => cut_fields_explicit_out_delim(
|
||||
reader,
|
||||
&matcher,
|
||||
ranges,
|
||||
opts.only_delimited,
|
||||
newline_char,
|
||||
out_delim,
|
||||
),
|
||||
None => cut_fields_implicit_out_delim(
|
||||
reader,
|
||||
&matcher,
|
||||
ranges,
|
||||
opts.only_delimited,
|
||||
newline_char,
|
||||
),
|
||||
}
|
||||
}
|
||||
Delimiter::Whitespace => {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let out_delim = opts.out_delimiter.as_deref().unwrap_or("\t");
|
||||
cut_fields_explicit_out_delim(
|
||||
reader,
|
||||
&matcher,
|
||||
ranges,
|
||||
opts.only_delimited,
|
||||
newline_char,
|
||||
out_delim,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cut_files(mut filenames: Vec<String>, mode: &Mode) {
|
||||
let mut stdin_read = false;
|
||||
|
||||
|
@ -387,6 +430,7 @@ mod options {
|
|||
pub const ZERO_TERMINATED: &str = "zero-terminated";
|
||||
pub const ONLY_DELIMITED: &str = "only-delimited";
|
||||
pub const OUTPUT_DELIMITER: &str = "output-delimiter";
|
||||
pub const WHITESPACE_DELIMITED: &str = "whitespace-delimited";
|
||||
pub const COMPLEMENT: &str = "complement";
|
||||
pub const FILE: &str = "file";
|
||||
}
|
||||
|
@ -449,9 +493,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
};
|
||||
|
||||
let only_delimited = matches.get_flag(options::ONLY_DELIMITED);
|
||||
let whitespace_delimited = matches.get_flag(options::WHITESPACE_DELIMITED);
|
||||
let zero_terminated = matches.get_flag(options::ZERO_TERMINATED);
|
||||
|
||||
match matches.get_one::<String>(options::DELIMITER).map(|s| s.as_str()) {
|
||||
Some(_) if whitespace_delimited => {
|
||||
Err("invalid input: Only one of --delimiter (-d) or -w option can be specified".into())
|
||||
}
|
||||
Some(mut delim) => {
|
||||
// GNU's `cut` supports `-d=` to set the delimiter to `=`.
|
||||
// Clap parsing is limited in this situation, see:
|
||||
|
@ -474,7 +522,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
Ok(Mode::Fields(
|
||||
ranges,
|
||||
FieldOptions {
|
||||
delimiter: delim,
|
||||
delimiter: Delimiter::String(delim),
|
||||
out_delimiter: out_delim,
|
||||
only_delimited,
|
||||
zero_terminated,
|
||||
|
@ -485,7 +533,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
None => Ok(Mode::Fields(
|
||||
ranges,
|
||||
FieldOptions {
|
||||
delimiter: "\t".to_owned(),
|
||||
delimiter: match whitespace_delimited {
|
||||
true => Delimiter::Whitespace,
|
||||
false => Delimiter::String("\t".to_owned()),
|
||||
},
|
||||
out_delimiter: out_delim,
|
||||
only_delimited,
|
||||
zero_terminated,
|
||||
|
@ -508,6 +559,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
{
|
||||
Err("invalid input: The '--delimiter' ('-d') option only usable if printing a sequence of fields".into())
|
||||
}
|
||||
Mode::Bytes(_, _) | Mode::Characters(_, _)
|
||||
if matches.get_flag(options::WHITESPACE_DELIMITED) =>
|
||||
{
|
||||
Err("invalid input: The '-w' option only usable if printing a sequence of fields".into())
|
||||
}
|
||||
Mode::Bytes(_, _) | Mode::Characters(_, _)
|
||||
if matches.get_flag(options::ONLY_DELIMITED) =>
|
||||
{
|
||||
|
@ -534,7 +590,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.override_usage(format_usage(USAGE))
|
||||
.about(ABOUT)
|
||||
|
@ -563,6 +618,13 @@ pub fn uu_app() -> Command {
|
|||
.help("specify the delimiter character that separates fields in the input source. Defaults to Tab.")
|
||||
.value_name("DELIM"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::WHITESPACE_DELIMITED)
|
||||
.short('w')
|
||||
.help("Use any number of whitespace (Space, Tab) to separate fields in the input source (FreeBSD extension).")
|
||||
.value_name("WHITESPACE")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::FIELDS)
|
||||
.short('f')
|
||||
|
|
126
src/uu/cut/src/matcher.rs
Normal file
126
src/uu/cut/src/matcher.rs
Normal file
|
@ -0,0 +1,126 @@
|
|||
// This file is part of the uutils coreutils package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use memchr::{memchr, memchr2};
|
||||
|
||||
// Find the next matching byte sequence positions
|
||||
// Return (first, last) where haystack[first..last] corresponds to the matched pattern
|
||||
pub trait Matcher {
|
||||
fn next_match(&self, haystack: &[u8]) -> Option<(usize, usize)>;
|
||||
}
|
||||
|
||||
// Matches for the exact byte sequence pattern
|
||||
pub struct ExactMatcher<'a> {
|
||||
needle: &'a [u8],
|
||||
}
|
||||
|
||||
impl<'a> ExactMatcher<'a> {
|
||||
pub fn new(needle: &'a [u8]) -> Self {
|
||||
assert!(!needle.is_empty());
|
||||
Self { needle }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Matcher for ExactMatcher<'a> {
|
||||
fn next_match(&self, haystack: &[u8]) -> Option<(usize, usize)> {
|
||||
let mut pos = 0usize;
|
||||
loop {
|
||||
match memchr(self.needle[0], &haystack[pos..]) {
|
||||
Some(match_idx) => {
|
||||
let match_idx = match_idx + pos; // account for starting from pos
|
||||
if self.needle.len() == 1
|
||||
|| haystack[match_idx + 1..].starts_with(&self.needle[1..])
|
||||
{
|
||||
return Some((match_idx, match_idx + self.needle.len()));
|
||||
} else {
|
||||
pos = match_idx + 1;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Matches for any number of SPACE or TAB
|
||||
pub struct WhitespaceMatcher {}
|
||||
|
||||
impl Matcher for WhitespaceMatcher {
|
||||
fn next_match(&self, haystack: &[u8]) -> Option<(usize, usize)> {
|
||||
match memchr2(b' ', b'\t', haystack) {
|
||||
Some(match_idx) => {
|
||||
let mut skip = match_idx + 1;
|
||||
while skip < haystack.len() {
|
||||
match haystack[skip] {
|
||||
b' ' | b'\t' => skip += 1,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
Some((match_idx, skip))
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod matcher_tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_exact_matcher_single_byte() {
|
||||
let matcher = ExactMatcher::new(":".as_bytes());
|
||||
// spell-checker:disable
|
||||
assert_eq!(matcher.next_match("".as_bytes()), None);
|
||||
assert_eq!(matcher.next_match(":".as_bytes()), Some((0, 1)));
|
||||
assert_eq!(matcher.next_match(":abcxyz".as_bytes()), Some((0, 1)));
|
||||
assert_eq!(matcher.next_match("abc:xyz".as_bytes()), Some((3, 4)));
|
||||
assert_eq!(matcher.next_match("abcxyz:".as_bytes()), Some((6, 7)));
|
||||
assert_eq!(matcher.next_match("abcxyz".as_bytes()), None);
|
||||
// spell-checker:enable
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exact_matcher_multi_bytes() {
|
||||
let matcher = ExactMatcher::new("<>".as_bytes());
|
||||
// spell-checker:disable
|
||||
assert_eq!(matcher.next_match("".as_bytes()), None);
|
||||
assert_eq!(matcher.next_match("<>".as_bytes()), Some((0, 2)));
|
||||
assert_eq!(matcher.next_match("<>abcxyz".as_bytes()), Some((0, 2)));
|
||||
assert_eq!(matcher.next_match("abc<>xyz".as_bytes()), Some((3, 5)));
|
||||
assert_eq!(matcher.next_match("abcxyz<>".as_bytes()), Some((6, 8)));
|
||||
assert_eq!(matcher.next_match("abcxyz".as_bytes()), None);
|
||||
// spell-checker:enable
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_whitespace_matcher_single_space() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
// spell-checker:disable
|
||||
assert_eq!(matcher.next_match("".as_bytes()), None);
|
||||
assert_eq!(matcher.next_match(" ".as_bytes()), Some((0, 1)));
|
||||
assert_eq!(matcher.next_match("\tabcxyz".as_bytes()), Some((0, 1)));
|
||||
assert_eq!(matcher.next_match("abc\txyz".as_bytes()), Some((3, 4)));
|
||||
assert_eq!(matcher.next_match("abcxyz ".as_bytes()), Some((6, 7)));
|
||||
assert_eq!(matcher.next_match("abcxyz".as_bytes()), None);
|
||||
// spell-checker:enable
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_whitespace_matcher_multi_spaces() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
// spell-checker:disable
|
||||
assert_eq!(matcher.next_match("".as_bytes()), None);
|
||||
assert_eq!(matcher.next_match(" \t ".as_bytes()), Some((0, 3)));
|
||||
assert_eq!(matcher.next_match("\t\tabcxyz".as_bytes()), Some((0, 2)));
|
||||
assert_eq!(matcher.next_match("abc \txyz".as_bytes()), Some((3, 5)));
|
||||
assert_eq!(matcher.next_match("abcxyz ".as_bytes()), Some((6, 8)));
|
||||
assert_eq!(matcher.next_match("abcxyz".as_bytes()), None);
|
||||
// spell-checker:enable
|
||||
}
|
||||
}
|
|
@ -5,82 +5,77 @@
|
|||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use memchr::memchr;
|
||||
// spell-checker:ignore multispace
|
||||
|
||||
pub struct Searcher<'a> {
|
||||
haystack: &'a [u8],
|
||||
needle: &'a [u8],
|
||||
use super::matcher::Matcher;
|
||||
|
||||
// Generic searcher that relies on a specific matcher
|
||||
pub struct Searcher<'a, 'b, M: Matcher> {
|
||||
matcher: &'a M,
|
||||
haystack: &'b [u8],
|
||||
position: usize,
|
||||
}
|
||||
|
||||
impl<'a> Searcher<'a> {
|
||||
pub fn new(haystack: &'a [u8], needle: &'a [u8]) -> Searcher<'a> {
|
||||
assert!(!needle.is_empty());
|
||||
Searcher {
|
||||
impl<'a, 'b, M: Matcher> Searcher<'a, 'b, M> {
|
||||
pub fn new(matcher: &'a M, haystack: &'b [u8]) -> Self {
|
||||
Self {
|
||||
matcher,
|
||||
haystack,
|
||||
needle,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Searcher<'a> {
|
||||
type Item = usize;
|
||||
// Iterate over field delimiters
|
||||
// Returns (first, last) positions of each sequence, where `haystack[first..last]`
|
||||
// corresponds to the delimiter.
|
||||
impl<'a, 'b, M: Matcher> Iterator for Searcher<'a, 'b, M> {
|
||||
type Item = (usize, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if let Some(match_idx) = memchr(self.needle[0], self.haystack) {
|
||||
if self.needle.len() == 1
|
||||
|| self.haystack[match_idx + 1..].starts_with(&self.needle[1..])
|
||||
{
|
||||
let match_pos = self.position + match_idx;
|
||||
let skip = match_idx + self.needle.len();
|
||||
self.haystack = &self.haystack[skip..];
|
||||
self.position += skip;
|
||||
return Some(match_pos);
|
||||
} else {
|
||||
let skip = match_idx + 1;
|
||||
self.haystack = &self.haystack[skip..];
|
||||
self.position += skip;
|
||||
// continue
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
match self.matcher.next_match(&self.haystack[self.position..]) {
|
||||
Some((first, last)) => {
|
||||
let result = (first + self.position, last + self.position);
|
||||
self.position += last;
|
||||
Some(result)
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
mod exact_searcher_tests {
|
||||
|
||||
use super::super::matcher::ExactMatcher;
|
||||
use super::*;
|
||||
|
||||
const NEEDLE: &[u8] = "ab".as_bytes();
|
||||
|
||||
#[test]
|
||||
fn test_normal() {
|
||||
let iter = Searcher::new("a.a.a".as_bytes(), "a".as_bytes());
|
||||
let items: Vec<usize> = iter.collect();
|
||||
assert_eq!(vec![0, 2, 4], items);
|
||||
let matcher = ExactMatcher::new("a".as_bytes());
|
||||
let iter = Searcher::new(&matcher, "a.a.a".as_bytes());
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(vec![(0, 1), (2, 3), (4, 5)], items);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let iter = Searcher::new("".as_bytes(), "a".as_bytes());
|
||||
let items: Vec<usize> = iter.collect();
|
||||
assert_eq!(vec![] as Vec<usize>, items);
|
||||
let matcher = ExactMatcher::new("a".as_bytes());
|
||||
let iter = Searcher::new(&matcher, "".as_bytes());
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(vec![] as Vec<(usize, usize)>, items);
|
||||
}
|
||||
|
||||
fn test_multibyte(line: &[u8], expected: &[usize]) {
|
||||
let iter = Searcher::new(line, NEEDLE);
|
||||
let items: Vec<usize> = iter.collect();
|
||||
fn test_multibyte(line: &[u8], expected: &[(usize, usize)]) {
|
||||
let matcher = ExactMatcher::new("ab".as_bytes());
|
||||
let iter = Searcher::new(&matcher, line);
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(expected, items);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multibyte_normal() {
|
||||
test_multibyte("...ab...ab...".as_bytes(), &[3, 8]);
|
||||
test_multibyte("...ab...ab...".as_bytes(), &[(3, 5), (8, 10)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -90,16 +85,101 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_multibyte_starting_needle() {
|
||||
test_multibyte("ab...ab...".as_bytes(), &[0, 5]);
|
||||
test_multibyte("ab...ab...".as_bytes(), &[(0, 2), (5, 7)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multibyte_trailing_needle() {
|
||||
test_multibyte("...ab...ab".as_bytes(), &[3, 8]);
|
||||
test_multibyte("...ab...ab".as_bytes(), &[(3, 5), (8, 10)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multibyte_first_byte_false_match() {
|
||||
test_multibyte("aA..aCaC..ab..aD".as_bytes(), &[10]);
|
||||
test_multibyte("aA..aCaC..ab..aD".as_bytes(), &[(10, 12)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_searcher_with_exact_matcher() {
|
||||
let matcher = ExactMatcher::new("<>".as_bytes());
|
||||
let haystack = "<><>a<>b<><>cd<><>".as_bytes();
|
||||
let mut searcher = Searcher::new(&matcher, haystack);
|
||||
assert_eq!(searcher.next(), Some((0, 2)));
|
||||
assert_eq!(searcher.next(), Some((2, 4)));
|
||||
assert_eq!(searcher.next(), Some((5, 7)));
|
||||
assert_eq!(searcher.next(), Some((8, 10)));
|
||||
assert_eq!(searcher.next(), Some((10, 12)));
|
||||
assert_eq!(searcher.next(), Some((14, 16)));
|
||||
assert_eq!(searcher.next(), Some((16, 18)));
|
||||
assert_eq!(searcher.next(), None);
|
||||
assert_eq!(searcher.next(), None);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod whitespace_searcher_tests {
|
||||
|
||||
use super::super::matcher::WhitespaceMatcher;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_space() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let iter = Searcher::new(&matcher, " . . ".as_bytes());
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(vec![(0, 1), (2, 3), (4, 5)], items);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tab() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let iter = Searcher::new(&matcher, "\t.\t.\t".as_bytes());
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(vec![(0, 1), (2, 3), (4, 5)], items);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let iter = Searcher::new(&matcher, "".as_bytes());
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(vec![] as Vec<(usize, usize)>, items);
|
||||
}
|
||||
|
||||
fn test_multispace(line: &[u8], expected: &[(usize, usize)]) {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let iter = Searcher::new(&matcher, line);
|
||||
let items: Vec<(usize, usize)> = iter.collect();
|
||||
assert_eq!(expected, items);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multispace_normal() {
|
||||
test_multispace(
|
||||
"... ... \t...\t ... \t ...".as_bytes(),
|
||||
&[(3, 5), (8, 10), (13, 15), (18, 21)],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multispace_begin() {
|
||||
test_multispace(" \t\t...".as_bytes(), &[(0, 3)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multispace_end() {
|
||||
test_multispace("...\t ".as_bytes(), &[(3, 6)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_searcher_with_whitespace_matcher() {
|
||||
let matcher = WhitespaceMatcher {};
|
||||
let haystack = "\t a b \t cd\t\t".as_bytes();
|
||||
let mut searcher = Searcher::new(&matcher, haystack);
|
||||
assert_eq!(searcher.next(), Some((0, 2)));
|
||||
assert_eq!(searcher.next(), Some((3, 4)));
|
||||
assert_eq!(searcher.next(), Some((5, 8)));
|
||||
assert_eq!(searcher.next(), Some((10, 12)));
|
||||
assert_eq!(searcher.next(), None);
|
||||
assert_eq!(searcher.next(), None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_date"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "date ~ (uutils) display or set the current time"
|
||||
|
@ -17,7 +17,7 @@ path = "src/date.rs"
|
|||
[dependencies]
|
||||
chrono = { version="^0.4.23", default-features=false, features=["std", "alloc", "clock"]}
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
|
|
|
@ -117,7 +117,7 @@ impl<'a> From<&'a str> for Iso8601Format {
|
|||
NS => Self::Ns,
|
||||
DATE => Self::Date,
|
||||
// Should be caught by clap
|
||||
_ => panic!("Invalid format: {}", s),
|
||||
_ => panic!("Invalid format: {s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ impl<'a> From<&'a str> for Rfc3339Format {
|
|||
SECONDS | SECOND => Self::Seconds,
|
||||
NS => Self::Ns,
|
||||
// Should be caught by clap
|
||||
_ => panic!("Invalid format: {}", s),
|
||||
_ => panic!("Invalid format: {s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
.format_with_items(format_items)
|
||||
.to_string()
|
||||
.replace("%f", "%N");
|
||||
println!("{}", formatted);
|
||||
println!("{formatted}");
|
||||
}
|
||||
Err((input, _err)) => show_error!("invalid date {}", input.quote()),
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_dd"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "dd ~ (uutils) copy and convert files"
|
||||
|
@ -18,7 +18,7 @@ path = "src/dd.rs"
|
|||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
gcd = "2.0"
|
||||
libc = "0.2"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
|
||||
signal-hook = "0.3.14"
|
||||
|
|
|
@ -491,8 +491,8 @@ impl<'a> Output<'a> {
|
|||
// These objects are counters, initialized to zero. After each
|
||||
// iteration of the main loop, each will be incremented by the
|
||||
// number of blocks read and written, respectively.
|
||||
let mut rstat = Default::default();
|
||||
let mut wstat = Default::default();
|
||||
let mut rstat = ReadStat::default();
|
||||
let mut wstat = WriteStat::default();
|
||||
|
||||
// The time at which the main loop starts executing.
|
||||
//
|
||||
|
@ -772,9 +772,7 @@ fn is_stdout_redirected_to_seekable_file() -> bool {
|
|||
let p = Path::new(&s);
|
||||
match File::open(p) {
|
||||
Ok(mut f) => {
|
||||
f.seek(SeekFrom::Current(0)).is_ok()
|
||||
&& f.seek(SeekFrom::End(0)).is_ok()
|
||||
&& f.seek(SeekFrom::Start(0)).is_ok()
|
||||
f.stream_position().is_ok() && f.seek(SeekFrom::End(0)).is_ok() && f.rewind().is_ok()
|
||||
}
|
||||
Err(_) => false,
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ pub(crate) fn to_magnitude_and_suffix(n: u128, suffix_type: SuffixType) -> Strin
|
|||
//
|
||||
let quotient = (n as f64) / (base as f64);
|
||||
if quotient < 10.0 {
|
||||
format!("{:.1} {}", quotient, suffix)
|
||||
format!("{quotient:.1} {suffix}")
|
||||
} else {
|
||||
format!("{} {}", quotient.round(), suffix)
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ impl std::fmt::Display for ParseError {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::UnrecognizedOperand(arg) => {
|
||||
write!(f, "Unrecognized operand '{}'", arg)
|
||||
write!(f, "Unrecognized operand '{arg}'")
|
||||
}
|
||||
Self::MultipleFmtTable => {
|
||||
write!(
|
||||
|
@ -415,37 +415,37 @@ impl std::fmt::Display for ParseError {
|
|||
// Additional message about 'dd --help' is displayed only in this situation.
|
||||
write!(
|
||||
f,
|
||||
"invalid input flag: ‘{}’\nTry 'dd --help' for more information.",
|
||||
arg
|
||||
"invalid input flag: ‘{}’\nTry '{} --help' for more information.",
|
||||
arg,
|
||||
uucore::execution_phrase()
|
||||
)
|
||||
}
|
||||
Self::ConvFlagNoMatch(arg) => {
|
||||
write!(f, "Unrecognized conv=CONV -> {}", arg)
|
||||
write!(f, "Unrecognized conv=CONV -> {arg}")
|
||||
}
|
||||
Self::MultiplierStringParseFailure(arg) => {
|
||||
write!(f, "Unrecognized byte multiplier -> {}", arg)
|
||||
write!(f, "Unrecognized byte multiplier -> {arg}")
|
||||
}
|
||||
Self::MultiplierStringOverflow(arg) => {
|
||||
write!(
|
||||
f,
|
||||
"Multiplier string would overflow on current system -> {}",
|
||||
arg
|
||||
"Multiplier string would overflow on current system -> {arg}"
|
||||
)
|
||||
}
|
||||
Self::BlockUnblockWithoutCBS => {
|
||||
write!(f, "conv=block or conv=unblock specified without cbs=N")
|
||||
}
|
||||
Self::StatusLevelNotRecognized(arg) => {
|
||||
write!(f, "status=LEVEL not recognized -> {}", arg)
|
||||
write!(f, "status=LEVEL not recognized -> {arg}")
|
||||
}
|
||||
Self::BsOutOfRange(arg) => {
|
||||
write!(f, "{}=N cannot fit into memory", arg)
|
||||
write!(f, "{arg}=N cannot fit into memory")
|
||||
}
|
||||
Self::Unimplemented(arg) => {
|
||||
write!(f, "feature not implemented on this system -> {}", arg)
|
||||
write!(f, "feature not implemented on this system -> {arg}")
|
||||
}
|
||||
Self::InvalidNumber(arg) => {
|
||||
write!(f, "invalid number: ‘{}’", arg)
|
||||
write!(f, "invalid number: ‘{arg}’")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,6 +501,7 @@ fn parse_bytes_only(s: &str) -> Result<u64, ParseError> {
|
|||
fn parse_bytes_no_x(full: &str, s: &str) -> Result<u64, ParseError> {
|
||||
let parser = SizeParser {
|
||||
capital_b_bytes: true,
|
||||
..Default::default()
|
||||
};
|
||||
let (num, multiplier) = match (s.find('c'), s.rfind('w'), s.rfind('b')) {
|
||||
(None, None, None) => match parser.parse(s) {
|
||||
|
|
|
@ -56,29 +56,28 @@ fn unimplemented_flags_should_error() {
|
|||
|
||||
// The following flags are not implemented
|
||||
for flag in ["cio", "nocache", "nolinks", "text", "binary"] {
|
||||
let args = vec![format!("iflag={}", flag)];
|
||||
let args = vec![format!("iflag={flag}")];
|
||||
|
||||
if Parser::new()
|
||||
.parse(&args.iter().map(AsRef::as_ref).collect::<Vec<_>>()[..])
|
||||
.is_ok()
|
||||
{
|
||||
succeeded.push(format!("iflag={}", flag));
|
||||
succeeded.push(format!("iflag={flag}"));
|
||||
}
|
||||
|
||||
let args = vec![format!("oflag={}", flag)];
|
||||
let args = vec![format!("oflag={flag}")];
|
||||
|
||||
if Parser::new()
|
||||
.parse(&args.iter().map(AsRef::as_ref).collect::<Vec<_>>()[..])
|
||||
.is_ok()
|
||||
{
|
||||
succeeded.push(format!("iflag={}", flag));
|
||||
succeeded.push(format!("iflag={flag}"));
|
||||
}
|
||||
}
|
||||
|
||||
assert!(
|
||||
succeeded.is_empty(),
|
||||
"The following flags did not panic as expected: {:?}",
|
||||
succeeded
|
||||
"The following flags did not panic as expected: {succeeded:?}"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ impl ProgUpdate {
|
|||
match self.read_stat.records_truncated {
|
||||
0 => {}
|
||||
1 => writeln!(w, "1 truncated record")?,
|
||||
n => writeln!(w, "{} truncated records", n)?,
|
||||
n => writeln!(w, "{n} truncated records")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -154,29 +154,19 @@ impl ProgUpdate {
|
|||
match btotal {
|
||||
1 => write!(
|
||||
w,
|
||||
"{}{} byte copied, {:.1} s, {}/s{}",
|
||||
carriage_return, btotal, duration, transfer_rate, newline,
|
||||
"{carriage_return}{btotal} byte copied, {duration:.1} s, {transfer_rate}/s{newline}",
|
||||
),
|
||||
0..=999 => write!(
|
||||
w,
|
||||
"{}{} bytes copied, {:.1} s, {}/s{}",
|
||||
carriage_return, btotal, duration, transfer_rate, newline,
|
||||
"{carriage_return}{btotal} bytes copied, {duration:.1} s, {transfer_rate}/s{newline}",
|
||||
),
|
||||
1000..=1023 => write!(
|
||||
w,
|
||||
"{}{} bytes ({}) copied, {:.1} s, {}/s{}",
|
||||
carriage_return, btotal, btotal_metric, duration, transfer_rate, newline,
|
||||
"{carriage_return}{btotal} bytes ({btotal_metric}) copied, {duration:.1} s, {transfer_rate}/s{newline}",
|
||||
),
|
||||
_ => write!(
|
||||
w,
|
||||
"{}{} bytes ({}, {}) copied, {:.1} s, {}/s{}",
|
||||
carriage_return,
|
||||
btotal,
|
||||
btotal_metric,
|
||||
btotal_bin,
|
||||
duration,
|
||||
transfer_rate,
|
||||
newline,
|
||||
"{carriage_return}{btotal} bytes ({btotal_metric}, {btotal_bin}) copied, {duration:.1} s, {transfer_rate}/s{newline}",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -455,10 +445,7 @@ pub(crate) fn gen_prog_updater(
|
|||
|
||||
register_linux_signal_handler(sigval.clone()).unwrap_or_else(|e| {
|
||||
if Some(StatusLevel::None) != print_level {
|
||||
eprintln!(
|
||||
"Internal dd Warning: Unable to register signal handler \n\t{}",
|
||||
e
|
||||
);
|
||||
eprintln!("Internal dd Warning: Unable to register signal handler \n\t{e}");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_df"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "df ~ (uutils) display file system information"
|
||||
|
@ -16,7 +16,7 @@ path = "src/df.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["libc", "fsext"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["libc", "fsext"] }
|
||||
unicode-width = "0.1.9"
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -91,12 +91,12 @@ pub(crate) fn to_magnitude_and_suffix(n: u128, suffix_type: SuffixType) -> Strin
|
|||
let suffix = suffixes[i];
|
||||
|
||||
if rem == 0 {
|
||||
format!("{}{}", quot, suffix)
|
||||
format!("{quot}{suffix}")
|
||||
} else {
|
||||
let tenths_place = rem / (bases[i] / 10);
|
||||
|
||||
if rem % (bases[i] / 10) == 0 {
|
||||
format!("{}.{}{}", quot, tenths_place, suffix)
|
||||
format!("{quot}.{tenths_place}{suffix}")
|
||||
} else if tenths_place + 1 == 10 || quot >= 10 {
|
||||
format!("{}{}", quot + 1, suffix)
|
||||
} else {
|
||||
|
@ -205,7 +205,7 @@ impl fmt::Display for BlockSize {
|
|||
to_magnitude_and_suffix(*n as u128, SuffixType::Si)
|
||||
};
|
||||
|
||||
write!(f, "{}", s)
|
||||
write!(f, "{s}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,11 +105,11 @@ impl Default for Options {
|
|||
Self {
|
||||
show_local_fs: Default::default(),
|
||||
show_all_fs: Default::default(),
|
||||
block_size: Default::default(),
|
||||
human_readable: Default::default(),
|
||||
header_mode: Default::default(),
|
||||
include: Default::default(),
|
||||
exclude: Default::default(),
|
||||
block_size: BlockSize::default(),
|
||||
human_readable: Option::default(),
|
||||
header_mode: HeaderMode::default(),
|
||||
include: Option::default(),
|
||||
exclude: Option::default(),
|
||||
sync: Default::default(),
|
||||
show_total: Default::default(),
|
||||
columns: vec![
|
||||
|
@ -146,10 +146,10 @@ impl fmt::Display for OptionsError {
|
|||
}
|
||||
// TODO This needs to vary based on whether `--block-size`
|
||||
// or `-B` were provided.
|
||||
Self::InvalidBlockSize(s) => write!(f, "invalid --block-size argument {}", s),
|
||||
Self::InvalidBlockSize(s) => write!(f, "invalid --block-size argument {s}"),
|
||||
// TODO This needs to vary based on whether `--block-size`
|
||||
// or `-B` were provided.
|
||||
Self::InvalidSuffix(s) => write!(f, "invalid suffix in --block-size argument {}", s),
|
||||
Self::InvalidSuffix(s) => write!(f, "invalid suffix in --block-size argument {s}"),
|
||||
Self::ColumnError(ColumnError::MultipleColumns(s)) => write!(
|
||||
f,
|
||||
"option --output: field {} used more than once",
|
||||
|
|
|
@ -438,7 +438,7 @@ impl fmt::Display for Table {
|
|||
Alignment::Left => {
|
||||
if is_last_col {
|
||||
// no trailing spaces in last column
|
||||
write!(f, "{}", elem)?;
|
||||
write!(f, "{elem}")?;
|
||||
} else {
|
||||
write!(f, "{:<width$}", elem, width = self.widths[i])?;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_dir"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "shortcut to ls -C -b"
|
||||
|
@ -16,8 +16,8 @@ path = "src/dir.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo", "env"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
uu_ls = { version = ">=0.0.16", path="../ls"}
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "fs"] }
|
||||
uu_ls = { version = ">=0.0.17", path="../ls"}
|
||||
|
||||
[[bin]]
|
||||
name = "dir"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_dircolors"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "dircolors ~ (uutils) display commands to set LS_COLORS"
|
||||
|
@ -16,7 +16,7 @@ path = "src/dircolors.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "dircolors"
|
||||
|
|
|
@ -103,7 +103,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
),
|
||||
));
|
||||
}
|
||||
println!("{}", INTERNAL_DB);
|
||||
println!("{INTERNAL_DB}");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
match result {
|
||||
Ok(s) => {
|
||||
println!("{}", s);
|
||||
println!("{s}");
|
||||
Ok(())
|
||||
}
|
||||
Err(s) => {
|
||||
|
@ -368,23 +368,23 @@ where
|
|||
if state != ParseState::Pass {
|
||||
if key.starts_with('.') {
|
||||
if *fmt == OutputFmt::Display {
|
||||
result.push_str(format!("\x1b[{1}m*{0}\t{1}\x1b[0m\n", key, val).as_str());
|
||||
result.push_str(format!("\x1b[{val}m*{key}\t{val}\x1b[0m\n").as_str());
|
||||
} else {
|
||||
result.push_str(format!("*{}={}:", key, val).as_str());
|
||||
result.push_str(format!("*{key}={val}:").as_str());
|
||||
}
|
||||
} else if key.starts_with('*') {
|
||||
if *fmt == OutputFmt::Display {
|
||||
result.push_str(format!("\x1b[{1}m{0}\t{1}\x1b[0m\n", key, val).as_str());
|
||||
result.push_str(format!("\x1b[{val}m{key}\t{val}\x1b[0m\n").as_str());
|
||||
} else {
|
||||
result.push_str(format!("{}={}:", key, val).as_str());
|
||||
result.push_str(format!("{key}={val}:").as_str());
|
||||
}
|
||||
} else if lower == "options" || lower == "color" || lower == "eightbit" {
|
||||
// Slackware only. Ignore
|
||||
} else if let Some(s) = table.get(lower.as_str()) {
|
||||
if *fmt == OutputFmt::Display {
|
||||
result.push_str(format!("\x1b[{1}m{0}\t{1}\x1b[0m\n", s, val).as_str());
|
||||
result.push_str(format!("\x1b[{val}m{s}\t{val}\x1b[0m\n").as_str());
|
||||
} else {
|
||||
result.push_str(format!("{}={}:", s, val).as_str());
|
||||
result.push_str(format!("{s}={val}:").as_str());
|
||||
}
|
||||
} else {
|
||||
return Err(format!(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_dirname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "dirname ~ (uutils) display parent directory of PATHNAME"
|
||||
|
@ -16,7 +16,7 @@ path = "src/dirname.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "dirname"
|
||||
|
|
|
@ -63,7 +63,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
}
|
||||
print!("{}", separator);
|
||||
print!("{separator}");
|
||||
}
|
||||
} else {
|
||||
return Err(UUsageError::new(1, "missing operand"));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_du"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "du ~ (uutils) display disk usage"
|
||||
|
@ -19,7 +19,7 @@ chrono = { version="^0.4.23", default-features=false, features=["std", "alloc",
|
|||
# For the --exclude & --exclude-from options
|
||||
glob = "0.3.0"
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows-sys = { version = "0.42.0", default-features = false, features = ["Win32_Storage_FileSystem", "Win32_Foundation"] }
|
||||
|
|
|
@ -389,7 +389,7 @@ fn convert_size_human(size: u64, multiplier: u64, _block_size: u64) -> String {
|
|||
if size == 0 {
|
||||
return "0".to_string();
|
||||
}
|
||||
format!("{}B", size)
|
||||
format!("{size}B")
|
||||
}
|
||||
|
||||
fn convert_size_b(size: u64, _multiplier: u64, _block_size: u64) -> String {
|
||||
|
@ -448,7 +448,7 @@ Try '{} --help' for more information.",
|
|||
'birth' and 'creation' arguments are not supported on this platform.",
|
||||
s.quote()
|
||||
),
|
||||
Self::InvalidGlob(s) => write!(f, "Invalid exclude syntax: {}", s),
|
||||
Self::InvalidGlob(s) => write!(f, "Invalid exclude syntax: {s}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,12 +650,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
let time_str = tm.format(time_format_str).to_string();
|
||||
print!("{}\t{}\t", convert_size(size), time_str);
|
||||
print_verbatim(stat.path).unwrap();
|
||||
print!("{}", line_separator);
|
||||
print!("{line_separator}");
|
||||
}
|
||||
} else if !summarize || index == len - 1 {
|
||||
print!("{}\t", convert_size(size));
|
||||
print_verbatim(stat.path).unwrap();
|
||||
print!("{}", line_separator);
|
||||
print!("{line_separator}");
|
||||
}
|
||||
if options.total && index == (len - 1) {
|
||||
// The last element will be the total size of the the path under
|
||||
|
@ -674,7 +674,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
if options.total {
|
||||
print!("{}\ttotal", convert_size(grand_total));
|
||||
print!("{}", line_separator);
|
||||
print!("{line_separator}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_echo"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "echo ~ (uutils) display TEXT"
|
||||
|
@ -16,7 +16,7 @@ path = "src/echo.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "echo"
|
||||
|
|
|
@ -13,7 +13,6 @@ use std::str::Chars;
|
|||
use uucore::error::{FromIo, UResult};
|
||||
use uucore::format_usage;
|
||||
|
||||
const NAME: &str = "echo";
|
||||
const ABOUT: &str = "display a line of text";
|
||||
const USAGE: &str = "{} [OPTIONS]... [STRING]...";
|
||||
const AFTER_HELP: &str = r#"
|
||||
|
@ -104,7 +103,7 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result<bool> {
|
|||
|
||||
// because printing char slices is apparently not available in the standard library
|
||||
for ch in &buffer[start..] {
|
||||
write!(output, "{}", ch)?;
|
||||
write!(output, "{ch}")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +128,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
pub fn uu_app() -> Command {
|
||||
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.
|
||||
|
@ -175,7 +173,7 @@ fn execute(no_newline: bool, escaped: bool, free: &[String]) -> io::Result<()> {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
write!(output, "{}", input)?;
|
||||
write!(output, "{input}")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
src/uu/env/Cargo.toml
vendored
4
src/uu/env/Cargo.toml
vendored
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_env"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "env ~ (uutils) set each NAME to VALUE in the environment and run COMMAND"
|
||||
|
@ -17,7 +17,7 @@ path = "src/env.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
rust-ini = "0.18.0"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["signals"]}
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["signals"]}
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
nix = { version = "0.25", default-features = false, features = ["signal"] }
|
||||
|
|
2
src/uu/env/src/env.rs
vendored
2
src/uu/env/src/env.rs
vendored
|
@ -210,7 +210,7 @@ fn run_env(args: impl uucore::Args) -> UResult<()> {
|
|||
Err(error) => {
|
||||
return Err(USimpleError::new(
|
||||
125,
|
||||
format!("cannot change directory to \"{}\": {}", d, error),
|
||||
format!("cannot change directory to \"{d}\": {error}"),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_expand"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "expand ~ (uutils) convert input tabs to spaces"
|
||||
|
@ -17,7 +17,7 @@ path = "src/expand.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
unicode-width = "0.1.5"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "expand"
|
||||
|
|
|
@ -255,7 +255,7 @@ fn expand_shortcuts(args: &[String]) -> Vec<String> {
|
|||
arg[1..]
|
||||
.split(',')
|
||||
.filter(|s| !s.is_empty())
|
||||
.for_each(|s| processed_args.push(format!("--tabs={}", s)));
|
||||
.for_each(|s| processed_args.push(format!("--tabs={s}")));
|
||||
} else {
|
||||
processed_args.push(arg.to_string());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_expr"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "expr ~ (uutils) display the value of EXPRESSION"
|
||||
|
@ -19,7 +19,7 @@ clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
|||
num-bigint = "0.4.0"
|
||||
num-traits = "0.2.15"
|
||||
onig = { version = "~6.4", default-features = false }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "expr"
|
||||
|
|
|
@ -73,8 +73,8 @@ fn process_expr(token_strings: &[&str]) -> Result<String, String> {
|
|||
}
|
||||
|
||||
fn print_expr_ok(expr_result: &str) -> UResult<()> {
|
||||
println!("{}", expr_result);
|
||||
if expr_result == "0" || expr_result.is_empty() {
|
||||
println!("{expr_result}");
|
||||
if expr_result.parse::<i32>() == Ok(0) || expr_result.is_empty() {
|
||||
Err(1.into())
|
||||
} else {
|
||||
Ok(())
|
||||
|
|
|
@ -151,7 +151,7 @@ impl AstNode {
|
|||
"index" => Ok(prefix_operator_index(&operand_values)),
|
||||
"substr" => Ok(prefix_operator_substr(&operand_values)),
|
||||
|
||||
_ => Err(format!("operation not implemented: {}", op_type)),
|
||||
_ => Err(format!("operation not implemented: {op_type}")),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ fn maybe_dump_ast(result: &Result<Box<AstNode>, String>) {
|
|||
println!("EXPR_DEBUG_AST");
|
||||
match result {
|
||||
Ok(ast) => ast.debug_dump(),
|
||||
Err(reason) => println!("\terr: {:?}", reason),
|
||||
Err(reason) => println!("\terr: {reason:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ fn maybe_dump_rpn(rpn: &TokenStack) {
|
|||
if debug_var == "1" {
|
||||
println!("EXPR_DEBUG_RPN");
|
||||
for token in rpn {
|
||||
println!("\t{:?}", token);
|
||||
println!("\t{token:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ fn ast_from_rpn(rpn: &mut TokenStack) -> Result<Box<AstNode>, String> {
|
|||
}
|
||||
|
||||
Some((token_idx, unexpected_token)) => {
|
||||
panic!("unexpected token at #{} {:?}", token_idx, unexpected_token)
|
||||
panic!("unexpected token at #{token_idx} {unexpected_token:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,14 +266,12 @@ fn move_rest_of_ops_to_out(
|
|||
None => return Ok(()),
|
||||
Some((token_idx, Token::ParOpen)) => {
|
||||
return Err(format!(
|
||||
"syntax error (Mismatched open-parenthesis at #{})",
|
||||
token_idx
|
||||
"syntax error (Mismatched open-parenthesis at #{token_idx})"
|
||||
))
|
||||
}
|
||||
Some((token_idx, Token::ParClose)) => {
|
||||
return Err(format!(
|
||||
"syntax error (Mismatched close-parenthesis at #{})",
|
||||
token_idx
|
||||
"syntax error (Mismatched close-parenthesis at #{token_idx})"
|
||||
))
|
||||
}
|
||||
Some(other) => out_stack.push(other),
|
||||
|
@ -325,10 +323,10 @@ fn maybe_dump_shunting_yard_step(
|
|||
if let Ok(debug_var) = env::var("EXPR_DEBUG_SYA_STEP") {
|
||||
if debug_var == "1" {
|
||||
println!("EXPR_DEBUG_SYA_STEP");
|
||||
println!("\t{} => {:?}", token_idx, token);
|
||||
println!("\t\tout: {:?}", out_stack);
|
||||
println!("\t\top : {:?}", op_stack);
|
||||
println!("\t\tresult: {:?}", result);
|
||||
println!("\t{token_idx} => {token:?}");
|
||||
println!("\t\tout: {out_stack:?}");
|
||||
println!("\t\top : {op_stack:?}");
|
||||
println!("\t\tresult: {result:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -478,7 +476,7 @@ fn prefix_operator_index(values: &[String]) -> String {
|
|||
for (current_idx, ch_h) in haystack.chars().enumerate() {
|
||||
for ch_n in needles.chars() {
|
||||
if ch_n == ch_h {
|
||||
return current_idx.to_string();
|
||||
return (current_idx + 1).to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ fn maybe_dump_tokens_acc(tokens_acc: &[(usize, Token)]) {
|
|||
if debug_var == "1" {
|
||||
println!("EXPR_DEBUG_TOKENS");
|
||||
for token in tokens_acc {
|
||||
println!("\t{:?}", token);
|
||||
println!("\t{token:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_factor"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "factor ~ (uutils) display the prime factors of each NUMBER"
|
||||
|
@ -20,7 +20,7 @@ coz = { version = "0.1.3", optional = true }
|
|||
num-traits = "0.2.15" # Needs at least version 0.2.15 for "OverflowingAdd"
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
smallvec = { version = "1.10", features = ["union"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[dev-dependencies]
|
||||
paste = "1.0.6"
|
||||
|
|
|
@ -46,7 +46,7 @@ fn main() {
|
|||
.and_then(|s| s.parse::<usize>().ok())
|
||||
.unwrap_or(DEFAULT_SIZE);
|
||||
|
||||
write!(file, "{}", PREAMBLE).unwrap();
|
||||
write!(file, "{PREAMBLE}").unwrap();
|
||||
let mut cols = 3;
|
||||
|
||||
// we want a total of n + 1 values
|
||||
|
@ -60,10 +60,10 @@ fn main() {
|
|||
// format the table
|
||||
let output = format!("({}, {}, {}),", x, modular_inverse(x), std::u64::MAX / x);
|
||||
if cols + output.len() > MAX_WIDTH {
|
||||
write!(file, "\n {}", output).unwrap();
|
||||
write!(file, "\n {output}").unwrap();
|
||||
cols = 4 + output.len();
|
||||
} else {
|
||||
write!(file, " {}", output).unwrap();
|
||||
write!(file, " {output}").unwrap();
|
||||
cols += 1 + output.len();
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,7 @@ fn main() {
|
|||
|
||||
write!(
|
||||
file,
|
||||
"\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {};\n",
|
||||
x
|
||||
"\n];\n\n#[allow(dead_code)]\npub const NEXT_PRIME: u64 = {x};\n"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ impl fmt::Display for Factors {
|
|||
|
||||
for (p, exp) in v.iter() {
|
||||
for _ in 0..*exp {
|
||||
write!(f, " {}", p)?;
|
||||
write!(f, " {p}")?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,8 +153,7 @@ mod tests {
|
|||
for p in odd_primes() {
|
||||
assert!(
|
||||
test(Montgomery::<A>::new(p)).is_prime(),
|
||||
"{} reported composite",
|
||||
p
|
||||
"{p} reported composite"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +172,7 @@ mod tests {
|
|||
fn first_composites() {
|
||||
for (p, q) in primes().zip(odd_primes()) {
|
||||
for i in p + 1..q {
|
||||
assert!(!is_prime(i), "{} reported prime", i);
|
||||
assert!(!is_prime(i), "{i} reported prime");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +191,7 @@ mod tests {
|
|||
for q in odd_primes().take_while(|q| *q <= p) {
|
||||
let n = p * q;
|
||||
let m = Montgomery::<A>::new(n);
|
||||
assert!(!test(m).is_prime(), "{} = {} × {} reported prime", n, p, q);
|
||||
assert!(!test(m).is_prime(), "{n} = {p} × {q} reported prime");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ pub fn gcd(mut u: u64, mut v: u64) -> u64 {
|
|||
|
||||
loop {
|
||||
// Loop invariant: u and v are odd
|
||||
debug_assert!(u % 2 == 1, "u = {} is even", u);
|
||||
debug_assert!(v % 2 == 1, "v = {} is even", v);
|
||||
debug_assert!(u % 2 == 1, "u = {u} is even");
|
||||
debug_assert!(v % 2 == 1, "v = {v} is even");
|
||||
|
||||
// gcd(u, v) = gcd(|u - v|, min(u, v))
|
||||
if u > v {
|
||||
|
|
|
@ -13,7 +13,7 @@ use super::traits::Int;
|
|||
pub(crate) fn modular_inverse<T: Int>(a: T) -> T {
|
||||
let zero = T::zero();
|
||||
let one = T::one();
|
||||
debug_assert!(a % (one + one) == one, "{:?} is not odd", a);
|
||||
debug_assert!(a % (one + one) == one, "{a:?} is not odd");
|
||||
|
||||
let mut t = zero;
|
||||
let mut new_t = one;
|
||||
|
|
|
@ -192,7 +192,7 @@ mod tests {
|
|||
let m_x = m.to_mod(x);
|
||||
for y in 0..=x {
|
||||
let m_y = m.to_mod(y);
|
||||
println!("{n:?}, {x:?}, {y:?}", n = n, x = x, y = y);
|
||||
println!("{n:?}, {x:?}, {y:?}");
|
||||
assert_eq!((x + y) % n, m.to_u64(m.add(m_x, m_y)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_false"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "false ~ (uutils) do nothing and fail"
|
||||
|
@ -16,7 +16,7 @@ path = "src/false.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "false"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_fmt"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "fmt ~ (uutils) reformat each paragraph of input"
|
||||
|
@ -17,7 +17,7 @@ path = "src/fmt.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
unicode-width = "0.1.5"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "fmt"
|
||||
|
|
|
@ -27,7 +27,7 @@ struct BreakArgs<'a> {
|
|||
}
|
||||
|
||||
impl<'a> BreakArgs<'a> {
|
||||
fn compute_width<'b>(&self, winfo: &WordInfo<'b>, posn: usize, fresh: bool) -> usize {
|
||||
fn compute_width(&self, winfo: &WordInfo, posn: usize, fresh: bool) -> usize {
|
||||
if fresh {
|
||||
0
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_fold"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "fold ~ (uutils) wrap each line of input"
|
||||
|
@ -16,7 +16,7 @@ path = "src/fold.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "fold"
|
||||
|
|
|
@ -17,7 +17,6 @@ use uucore::format_usage;
|
|||
|
||||
const TAB_WIDTH: usize = 8;
|
||||
|
||||
static NAME: &str = "fold";
|
||||
static USAGE: &str = "{} [OPTION]... [FILE]...";
|
||||
static ABOUT: &str = "Writes each file (or standard input if no files are given)
|
||||
to standard output whilst breaking long lines";
|
||||
|
@ -63,7 +62,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.name(NAME)
|
||||
.version(crate_version!())
|
||||
.override_usage(format_usage(USAGE))
|
||||
.about(ABOUT)
|
||||
|
@ -190,9 +188,9 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
|
|||
let at_eol = i >= len;
|
||||
|
||||
if at_eol {
|
||||
print!("{}", slice);
|
||||
print!("{slice}");
|
||||
} else {
|
||||
println!("{}", slice);
|
||||
println!("{slice}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +285,7 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> URe
|
|||
}
|
||||
|
||||
if !output.is_empty() {
|
||||
print!("{}", output);
|
||||
print!("{output}");
|
||||
output.truncate(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_groups"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "groups ~ (uutils) display group memberships for USERNAME"
|
||||
|
@ -16,7 +16,7 @@ path = "src/groups.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "process"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "process"] }
|
||||
|
||||
[[bin]]
|
||||
name = "groups"
|
||||
|
|
|
@ -49,7 +49,7 @@ impl Display for GroupsError {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::GetGroupsFailed => write!(f, "failed to fetch groups"),
|
||||
Self::GroupNotFound(gid) => write!(f, "cannot find name for group ID {}", gid),
|
||||
Self::GroupNotFound(gid) => write!(f, "cannot find name for group ID {gid}"),
|
||||
Self::UserNotFound(user) => write!(f, "{}: no such user", user.quote()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_hashsum"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "hashsum ~ (uutils) display or check input digests"
|
||||
|
@ -26,7 +26,7 @@ sha2 = "0.10.2"
|
|||
sha3 = "0.10.6"
|
||||
blake2b_simd = "1.0.0"
|
||||
blake3 = "1.3.2"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "hashsum"
|
||||
|
|
|
@ -520,13 +520,12 @@ where
|
|||
// where `n` is the number of bytes.
|
||||
let bytes = options.digest.output_bits() / 4;
|
||||
let modifier = if bytes > 0 {
|
||||
format!("{{{}}}", bytes)
|
||||
format!("{{{bytes}}}")
|
||||
} else {
|
||||
"+".to_string()
|
||||
};
|
||||
let gnu_re = Regex::new(&format!(
|
||||
r"^(?P<digest>[a-fA-F0-9]{}) (?P<binary>[ \*])(?P<fileName>.*)",
|
||||
modifier,
|
||||
r"^(?P<digest>[a-fA-F0-9]{modifier}) (?P<binary>[ \*])(?P<fileName>.*)",
|
||||
))
|
||||
.map_err(|_| HashsumError::InvalidRegex)?;
|
||||
let bsd_re = Regex::new(&format!(
|
||||
|
@ -579,7 +578,7 @@ where
|
|||
uucore::util_name(),
|
||||
ck_filename
|
||||
);
|
||||
println!("{}: FAILED open or read", ck_filename);
|
||||
println!("{ck_filename}: FAILED open or read");
|
||||
continue;
|
||||
}
|
||||
Ok(file) => file,
|
||||
|
@ -604,11 +603,11 @@ where
|
|||
// easier (and more important) on Unix than on Windows.
|
||||
if sum == real_sum {
|
||||
if !options.quiet {
|
||||
println!("{}: OK", ck_filename);
|
||||
println!("{ck_filename}: OK");
|
||||
}
|
||||
} else {
|
||||
if !options.status {
|
||||
println!("{}: FAILED", ck_filename);
|
||||
println!("{ck_filename}: FAILED");
|
||||
}
|
||||
failed_cksum += 1;
|
||||
}
|
||||
|
@ -624,7 +623,7 @@ where
|
|||
if options.tag {
|
||||
println!("{} ({}) = {}", options.algoname, filename.display(), sum);
|
||||
} else if options.nonames {
|
||||
println!("{}", sum);
|
||||
println!("{sum}");
|
||||
} else {
|
||||
println!("{} {}{}", sum, binary_marker, filename.display());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_head"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "head ~ (uutils) display the first lines of input"
|
||||
|
@ -17,7 +17,7 @@ path = "src/head.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
memchr = "2"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["ringbuffer", "lines"] }
|
||||
|
||||
[[bin]]
|
||||
name = "head"
|
||||
|
|
|
@ -134,7 +134,7 @@ impl Mode {
|
|||
fn from(matches: &ArgMatches) -> Result<Self, String> {
|
||||
if let Some(v) = matches.get_one::<String>(options::BYTES_NAME) {
|
||||
let (n, all_but_last) =
|
||||
parse::parse_num(v).map_err(|err| format!("invalid number of bytes: {}", err))?;
|
||||
parse::parse_num(v).map_err(|err| format!("invalid number of bytes: {err}"))?;
|
||||
if all_but_last {
|
||||
Ok(Self::AllButLastBytes(n))
|
||||
} else {
|
||||
|
@ -142,14 +142,14 @@ impl Mode {
|
|||
}
|
||||
} else if let Some(v) = matches.get_one::<String>(options::LINES_NAME) {
|
||||
let (n, all_but_last) =
|
||||
parse::parse_num(v).map_err(|err| format!("invalid number of lines: {}", err))?;
|
||||
parse::parse_num(v).map_err(|err| format!("invalid number of lines: {err}"))?;
|
||||
if all_but_last {
|
||||
Ok(Self::AllButLastLines(n))
|
||||
} else {
|
||||
Ok(Self::FirstLines(n))
|
||||
}
|
||||
} else {
|
||||
Ok(Default::default())
|
||||
Ok(Self::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,13 +387,13 @@ where
|
|||
}
|
||||
// if it were just `n`,
|
||||
if lines == n + 1 {
|
||||
input.seek(SeekFrom::Start(0))?;
|
||||
input.rewind()?;
|
||||
return Ok(size - i);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if size - i == 0 {
|
||||
input.seek(SeekFrom::Start(0))?;
|
||||
input.rewind()?;
|
||||
return Ok(0);
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
|
|||
if let Err(e) = usize::try_from(n) {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!("{}: number of bytes is too large", e)
|
||||
format!("{e}: number of bytes is too large")
|
||||
));
|
||||
continue;
|
||||
};
|
||||
|
@ -493,7 +493,7 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
|
|||
if !first {
|
||||
println!();
|
||||
}
|
||||
println!("==> {} <==", name);
|
||||
println!("==> {name} <==");
|
||||
}
|
||||
head_file(&mut file, options)
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
|
|||
};
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!("error reading {}: Input/output error", name)
|
||||
format!("error reading {name}: Input/output error")
|
||||
));
|
||||
}
|
||||
first = false;
|
||||
|
|
|
@ -79,10 +79,10 @@ pub fn parse_obsolete(src: &str) -> Option<Result<impl Iterator<Item = OsString>
|
|||
Some(n) => n,
|
||||
None => return Some(Err(ParseError::Overflow)),
|
||||
};
|
||||
options.push(OsString::from(format!("{}", num)));
|
||||
options.push(OsString::from(format!("{num}")));
|
||||
} else {
|
||||
options.push(OsString::from("-n"));
|
||||
options.push(OsString::from(format!("{}", num)));
|
||||
options.push(OsString::from(format!("{num}")));
|
||||
}
|
||||
Some(Ok(options.into_iter()))
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_hostid"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "hostid ~ (uutils) display the numeric identifier of the current host"
|
||||
|
@ -17,7 +17,7 @@ path = "src/hostid.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
libc = "0.2.137"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "hostid"
|
||||
|
|
|
@ -50,5 +50,5 @@ fn hostid() {
|
|||
let mask = 0xffff_ffff;
|
||||
|
||||
result &= mask;
|
||||
println!("{:0>8x}", result);
|
||||
println!("{result:0>8x}");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_hostname"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "hostname ~ (uutils) display or set the host name of the current host"
|
||||
|
@ -17,7 +17,7 @@ path = "src/hostname.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
hostname = { version = "0.3", features = ["set"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["wide"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["wide"] }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
windows-sys = { version = "0.42.0", default-features = false, features = ["Win32_Networking_WinSock", "Win32_Foundation"] }
|
||||
|
|
|
@ -164,7 +164,7 @@ fn display_hostname(matches: &ArgMatches) -> UResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
println!("{}", hostname);
|
||||
println!("{hostname}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_id"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "id ~ (uutils) display user and group information for USER"
|
||||
|
@ -16,7 +16,7 @@ path = "src/id.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "process"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["entries", "process"] }
|
||||
selinux = { version="0.3", optional = true }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -326,7 +326,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
if default_format {
|
||||
id_print(&mut state, &groups);
|
||||
}
|
||||
print!("{}", line_ending);
|
||||
print!("{line_ending}");
|
||||
|
||||
if i + 1 >= users.len() {
|
||||
break;
|
||||
|
@ -468,11 +468,11 @@ fn pretty(possible_pw: Option<Passwd>) {
|
|||
let rid = getuid();
|
||||
if let Ok(p) = Passwd::locate(rid) {
|
||||
if login == p.name {
|
||||
println!("login\t{}", login);
|
||||
println!("login\t{login}");
|
||||
}
|
||||
println!("uid\t{}", p.name);
|
||||
} else {
|
||||
println!("uid\t{}", rid);
|
||||
println!("uid\t{rid}");
|
||||
}
|
||||
|
||||
let eid = getegid();
|
||||
|
@ -480,7 +480,7 @@ fn pretty(possible_pw: Option<Passwd>) {
|
|||
if let Ok(p) = Passwd::locate(eid) {
|
||||
println!("euid\t{}", p.name);
|
||||
} else {
|
||||
println!("euid\t{}", eid);
|
||||
println!("euid\t{eid}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ fn pretty(possible_pw: Option<Passwd>) {
|
|||
if let Ok(g) = Group::locate(rid) {
|
||||
println!("euid\t{}", g.name);
|
||||
} else {
|
||||
println!("euid\t{}", rid);
|
||||
println!("euid\t{rid}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_install"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = [
|
||||
"Ben Eills <ben@beneills.com>",
|
||||
"uutils developers",
|
||||
|
@ -22,7 +22,7 @@ clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
|||
filetime = "0.2"
|
||||
file_diff = "1.0.0"
|
||||
libc = ">= 0.2"
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs", "mode", "perms", "entries"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["fs", "mode", "perms", "entries"] }
|
||||
|
||||
[dev-dependencies]
|
||||
time = "0.3"
|
||||
|
|
|
@ -87,7 +87,7 @@ impl Error for InstallError {}
|
|||
impl Display for InstallError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Unimplemented(opt) => write!(f, "Unimplemented feature: {}", opt),
|
||||
Self::Unimplemented(opt) => write!(f, "Unimplemented feature: {opt}"),
|
||||
Self::DirNeedsArg() => {
|
||||
write!(
|
||||
f,
|
||||
|
@ -115,7 +115,7 @@ impl Display for InstallError {
|
|||
&uio_error!(e, "cannot install {} to {}", from.quote(), to.quote()),
|
||||
f,
|
||||
),
|
||||
Self::StripProgramFailed(msg) => write!(f, "strip program failed: {}", msg),
|
||||
Self::StripProgramFailed(msg) => write!(f, "strip program failed: {msg}"),
|
||||
Self::MetadataFailed(e) => Display::fmt(&uio_error!(e, ""), f),
|
||||
Self::NoSuchUser(user) => write!(f, "no such user: {}", user.maybe_quote()),
|
||||
Self::NoSuchGroup(group) => write!(f, "no such group: {}", group.maybe_quote()),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_join"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "join ~ (uutils) merge lines from inputs with matching join fields"
|
||||
|
@ -16,7 +16,7 @@ path = "src/join.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
memchr = "2"
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -24,8 +24,6 @@ use uucore::display::Quotable;
|
|||
use uucore::error::{set_exit_code, UError, UResult, USimpleError};
|
||||
use uucore::{crash, crash_if_err};
|
||||
|
||||
static NAME: &str = "join";
|
||||
|
||||
#[derive(Debug)]
|
||||
enum JoinError {
|
||||
IOError(std::io::Error),
|
||||
|
@ -43,7 +41,7 @@ impl Error for JoinError {}
|
|||
impl Display for JoinError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::IOError(e) => write!(f, "io error: {}", e),
|
||||
Self::IOError(e) => write!(f, "io error: {e}"),
|
||||
Self::UnorderedInput(e) => f.write_str(e),
|
||||
}
|
||||
}
|
||||
|
@ -606,7 +604,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
let key1 = parse_field_number_option(matches.get_one::<String>("1").map(|s| s.as_str()))?;
|
||||
let key2 = parse_field_number_option(matches.get_one::<String>("2").map(|s| s.as_str()))?;
|
||||
|
||||
let mut settings: Settings = Default::default();
|
||||
let mut settings = Settings::default();
|
||||
|
||||
let v_values = matches.get_many::<String>("v");
|
||||
if v_values.is_some() {
|
||||
|
@ -694,12 +692,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
|
||||
match exec(file1, file2, settings) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(USimpleError::new(1, format!("{}", e))),
|
||||
Err(e) => Err(USimpleError::new(1, format!("{e}"))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(NAME)
|
||||
Command::new(uucore::util_name())
|
||||
.version(crate_version!())
|
||||
.about(
|
||||
"For each pair of input lines with identical join fields, write a line to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_kill"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "kill ~ (uutils) send a signal to a process"
|
||||
|
@ -17,7 +17,7 @@ path = "src/kill.rs"
|
|||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
nix = { version = "0.25", features = ["signal"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["signals"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["signals"] }
|
||||
|
||||
[[bin]]
|
||||
name = "kill"
|
||||
|
|
|
@ -146,11 +146,11 @@ fn table() {
|
|||
|
||||
fn print_signal(signal_name_or_value: &str) -> UResult<()> {
|
||||
for (value, &signal) in ALL_SIGNALS.iter().enumerate() {
|
||||
if signal == signal_name_or_value || (format!("SIG{}", signal)) == signal_name_or_value {
|
||||
println!("{}", value);
|
||||
if signal == signal_name_or_value || (format!("SIG{signal}")) == signal_name_or_value {
|
||||
println!("{value}");
|
||||
return Ok(());
|
||||
} else if signal_name_or_value == value.to_string() {
|
||||
println!("{}", signal);
|
||||
println!("{signal}");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ fn print_signals() {
|
|||
if idx > 0 {
|
||||
print!(" ");
|
||||
}
|
||||
print!("{}", signal);
|
||||
print!("{signal}");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ fn kill(sig: Signal, pids: &[i32]) {
|
|||
for &pid in pids {
|
||||
if let Err(e) = signal::kill(Pid::from_raw(pid), sig) {
|
||||
show!(Error::from_raw_os_error(e as i32)
|
||||
.map_err_context(|| format!("sending signal to {} failed", pid)));
|
||||
.map_err_context(|| format!("sending signal to {pid} failed")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_link"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "link ~ (uutils) create a hard (file system) link to FILE"
|
||||
|
@ -16,7 +16,7 @@ path = "src/link.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore" }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore" }
|
||||
|
||||
[[bin]]
|
||||
name = "link"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "uu_ln"
|
||||
version = "0.0.16"
|
||||
version = "0.0.17"
|
||||
authors = ["uutils developers"]
|
||||
license = "MIT"
|
||||
description = "ln ~ (uutils) create a (file system) link to TARGET"
|
||||
|
@ -16,7 +16,7 @@ path = "src/ln.rs"
|
|||
|
||||
[dependencies]
|
||||
clap = { version = "4.0", features = ["wrap_help", "cargo"] }
|
||||
uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs"] }
|
||||
uucore = { version=">=0.0.17", package="uucore", path="../../uucore", features=["fs"] }
|
||||
|
||||
[[bin]]
|
||||
name = "ln"
|
||||
|
|
|
@ -466,7 +466,7 @@ fn simple_backup_path(path: &Path, suffix: &str) -> PathBuf {
|
|||
fn numbered_backup_path(path: &Path) -> PathBuf {
|
||||
let mut i: u64 = 1;
|
||||
loop {
|
||||
let new_path = simple_backup_path(path, &format!(".~{}~", i));
|
||||
let new_path = simple_backup_path(path, &format!(".~{i}~"));
|
||||
if !new_path.exists() {
|
||||
return new_path;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue