Compare commits

..

14 Commits

Author SHA1 Message Date
andy.boot 15845dee3e refactor: cleanup code 2023-01-04 21:24:57 +00:00
andy.boot 57115bd624 feature: Support for dereference links -L follow
du has -L flag which allows it to dereference or follow
symlinks. Clone this feature into dust.
https://github.com/bootandy/dust/issues/276
2023-01-04 21:17:23 +00:00
andy.boot 0ac818a2f5 Feature: Ignore sym links
https://github.com/bootandy/dust/issues/264
2023-01-04 20:57:43 +00:00
andy.boot a91aa62060 clippy: Fix new clippy 2023-01-04 20:08:20 +00:00
andy.boot a7b82f32d7 fix: update use of sysinfo.system
System is now much quicker to start but requires an explicit call
to refresh memory else it deafults to 0 (oops)
2023-01-04 20:08:20 +00:00
Guillaume Gomez 72b811c278 Update sysinfo version to 0.26.7 2023-01-04 19:38:40 +00:00
Phil Clifford b478534b22 added deb-get as installation source 2022-10-24 23:25:13 +01:00
DIRE 2ca7177446 FEATURE: support only directories will be displayed. Flag -D 2022-10-05 23:26:10 +01:00
Collin Styles e858f9e976 Read inputs from stdin when applicable 2022-10-01 11:16:14 +01:00
Collin Styles 0a67191054 Add a direct dependency on the atty crate 2022-10-01 11:16:14 +01:00
andy.boot c363e5ff8b Fix: Only create large stack size if enough memory
Small boxes do not have enough memory to create a large stack

Conversely we want a large stack size for large boxes with a very highly
nested directory structure.

Version: New version
2022-08-31 21:14:56 +01:00
Kian-Meng Ang c148cd9044 Prettify md/yaml file
Resolved via `prettier --write .`
2022-08-24 08:59:30 +01:00
Kian-Meng Ang 2893f73f47 Fix typos
Found via `codespell -L crate`.
2022-08-24 08:55:00 +01:00
andy.boot 5103ebe0d8 Version: Increment version 2022-08-23 12:26:08 +01:00
16 changed files with 439 additions and 280 deletions
+249 -221
View File
@@ -22,56 +22,56 @@ jobs:
- { os: macos-latest } - { os: macos-latest }
- { os: windows-latest } - { os: windows-latest }
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Initialize workflow variables - name: Initialize workflow variables
id: vars id: vars
shell: bash shell: bash
run: | run: |
# 'windows-latest' `cargo fmt` is bugged for this project (see reasons @ GH:rust-lang/rustfmt #3324, #3590, #3688 ; waiting for repair) # 'windows-latest' `cargo fmt` is bugged for this project (see reasons @ GH:rust-lang/rustfmt #3324, #3590, #3688 ; waiting for repair)
JOB_DO_FORMAT_TESTING="true" JOB_DO_FORMAT_TESTING="true"
case ${{ matrix.job.os }} in windows-latest) unset JOB_DO_FORMAT_TESTING ;; esac; case ${{ matrix.job.os }} in windows-latest) unset JOB_DO_FORMAT_TESTING ;; esac;
echo set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING:-<empty>/false} echo set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING:-<empty>/false}
echo ::set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING} echo ::set-output name=JOB_DO_FORMAT_TESTING::${JOB_DO_FORMAT_TESTING}
# target-specific options # target-specific options
# * CARGO_FEATURES_OPTION # * CARGO_FEATURES_OPTION
CARGO_FEATURES_OPTION='' ; CARGO_FEATURES_OPTION='' ;
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
- name: Install `rust` toolchain - name: Install `rust` toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: stable
override: true override: true
profile: minimal # minimal component installation (ie, no documentation) profile: minimal # minimal component installation (ie, no documentation)
components: rustfmt, clippy components: rustfmt, clippy
- name: "`fmt` testing" - name: "`fmt` testing"
if: steps.vars.outputs.JOB_DO_FORMAT_TESTING if: steps.vars.outputs.JOB_DO_FORMAT_TESTING
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: fmt command: fmt
args: --all -- --check args: --all -- --check
- name: "`clippy` testing" - name: "`clippy` testing"
if: success() || failure() # run regardless of prior step ("`fmt` testing") success/failure if: success() || failure() # run regardless of prior step ("`fmt` testing") success/failure
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: clippy command: clippy
args: ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings args: ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} -- -D warnings
min_version: min_version:
name: MinSRV # Minimum supported rust version name: MinSRV # Minimum supported rust version
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }}) - name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }})
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: ${{ env.RUST_MIN_SRV }} toolchain: ${{ env.RUST_MIN_SRV }}
profile: minimal # minimal component installation (ie, no documentation) profile: minimal # minimal component installation (ie, no documentation)
- name: Test - name: Test
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: test command: test
build: build:
name: Build name: Build
@@ -81,188 +81,216 @@ jobs:
matrix: matrix:
job: job:
# { os, target, cargo-options, features, use-cross, toolchain } # { os, target, cargo-options, features, use-cross, toolchain }
- { os: ubuntu-latest , target: aarch64-unknown-linux-gnu , use-cross: use-cross } - {
- { os: ubuntu-latest , target: aarch64-unknown-linux-musl , use-cross: use-cross } os: ubuntu-latest,
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , use-cross: use-cross } target: aarch64-unknown-linux-gnu,
- { os: ubuntu-latest , target: i686-unknown-linux-gnu , use-cross: use-cross } use-cross: use-cross,
- { os: ubuntu-latest , target: i686-unknown-linux-musl , use-cross: use-cross } }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , use-cross: use-cross } - {
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , use-cross: use-cross } os: ubuntu-latest,
- { os: macos-latest , target: x86_64-apple-darwin } target: aarch64-unknown-linux-musl,
- { os: windows-latest , target: i686-pc-windows-gnu } use-cross: use-cross,
- { os: windows-latest , target: i686-pc-windows-msvc } }
- { os: windows-latest , target: x86_64-pc-windows-gnu } ## !maint: [rivy; 2020-01-21] may break due to rust bug; follow possible solution from GH:rust-lang/rust#47048 (refs: GH:rust-lang/rust#47048 , GH:rust-lang/rust#53454 , GH:bike-barn/hermit#172 ) - {
- { os: windows-latest , target: x86_64-pc-windows-msvc } os: ubuntu-latest,
target: arm-unknown-linux-gnueabihf,
use-cross: use-cross,
}
- {
os: ubuntu-latest,
target: i686-unknown-linux-gnu,
use-cross: use-cross,
}
- {
os: ubuntu-latest,
target: i686-unknown-linux-musl,
use-cross: use-cross,
}
- {
os: ubuntu-latest,
target: x86_64-unknown-linux-gnu,
use-cross: use-cross,
}
- {
os: ubuntu-latest,
target: x86_64-unknown-linux-musl,
use-cross: use-cross,
}
- { os: macos-latest, target: x86_64-apple-darwin }
- { os: windows-latest, target: i686-pc-windows-gnu }
- { os: windows-latest, target: i686-pc-windows-msvc }
- { os: windows-latest, target: x86_64-pc-windows-gnu } ## !maint: [rivy; 2020-01-21] may break due to rust bug; follow possible solution from GH:rust-lang/rust#47048 (refs: GH:rust-lang/rust#47048 , GH:rust-lang/rust#53454 , GH:bike-barn/hermit#172 )
- { os: windows-latest, target: x86_64-pc-windows-msvc }
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Install any prerequisites - name: Install any prerequisites
shell: bash shell: bash
run: | run: |
case ${{ matrix.job.target }} in case ${{ matrix.job.target }} in
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install binutils-aarch64-linux-gnu ;; aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install binutils-aarch64-linux-gnu ;;
esac esac
- name: Initialize workflow variables - name: Initialize workflow variables
id: vars id: vars
shell: bash shell: bash
run: | run: |
# toolchain # toolchain
TOOLCHAIN="stable" ## default to "stable" toolchain TOOLCHAIN="stable" ## default to "stable" toolchain
# * specify alternate TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: <https://github.com/rust-lang/rust/issues/47048>, <https://github.com/rust-lang/rust/issues/53454>, <https://github.com/rust-lang/cargo/issues/6754>) # * specify alternate TOOLCHAIN for *-pc-windows-gnu targets; gnu targets on Windows are broken for the standard *-pc-windows-msvc toolchain (refs: <https://github.com/rust-lang/rust/issues/47048>, <https://github.com/rust-lang/rust/issues/53454>, <https://github.com/rust-lang/cargo/issues/6754>)
case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac; case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac;
# * use requested TOOLCHAIN if specified # * use requested TOOLCHAIN if specified
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
echo set-output name=TOOLCHAIN::${TOOLCHAIN} echo set-output name=TOOLCHAIN::${TOOLCHAIN}
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN} echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
# staging directory # staging directory
STAGING='_staging' STAGING='_staging'
echo set-output name=STAGING::${STAGING} echo set-output name=STAGING::${STAGING}
echo ::set-output name=STAGING::${STAGING} echo ::set-output name=STAGING::${STAGING}
# determine EXE suffix # determine EXE suffix
EXE_suffix="" ; case ${{ matrix.job.target }} in *-pc-windows-*) EXE_suffix=".exe" ;; esac; EXE_suffix="" ; case ${{ matrix.job.target }} in *-pc-windows-*) EXE_suffix=".exe" ;; esac;
echo set-output name=EXE_suffix::${EXE_suffix} echo set-output name=EXE_suffix::${EXE_suffix}
echo ::set-output name=EXE_suffix::${EXE_suffix} echo ::set-output name=EXE_suffix::${EXE_suffix}
# parse commit reference info # parse commit reference info
REF_NAME=${GITHUB_REF#refs/*/} REF_NAME=${GITHUB_REF#refs/*/}
unset REF_BRANCH ; case ${GITHUB_REF} in refs/heads/*) REF_BRANCH=${GITHUB_REF#refs/heads/} ;; esac; 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; 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:8}
echo set-output name=REF_NAME::${REF_NAME} echo set-output name=REF_NAME::${REF_NAME}
echo set-output name=REF_BRANCH::${REF_BRANCH} echo set-output name=REF_BRANCH::${REF_BRANCH}
echo set-output name=REF_TAG::${REF_TAG} echo set-output name=REF_TAG::${REF_TAG}
echo set-output name=REF_SHAS::${REF_SHAS} echo set-output name=REF_SHAS::${REF_SHAS}
echo ::set-output name=REF_NAME::${REF_NAME} echo ::set-output name=REF_NAME::${REF_NAME}
echo ::set-output name=REF_BRANCH::${REF_BRANCH} echo ::set-output name=REF_BRANCH::${REF_BRANCH}
echo ::set-output name=REF_TAG::${REF_TAG} echo ::set-output name=REF_TAG::${REF_TAG}
echo ::set-output name=REF_SHAS::${REF_SHAS} echo ::set-output name=REF_SHAS::${REF_SHAS}
# parse target # parse target
unset TARGET_ARCH ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) TARGET_ARCH=arm ;; aarch-*) TARGET_ARCH=aarch64 ;; i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac; unset TARGET_ARCH ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) TARGET_ARCH=arm ;; aarch-*) TARGET_ARCH=aarch64 ;; i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac;
echo set-output name=TARGET_ARCH::${TARGET_ARCH} echo set-output name=TARGET_ARCH::${TARGET_ARCH}
echo ::set-output name=TARGET_ARCH::${TARGET_ARCH} echo ::set-output name=TARGET_ARCH::${TARGET_ARCH}
unset TARGET_OS ; case ${{ matrix.job.target }} in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac; unset TARGET_OS ; case ${{ matrix.job.target }} in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac;
echo set-output name=TARGET_OS::${TARGET_OS} echo set-output name=TARGET_OS::${TARGET_OS}
echo ::set-output name=TARGET_OS::${TARGET_OS} echo ::set-output name=TARGET_OS::${TARGET_OS}
# package name # package name
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac; PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
PKG_BASENAME=${PROJECT_NAME}-${REF_TAG:-$REF_SHAS}-${{ matrix.job.target }} PKG_BASENAME=${PROJECT_NAME}-${REF_TAG:-$REF_SHAS}-${{ matrix.job.target }}
PKG_NAME=${PKG_BASENAME}${PKG_suffix} PKG_NAME=${PKG_BASENAME}${PKG_suffix}
echo set-output name=PKG_suffix::${PKG_suffix} echo set-output name=PKG_suffix::${PKG_suffix}
echo set-output name=PKG_BASENAME::${PKG_BASENAME} echo set-output name=PKG_BASENAME::${PKG_BASENAME}
echo set-output name=PKG_NAME::${PKG_NAME} echo set-output name=PKG_NAME::${PKG_NAME}
echo ::set-output name=PKG_suffix::${PKG_suffix} echo ::set-output name=PKG_suffix::${PKG_suffix}
echo ::set-output name=PKG_BASENAME::${PKG_BASENAME} echo ::set-output name=PKG_BASENAME::${PKG_BASENAME}
echo ::set-output name=PKG_NAME::${PKG_NAME} echo ::set-output name=PKG_NAME::${PKG_NAME}
# deployable tag? (ie, leading "vM" or "M"; M == version number) # deployable tag? (ie, leading "vM" or "M"; M == version number)
unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi unset DEPLOY ; if [[ $REF_TAG =~ ^[vV]?[0-9].* ]]; then DEPLOY='true' ; fi
echo set-output name=DEPLOY::${DEPLOY:-<empty>/false} echo set-output name=DEPLOY::${DEPLOY:-<empty>/false}
echo ::set-output name=DEPLOY::${DEPLOY} echo ::set-output name=DEPLOY::${DEPLOY}
# target-specific options # target-specific options
# * CARGO_FEATURES_OPTION # * CARGO_FEATURES_OPTION
CARGO_FEATURES_OPTION='' ; CARGO_FEATURES_OPTION='' ;
if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi
echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} echo set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION} echo ::set-output name=CARGO_FEATURES_OPTION::${CARGO_FEATURES_OPTION}
# * CARGO_USE_CROSS (truthy) # * CARGO_USE_CROSS (truthy)
CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac; CARGO_USE_CROSS='true' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) unset CARGO_USE_CROSS ;; esac;
echo set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS:-<empty>/false} echo set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS:-<empty>/false}
echo ::set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS} echo ::set-output name=CARGO_USE_CROSS::${CARGO_USE_CROSS}
# # * `arm` cannot be tested on ubuntu-* hosts (b/c testing is currently primarily done via comparison of target outputs with built-in outputs and the `arm` target is not executable on the host) # # * `arm` cannot be tested on ubuntu-* hosts (b/c testing is currently primarily done via comparison of target outputs with built-in outputs and the `arm` target is not executable on the host)
JOB_DO_TESTING="true" JOB_DO_TESTING="true"
case ${{ matrix.job.target }} in arm-*|aarch64-*) unset JOB_DO_TESTING ;; esac; case ${{ matrix.job.target }} in arm-*|aarch64-*) unset JOB_DO_TESTING ;; esac;
echo set-output name=JOB_DO_TESTING::${JOB_DO_TESTING:-<empty>/false} echo set-output name=JOB_DO_TESTING::${JOB_DO_TESTING:-<empty>/false}
echo ::set-output name=JOB_DO_TESTING::${JOB_DO_TESTING} echo ::set-output name=JOB_DO_TESTING::${JOB_DO_TESTING}
# # * test only binary for arm-type targets # # * test only binary for arm-type targets
unset CARGO_TEST_OPTIONS unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-*|aarch64-*) CARGO_TEST_OPTIONS="--bin ${PROJECT_NAME}" ;; esac; unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-*|aarch64-*) CARGO_TEST_OPTIONS="--bin ${PROJECT_NAME}" ;; esac;
echo set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} echo set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS} echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
# * strip executable? # * strip executable?
STRIP="strip" ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; *-pc-windows-msvc) STRIP="" ;; aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; aarch64-unknown-linux-musl) STRIP="" ;;esac; STRIP="strip" ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; *-pc-windows-msvc) STRIP="" ;; aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;; aarch64-unknown-linux-musl) STRIP="" ;;esac;
echo set-output name=STRIP::${STRIP} echo set-output name=STRIP::${STRIP}
echo ::set-output name=STRIP::${STRIP} echo ::set-output name=STRIP::${STRIP}
- name: Create all needed build/work directories - name: Create all needed build/work directories
shell: bash shell: bash
run: | run: |
mkdir -p '${{ steps.vars.outputs.STAGING }}' mkdir -p '${{ steps.vars.outputs.STAGING }}'
mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}' mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}'
- name: rust toolchain ~ install - name: rust toolchain ~ install
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: ${{ steps.vars.outputs.TOOLCHAIN }} toolchain: ${{ steps.vars.outputs.TOOLCHAIN }}
target: ${{ matrix.job.target }} target: ${{ matrix.job.target }}
override: true override: true
profile: minimal # minimal component installation (ie, no documentation) profile: minimal # minimal component installation (ie, no documentation)
- name: Info - name: Info
shell: bash shell: bash
run: | run: |
gcc --version || true gcc --version || true
rustup -V rustup -V
rustup toolchain list rustup toolchain list
rustup default rustup default
cargo -V cargo -V
rustc -V rustc -V
- name: Build - name: Build
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: build command: build
args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
- name: Install cargo-deb - name: Install cargo-deb
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: install command: install
args: cargo-deb args: cargo-deb
if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl' if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl'
- name: Build deb - name: Build deb
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: deb command: deb
args: --no-build --target=${{ matrix.job.target }} args: --no-build --target=${{ matrix.job.target }}
if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl' if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl'
- name: Test - name: Test
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }} use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
command: test command: test
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }}
- name: Archive executable artifacts - name: Archive executable artifacts
uses: actions/upload-artifact@master uses: actions/upload-artifact@master
with: with:
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }} name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }} path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
- name: Archive deb artifacts - name: Archive deb artifacts
uses: actions/upload-artifact@master uses: actions/upload-artifact@master
with: with:
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}.deb name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}.deb
path: target/${{ matrix.job.target }}/debian path: target/${{ matrix.job.target }}/debian
if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl' if: matrix.job.target == 'i686-unknown-linux-musl' || matrix.job.target == 'x86_64-unknown-linux-musl'
- name: Package - name: Package
shell: bash shell: bash
run: | run: |
# binary # binary
cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' cp 'target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
# `strip` binary (if needed) # `strip` binary (if needed)
if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' ; fi if [ -n "${{ steps.vars.outputs.STRIP }}" ]; then "${{ steps.vars.outputs.STRIP }}" '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}' ; fi
# README and LICENSE # README and LICENSE
cp README.md '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' cp README.md '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
cp LICENSE '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/' cp LICENSE '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
# base compressed package # base compressed package
pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null
case ${{ matrix.job.target }} in case ${{ matrix.job.target }} in
*-pc-windows-*) 7z -y a '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* | tail -2 ;; *-pc-windows-*) 7z -y a '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* | tail -2 ;;
*) tar czf '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* ;; *) tar czf '${{ steps.vars.outputs.PKG_NAME }}' '${{ steps.vars.outputs.PKG_BASENAME }}'/* ;;
esac; esac;
popd >/dev/null popd >/dev/null
- name: Publish - name: Publish
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
if: steps.vars.outputs.DEPLOY if: steps.vars.outputs.DEPLOY
with: with:
files: | files: |
${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }} ${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }}
target/${{ matrix.job.target }}/debian/*.deb target/${{ matrix.job.target }}/debian/*.deb
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
## fix! [rivy; 2020-22-01] `cargo tarpaulin` is unable to test this repo at the moment; alternate recipe or another testing framework? ## fix! [rivy; 2020-22-01] `cargo tarpaulin` is unable to test this repo at the moment; alternate recipe or another testing framework?
# coverage: # coverage:
Generated
+33 -1
View File
@@ -118,6 +118,12 @@ dependencies = [
"toml", "toml",
] ]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.6" version = "0.5.6"
@@ -197,10 +203,11 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]] [[package]]
name = "du-dust" name = "du-dust"
version = "0.8.2" version = "0.8.3"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"assert_cmd", "assert_cmd",
"atty",
"clap", "clap",
"clap_complete", "clap_complete",
"config-file", "config-file",
@@ -210,6 +217,7 @@ dependencies = [
"regex", "regex",
"serde", "serde",
"stfu8", "stfu8",
"sysinfo",
"tempfile", "tempfile",
"terminal_size", "terminal_size",
"thousands", "thousands",
@@ -322,6 +330,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "ntapi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "num_cpus" name = "num_cpus"
version = "1.13.1" version = "1.13.1"
@@ -518,6 +535,21 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sysinfo"
version = "0.26.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
dependencies = [
"cfg-if",
"core-foundation-sys",
"libc",
"ntapi",
"once_cell",
"rayon",
"winapi",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.3.0" version = "3.3.0"
+3 -1
View File
@@ -1,7 +1,7 @@
[package] [package]
name = "du-dust" name = "du-dust"
description = "A more intuitive version of du" description = "A more intuitive version of du"
version = "0.8.2" version = "0.8.3"
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"] authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
@@ -28,6 +28,7 @@ strip = true
[dependencies] [dependencies]
ansi_term = "0.12" ansi_term = "0.12"
atty = "0.2.14"
clap = "3.2.17" clap = "3.2.17"
lscolors = "0.7" lscolors = "0.7"
terminal_size = "0.1" terminal_size = "0.1"
@@ -39,6 +40,7 @@ regex = "1"
config-file = "0.2" config-file = "0.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
directories = "4" directories = "4"
sysinfo = "0.26"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi-util = "0.1" winapi-util = "0.1"
+23 -18
View File
@@ -1,4 +1,3 @@
[![Build Status](https://travis-ci.org/bootandy/dust.svg?branch=master)](https://travis-ci.org/bootandy/dust) [![Build Status](https://travis-ci.org/bootandy/dust.svg?branch=master)](https://travis-ci.org/bootandy/dust)
# Dust # Dust
@@ -10,35 +9,41 @@ du + rust = dust. Like du but more intuitive.
Because I want an easy way to see where my disk is being used. Because I want an easy way to see where my disk is being used.
# Demo # Demo
![Example](media/snap.png) ![Example](media/snap.png)
## Install ## Install
#### Cargo <a href="https://repology.org/project/du-dust/versions"><img src="https://repology.org/badge/vertical-allrepos/du-dust.svg" alt="Packaging status" align="right"></a> #### Cargo <a href="https://repology.org/project/du-dust/versions"><img src="https://repology.org/badge/vertical-allrepos/du-dust.svg" alt="Packaging status" align="right"></a>
* `cargo install du-dust` - `cargo install du-dust`
#### 🍺 Homebrew (Mac OS) #### 🍺 Homebrew (Mac OS)
* `brew install dust` - `brew install dust`
#### 🍺 Homebrew (Linux) #### 🍺 Homebrew (Linux)
* `brew tap tgotwig/linux-dust && brew install dust` - `brew tap tgotwig/linux-dust && brew install dust`
#### [Pacstall](https://github.com/pacstall/pacstall) (Debian/Ubuntu) #### [Pacstall](https://github.com/pacstall/pacstall) (Debian/Ubuntu)
* `pacstall -I dust-bin` - `pacstall -I dust-bin`
#### [deb-get](https://github.com/wimpysworld/deb-get) (Debian/Ubuntu)
- `deb-get install du-dust`
#### Windows: #### Windows:
* Windows GNU version - works
* Windows MSVC - requires: [VCRUNTIME140.dll](https://docs.microsoft.com/en-gb/cpp/windows/latest-supported-vc-redist?view=msvc-170) - Windows GNU version - works
- Windows MSVC - requires: [VCRUNTIME140.dll](https://docs.microsoft.com/en-gb/cpp/windows/latest-supported-vc-redist?view=msvc-170)
#### Download #### Download
* Download Linux/Mac binary from [Releases](https://github.com/bootandy/dust/releases) - Download Linux/Mac binary from [Releases](https://github.com/bootandy/dust/releases)
* unzip file: `tar -xvf _downloaded_file.tar.gz` - unzip file: `tar -xvf _downloaded_file.tar.gz`
* move file to executable path: `sudo mv dust /usr/local/bin/` - move file to executable path: `sudo mv dust /usr/local/bin/`
## Overview ## Overview
@@ -58,6 +63,7 @@ Usage: dust -p (full-path - Show fullpath of the subdirectories)
Usage: dust -s (apparent-size - shows the length of the file as opposed to the amount of disk space it uses) Usage: dust -s (apparent-size - shows the length of the file as opposed to the amount of disk space it uses)
Usage: dust -n 30 (Shows 30 directories instead of the default [default is terminal height]) Usage: dust -n 30 (Shows 30 directories instead of the default [default is terminal height])
Usage: dust -d 3 (Shows 3 levels of subdirectories) Usage: dust -d 3 (Shows 3 levels of subdirectories)
Usage: dust -D (Show only directories (eg dust -D))
Usage: dust -r (reverse order of output) Usage: dust -r (reverse order of output)
Usage: dust -H (si print sizes in powers of 1000 instead of 1024) Usage: dust -H (si print sizes in powers of 1000 instead of 1024)
Usage: dust -X ignore (ignore all files and directories with the name 'ignore') Usage: dust -X ignore (ignore all files and directories with the name 'ignore')
@@ -69,18 +75,17 @@ Usage: dust -f (Count files instead of diskspace)
Usage: dust -t (Group by filetype) Usage: dust -t (Group by filetype)
Usage: dust -z 10M (min-size, Only include files larger than 10M) Usage: dust -z 10M (min-size, Only include files larger than 10M)
Usage: dust -e regex (Only include files matching this regex (eg dust -e "\.png$" would match png files)) Usage: dust -e regex (Only include files matching this regex (eg dust -e "\.png$" would match png files))
Usage: dust -v regex (Exculde files matching this regex (eg dust -v "\.png$" would ignore png files)) Usage: dust -v regex (Exclude files matching this regex (eg dust -v "\.png$" would ignore png files))
``` ```
## Alternatives ## Alternatives
* [NCDU](https://dev.yorhel.nl/ncdu) - [NCDU](https://dev.yorhel.nl/ncdu)
* [dutree](https://github.com/nachoparker/dutree) - [dutree](https://github.com/nachoparker/dutree)
* [dua](https://github.com/Byron/dua-cli/) - [dua](https://github.com/Byron/dua-cli/)
* [pdu](https://github.com/KSXGitHub/parallel-disk-usage) - [pdu](https://github.com/KSXGitHub/parallel-disk-usage)
* [dirstat-rs](https://github.com/scullionw/dirstat-rs) - [dirstat-rs](https://github.com/scullionw/dirstat-rs)
* du -d 1 -h | sort -h - du -d 1 -h | sort -h
Note: Apparent-size is calculated slightly differently in dust to gdu. In dust each hard link is counted as using file_length space. In gdu only the first entry is counted. Note: Apparent-size is calculated slightly differently in dust to gdu. In dust each hard link is counted as using file_length space. In gdu only the first entry is counted.
+6
View File
@@ -35,6 +35,10 @@ _dust() {
'--version[Print version information]' \ '--version[Print version information]' \
'-p[Subdirectories will not have their path shortened]' \ '-p[Subdirectories will not have their path shortened]' \
'--full-paths[Subdirectories will not have their path shortened]' \ '--full-paths[Subdirectories will not have their path shortened]' \
'(-L --dereference-links)-l[Ignore links]' \
'(-L --dereference-links)--ignore-links[Ignore links]' \
'(-l --ignore-links)-L[dereference sym links - Treat sym links as directories and go into them]' \
'(-l --ignore-links)--dereference-links[dereference sym links - Treat sym links as directories and go into them]' \
'-x[Only count the files and directories on the same filesystem as the supplied directory]' \ '-x[Only count the files and directories on the same filesystem as the supplied directory]' \
'--limit-filesystem[Only count the files and directories on the same filesystem as the supplied directory]' \ '--limit-filesystem[Only count the files and directories on the same filesystem as the supplied directory]' \
'-s[Use file length instead of blocks]' \ '-s[Use file length instead of blocks]' \
@@ -54,6 +58,8 @@ _dust() {
'(-d --depth)--file_types[show only these file types]' \ '(-d --depth)--file_types[show only these file types]' \
'-H[print sizes in powers of 1000 (e.g., 1.1G)]' \ '-H[print sizes in powers of 1000 (e.g., 1.1G)]' \
'--si[print sizes in powers of 1000 (e.g., 1.1G)]' \ '--si[print sizes in powers of 1000 (e.g., 1.1G)]' \
'-D[Only directories will be displayed.]' \
'--only-dir[Only directories will be displayed.]' \
'*::inputs:' \ '*::inputs:' \
&& ret=0 && ret=0
} }
+6
View File
@@ -41,6 +41,10 @@ Register-ArgumentCompleter -Native -CommandName 'dust' -ScriptBlock {
[CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version information')
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened') [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened')
[CompletionResult]::new('--full-paths', 'full-paths', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened') [CompletionResult]::new('--full-paths', 'full-paths', [CompletionResultType]::ParameterName, 'Subdirectories will not have their path shortened')
[CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Ignore links')
[CompletionResult]::new('--ignore-links', 'ignore-links', [CompletionResultType]::ParameterName, 'Ignore links')
[CompletionResult]::new('-L', 'L', [CompletionResultType]::ParameterName, 'dereference sym links - Treat sym links as directories and go into them')
[CompletionResult]::new('--dereference-links', 'dereference-links', [CompletionResultType]::ParameterName, 'dereference sym links - Treat sym links as directories and go into them')
[CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory') [CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory')
[CompletionResult]::new('--limit-filesystem', 'limit-filesystem', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory') [CompletionResult]::new('--limit-filesystem', 'limit-filesystem', [CompletionResultType]::ParameterName, 'Only count the files and directories on the same filesystem as the supplied directory')
[CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Use file length instead of blocks') [CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Use file length instead of blocks')
@@ -60,6 +64,8 @@ Register-ArgumentCompleter -Native -CommandName 'dust' -ScriptBlock {
[CompletionResult]::new('--file_types', 'file_types', [CompletionResultType]::ParameterName, 'show only these file types') [CompletionResult]::new('--file_types', 'file_types', [CompletionResultType]::ParameterName, 'show only these file types')
[CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)') [CompletionResult]::new('-H', 'H', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)')
[CompletionResult]::new('--si', 'si', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)') [CompletionResult]::new('--si', 'si', [CompletionResultType]::ParameterName, 'print sizes in powers of 1000 (e.g., 1.1G)')
[CompletionResult]::new('-D', 'D', [CompletionResultType]::ParameterName, 'Only directories will be displayed.')
[CompletionResult]::new('--only-dir', 'only-dir', [CompletionResultType]::ParameterName, 'Only directories will be displayed.')
break break
} }
}) })
+1 -1
View File
@@ -19,7 +19,7 @@ _dust() {
case "${cmd}" in case "${cmd}" in
dust) dust)
opts="-h -V -d -n -p -X -x -s -r -c -b -z -f -i -v -e -t -w -H --help --version --depth --number-of-lines --full-paths --ignore-directory --limit-filesystem --apparent-size --reverse --no-colors --no-percent-bars --min-size --skip-total --filecount --ignore_hidden --invert-filter --filter --file_types --terminal_width --si <inputs>..." opts="-h -V -d -n -p -X -l -L -x -s -r -c -b -z -f -i -v -e -t -w -H -D --help --version --depth --number-of-lines --full-paths --ignore-directory --ignore-links --dereference-links --limit-filesystem --apparent-size --reverse --no-colors --no-percent-bars --min-size --skip-total --filecount --ignore_hidden --invert-filter --filter --file_types --terminal_width --si --only-dir <inputs>..."
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0 return 0
+6
View File
@@ -38,6 +38,10 @@ set edit:completion:arg-completer[dust] = {|@words|
cand --version 'Print version information' cand --version 'Print version information'
cand -p 'Subdirectories will not have their path shortened' cand -p 'Subdirectories will not have their path shortened'
cand --full-paths 'Subdirectories will not have their path shortened' cand --full-paths 'Subdirectories will not have their path shortened'
cand -l 'Ignore links'
cand --ignore-links 'Ignore links'
cand -L 'dereference sym links - Treat sym links as directories and go into them'
cand --dereference-links 'dereference sym links - Treat sym links as directories and go into them'
cand -x 'Only count the files and directories on the same filesystem as the supplied directory' cand -x 'Only count the files and directories on the same filesystem as the supplied directory'
cand --limit-filesystem 'Only count the files and directories on the same filesystem as the supplied directory' cand --limit-filesystem 'Only count the files and directories on the same filesystem as the supplied directory'
cand -s 'Use file length instead of blocks' cand -s 'Use file length instead of blocks'
@@ -57,6 +61,8 @@ set edit:completion:arg-completer[dust] = {|@words|
cand --file_types 'show only these file types' cand --file_types 'show only these file types'
cand -H 'print sizes in powers of 1000 (e.g., 1.1G)' cand -H 'print sizes in powers of 1000 (e.g., 1.1G)'
cand --si 'print sizes in powers of 1000 (e.g., 1.1G)' cand --si 'print sizes in powers of 1000 (e.g., 1.1G)'
cand -D 'Only directories will be displayed.'
cand --only-dir 'Only directories will be displayed.'
} }
] ]
$completions[$command] $completions[$command]
+3
View File
@@ -8,6 +8,8 @@ complete -c dust -s w -l terminal_width -d 'Specify width of output overriding t
complete -c dust -s h -l help -d 'Print help information' complete -c dust -s h -l help -d 'Print help information'
complete -c dust -s V -l version -d 'Print version information' complete -c dust -s V -l version -d 'Print version information'
complete -c dust -s p -l full-paths -d 'Subdirectories will not have their path shortened' complete -c dust -s p -l full-paths -d 'Subdirectories will not have their path shortened'
complete -c dust -s l -l ignore-links -d 'Ignore links'
complete -c dust -s L -l dereference-links -d 'dereference sym links - Treat sym links as directories and go into them'
complete -c dust -s x -l limit-filesystem -d 'Only count the files and directories on the same filesystem as the supplied directory' complete -c dust -s x -l limit-filesystem -d 'Only count the files and directories on the same filesystem as the supplied directory'
complete -c dust -s s -l apparent-size -d 'Use file length instead of blocks' complete -c dust -s s -l apparent-size -d 'Use file length instead of blocks'
complete -c dust -s r -l reverse -d 'Print tree upside down (biggest highest)' complete -c dust -s r -l reverse -d 'Print tree upside down (biggest highest)'
@@ -18,3 +20,4 @@ complete -c dust -s f -l filecount -d 'Directory \'size\' is number of child fil
complete -c dust -s i -l ignore_hidden -d 'Do not display hidden files' complete -c dust -s i -l ignore_hidden -d 'Do not display hidden files'
complete -c dust -s t -l file_types -d 'show only these file types' complete -c dust -s t -l file_types -d 'show only these file types'
complete -c dust -s H -l si -d 'print sizes in powers of 1000 (e.g., 1.1G)' complete -c dust -s H -l si -d 'print sizes in powers of 1000 (e.g., 1.1G)'
complete -c dust -s D -l only-dir -d 'Only directories will be displayed.'
+21 -1
View File
@@ -34,6 +34,20 @@ pub fn build_cli() -> Command<'static> {
.multiple_occurrences(true) .multiple_occurrences(true)
.help("Exclude any file or directory with this name"), .help("Exclude any file or directory with this name"),
) )
.arg(
Arg::new("ignore_links")
.short('l')
.long("ignore-links")
.conflicts_with("dereference_links")
.help("Ignore links"),
)
.arg(
Arg::new("dereference_links")
.short('L')
.long("dereference-links")
.conflicts_with("ignore_links")
.help("dereference sym links - Treat sym links as directories and go into them"),
)
.arg( .arg(
Arg::new("limit_filesystem") Arg::new("limit_filesystem")
.short('x') .short('x')
@@ -131,5 +145,11 @@ pub fn build_cli() -> Command<'static> {
.long("si") .long("si")
.help("print sizes in powers of 1000 (e.g., 1.1G)") .help("print sizes in powers of 1000 (e.g., 1.1G)")
) )
.arg(Arg::new("inputs").multiple_occurrences(true).default_value(".")) .arg(Arg::new("inputs").multiple_occurrences(true))
.arg(
Arg::new("only_dir")
.short('D')
.long("only-dir")
.help("Only directories will be displayed."),
)
} }
+4
View File
@@ -19,6 +19,7 @@ pub struct Config {
pub ignore_hidden: Option<bool>, pub ignore_hidden: Option<bool>,
pub iso: Option<bool>, pub iso: Option<bool>,
pub min_size: Option<String>, pub min_size: Option<String>,
pub only_dir: Option<bool>,
} }
impl Config { impl Config {
@@ -61,6 +62,9 @@ impl Config {
size_from_param size_from_param
} }
} }
pub fn get_only_dir(&self, options: &ArgMatches) -> bool {
Some(true) == self.only_dir || options.is_present("only_dir")
}
} }
fn convert_min_size(input: &str, iso: bool) -> Option<usize> { fn convert_min_size(input: &str, iso: bool) -> Option<usize> {
+22 -17
View File
@@ -26,6 +26,8 @@ pub struct WalkData<'a> {
pub use_apparent_size: bool, pub use_apparent_size: bool,
pub by_filecount: bool, pub by_filecount: bool,
pub ignore_hidden: bool, pub ignore_hidden: bool,
pub ignore_links: bool,
pub follow_links: bool,
} }
pub fn walk_it(dirs: HashSet<PathBuf>, walk_data: WalkData) -> (Vec<Node>, bool) { pub fn walk_it(dirs: HashSet<PathBuf>, walk_data: WalkData) -> (Vec<Node>, bool) {
@@ -141,24 +143,27 @@ fn walk(
// return walk(entry.path(), permissions_flag, ignore_directories, allowed_filesystems, use_apparent_size, by_filecount, ignore_hidden); // return walk(entry.path(), permissions_flag, ignore_directories, allowed_filesystems, use_apparent_size, by_filecount, ignore_hidden);
if !ignore_file(entry, walk_data) { if ignore_file(entry, walk_data) {
if let Ok(data) = entry.file_type() { return None;
return if data.is_dir() && !data.is_symlink() { }
walk(entry.path(), permissions_flag, walk_data, depth + 1) if let Ok(data) = entry.file_type() {
} else { if data.is_symlink() && walk_data.ignore_links {
build_node( return None;
entry.path(),
vec![],
walk_data.filter_regex,
walk_data.invert_filter_regex,
walk_data.use_apparent_size,
data.is_symlink(),
data.is_file(),
walk_data.by_filecount,
depth,
)
};
} }
if data.is_dir() || (walk_data.follow_links && data.is_symlink()) {
return walk(entry.path(), permissions_flag, walk_data, depth + 1);
}
return build_node(
entry.path(),
vec![],
walk_data.filter_regex,
walk_data.invert_filter_regex,
walk_data.use_apparent_size,
data.is_symlink(),
data.is_file(),
walk_data.by_filecount,
depth,
);
} }
} else { } else {
permissions_flag.store(true, atomic::Ordering::Relaxed); permissions_flag.store(true, atomic::Ordering::Relaxed);
+3 -3
View File
@@ -88,7 +88,7 @@ impl DrawData<'_> {
let mut num_not_my_bar = (chars_in_bar as i32) - num_bars as i32; let mut num_not_my_bar = (chars_in_bar as i32) - num_bars as i32;
let mut new_bar = "".to_string(); let mut new_bar = "".to_string();
let idx = 5 - min(4, max(1, level)); let idx = 5 - level.clamp(1, 4);
for c in self.percent_bar.chars() { for c in self.percent_bar.chars() {
num_not_my_bar -= 1; num_not_my_bar -= 1;
@@ -141,10 +141,10 @@ pub fn draw_it(
let longest_string_length = let longest_string_length =
find_longest_dir_name(root_node, num_indent_chars, allowed_width, !use_full_path); find_longest_dir_name(root_node, num_indent_chars, allowed_width, !use_full_path);
let max_bar_length = if no_percent_bars || longest_string_length + 7 >= allowed_width as usize { let max_bar_length = if no_percent_bars || longest_string_length + 7 >= allowed_width {
0 0
} else { } else {
allowed_width as usize - longest_string_length - 7 allowed_width - longest_string_length - 7
}; };
let first_size_bar = repeat(BLOCKS[0]).take(max_bar_length).collect(); let first_size_bar = repeat(BLOCKS[0]).take(max_bar_length).collect();
+14 -6
View File
@@ -8,6 +8,7 @@ use std::path::PathBuf;
pub fn get_biggest( pub fn get_biggest(
top_level_nodes: Vec<Node>, top_level_nodes: Vec<Node>,
min_size: Option<usize>, min_size: Option<usize>,
only_dir: bool,
n: usize, n: usize,
depth: usize, depth: usize,
using_a_filter: bool, using_a_filter: bool,
@@ -23,14 +24,14 @@ pub fn get_biggest(
let mut allowed_nodes = HashSet::new(); let mut allowed_nodes = HashSet::new();
allowed_nodes.insert(root.name.as_path()); allowed_nodes.insert(root.name.as_path());
heap = add_children(using_a_filter, min_size, &root, depth, heap); heap = add_children(using_a_filter, min_size, only_dir, &root, depth, heap);
for _ in number_top_level_nodes..n { for _ in number_top_level_nodes..n {
let line = heap.pop(); let line = heap.pop();
match line { match line {
Some(line) => { Some(line) => {
allowed_nodes.insert(line.name.as_path()); allowed_nodes.insert(line.name.as_path());
heap = add_children(using_a_filter, min_size, line, depth, heap); heap = add_children(using_a_filter, min_size, only_dir, line, depth, heap);
} }
None => break, None => break,
} }
@@ -41,15 +42,22 @@ pub fn get_biggest(
fn add_children<'a>( fn add_children<'a>(
using_a_filter: bool, using_a_filter: bool,
min_size: Option<usize>, min_size: Option<usize>,
only_dir: bool,
file_or_folder: &'a Node, file_or_folder: &'a Node,
depth: usize, depth: usize,
mut heap: BinaryHeap<&'a Node>, mut heap: BinaryHeap<&'a Node>,
) -> BinaryHeap<&'a Node> { ) -> BinaryHeap<&'a Node> {
if depth > file_or_folder.depth { if depth > file_or_folder.depth {
heap.extend(file_or_folder.children.iter().filter(|c| match min_size { heap.extend(
Some(ms) => c.size > ms as u64, file_or_folder
None => !using_a_filter || c.name.is_file() || c.size > 0, .children
})) .iter()
.filter(|c| match min_size {
Some(ms) => c.size > ms as u64,
None => !using_a_filter || c.name.is_file() || c.size > 0,
})
.filter(|c| if only_dir { c.name.is_dir() } else { true }),
)
} }
heap heap
} }
+43 -9
View File
@@ -11,7 +11,9 @@ mod utils;
use crate::cli::build_cli; use crate::cli::build_cli;
use std::collections::HashSet; use std::collections::HashSet;
use std::io::BufRead;
use std::process; use std::process;
use sysinfo::{System, SystemExt};
use self::display::draw_it; use self::display::draw_it;
use clap::Values; use clap::Values;
@@ -19,6 +21,7 @@ use config::get_config;
use dir_walker::{walk_it, WalkData}; use dir_walker::{walk_it, WalkData};
use filter::get_biggest; use filter::get_biggest;
use filter_type::get_all_file_types; use filter_type::get_all_file_types;
use rayon::ThreadPoolBuildError;
use regex::Regex; use regex::Regex;
use std::cmp::max; use std::cmp::max;
use std::path::PathBuf; use std::path::PathBuf;
@@ -89,14 +92,28 @@ fn get_regex_value(maybe_value: Option<Values>) -> Vec<Regex> {
.collect() .collect()
} }
// Returns a list of lines from stdin or `None` if there's nothing to read
fn get_lines_from_stdin() -> Option<Vec<String>> {
atty::isnt(atty::Stream::Stdin).then(|| {
std::io::stdin()
.lock()
.lines()
.collect::<Result<_, _>>()
.expect("Error reading from stdin")
})
}
fn main() { fn main() {
let options = build_cli().get_matches(); let options = build_cli().get_matches();
let config = get_config(); let config = get_config();
let stdin_lines = get_lines_from_stdin();
let target_dirs = options let target_dirs = match options.values_of("inputs") {
.values_of("inputs") Some(values) => values.collect(),
.expect("Should be a default value here") None => stdin_lines.as_ref().map_or(vec!["."], |lines| {
.collect(); lines.iter().map(String::as_str).collect()
}),
};
let summarize_file_types = options.is_present("types"); let summarize_file_types = options.is_present("types");
@@ -135,6 +152,8 @@ fn main() {
let by_filecount = options.is_present("by_filecount"); let by_filecount = options.is_present("by_filecount");
let limit_filesystem = options.is_present("limit_filesystem"); let limit_filesystem = options.is_present("limit_filesystem");
let ignore_links = options.is_present("ignore_links");
let follow_links = options.is_present("dereference_links");
let simplified_dirs = simplify_dir_names(target_dirs); let simplified_dirs = simplify_dir_names(target_dirs);
let allowed_filesystems = limit_filesystem let allowed_filesystems = limit_filesystem
@@ -150,15 +169,13 @@ fn main() {
filter_regex: &filter_regexs, filter_regex: &filter_regexs,
invert_filter_regex: &invert_filter_regexs, invert_filter_regex: &invert_filter_regexs,
allowed_filesystems, allowed_filesystems,
ignore_links,
follow_links,
use_apparent_size: config.get_apparent_size(&options), use_apparent_size: config.get_apparent_size(&options),
by_filecount, by_filecount,
ignore_hidden: config.get_ignore_hidden(&options), ignore_hidden: config.get_ignore_hidden(&options),
}; };
// Larger stack size to handle cases with lots of nested directories let _rayon = init_rayon();
rayon::ThreadPoolBuilder::new()
.stack_size(usize::pow(1024, 3))
.build_global()
.unwrap();
let iso = config.get_iso(&options); let iso = config.get_iso(&options);
let (top_level_nodes, has_errors) = walk_it(simplified_dirs, walk_data); let (top_level_nodes, has_errors) = walk_it(simplified_dirs, walk_data);
@@ -168,6 +185,7 @@ fn main() {
false => get_biggest( false => get_biggest(
top_level_nodes, top_level_nodes,
config.get_min_size(&options, iso), config.get_min_size(&options, iso),
config.get_only_dir(&options),
number_of_lines, number_of_lines,
depth, depth,
options.values_of("filter").is_some() || options.value_of("invert_filter").is_some(), options.values_of("filter").is_some() || options.value_of("invert_filter").is_some(),
@@ -191,3 +209,19 @@ fn main() {
) )
} }
} }
fn init_rayon() -> Result<(), ThreadPoolBuildError> {
let large_stack = usize::pow(1024, 3);
let mut s = System::new();
s.refresh_memory();
let available = s.available_memory();
if available > large_stack.try_into().unwrap() {
// Larger stack size to handle cases with lots of nested directories
rayon::ThreadPoolBuilder::new()
.stack_size(large_stack)
.build_global()
} else {
Ok(())
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ static INIT: Once = Once::new();
/// Copy to /tmp dir - we assume that the formatting of the /tmp partition /// Copy to /tmp dir - we assume that the formatting of the /tmp partition
/// is consistent. If the tests fail your /tmp filesystem probably differs /// is consistent. If the tests fail your /tmp filesystem probably differs
fn copy_test_data(dir: &str) { fn copy_test_data(dir: &str) {
// First remove the existing directory - just incase it is there and has incorrect data // First remove the existing directory - just in case it is there and has incorrect data
let last_slash = dir.rfind('/').unwrap(); let last_slash = dir.rfind('/').unwrap();
let last_part_of_dir = dir.chars().skip(last_slash).collect::<String>(); let last_part_of_dir = dir.chars().skip(last_slash).collect::<String>();
let _ = Command::new("rm") let _ = Command::new("rm")
@@ -196,7 +196,7 @@ pub fn test_apparent_size() {
} }
fn apparent_size_output() -> Vec<String> { fn apparent_size_output() -> Vec<String> {
// The apparent directory sizes are too unpredictable and system dependant to try and match // The apparent directory sizes are too unpredictable and system dependent to try and match
let files = r#" let files = r#"
0B ┌── a_file 0B ┌── a_file
6B ├── hello_file 6B ├── hello_file