mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d2b959fdcf | |||
| 36ebb1b2b0 | |||
| e126a01096 | |||
| 7a38a26593 | |||
| 1af6e1f757 | |||
| affafcc5f2 | |||
| 26ef8c3e59 | |||
| 0898ee6bf0 | |||
| 5ac168868e | |||
| 684994ee11 | |||
| 416ad517fe | |||
| 7c34389aea | |||
| 18510130d8 | |||
| 0bf8c914b7 | |||
| 95888d5f31 | |||
| 5d195e27cb | |||
| 0c7b05fec9 | |||
| bc895879e6 | |||
| 31f01c061a | |||
| 17894e723c | |||
| 6141ddddea | |||
| 352c0f7d90 | |||
| 842a8ec673 | |||
| d97edba041 | |||
| f64e0094f1 | |||
| 3d2477e554 | |||
| 350d695f7c | |||
| f8b8b8a788 | |||
| b9c27f9838 | |||
| 5541df6a73 | |||
| bdc3d404ef | |||
| f395a7d768 | |||
| a36eec6cae | |||
| 38938e005e | |||
| da61b15715 | |||
| 0b22d0a977 | |||
| 356d14ac0f | |||
| 311bc45388 | |||
| ef66fb3938 | |||
| b934445e04 | |||
| a6839c020f | |||
| 7e47d5b47a | |||
| 6a65570f3f | |||
| a4ca78dbe4 | |||
| bfbe8a57ae | |||
| b4b73e45f3 | |||
| 78119aba0f | |||
| 5535478fe8 | |||
| 7ba91a4a22 | |||
| 79416fd5fc | |||
| b66523cff3 | |||
| 19a41aa382 | |||
| 62ac9b623a | |||
| bf28d42483 | |||
| f8ce6c97bf | |||
| 86b3cccaf6 | |||
| 3c920431fa | |||
| a1ece05af5 | |||
| cef2c588b7 | |||
| 7d8e498238 | |||
| 53c7a69dcb | |||
| 9a9cbefd3d | |||
| 224a2c6f25 | |||
| 99003cbba9 | |||
| c83803b440 | |||
| a41862d799 | |||
| 6ab46d8471 | |||
| c727eb2d11 | |||
| 0effaa7fd7 | |||
| 25c50f88c4 | |||
| 0c19a66432 | |||
| 4cffc4370b | |||
| db6c8a019d | |||
| e03094a4fa | |||
| 1d9a56e025 | |||
| ec2d9e19d4 | |||
| 9fbfcb275a | |||
| 1c60d1e2ac | |||
| fd35734a94 | |||
| c6f4ace2b6 | |||
| d46b63fad8 | |||
| 872a49bb7d | |||
| 04c6c204c3 | |||
| 7ac01e8166 | |||
| 2f7a88e8dc | |||
| 2ca2cebdad | |||
| 80338f4731 | |||
| d327bd2e68 | |||
| 7db6cf2f32 | |||
| 76d0762c97 | |||
| 6e03dd77e6 | |||
| 4906e9efda | |||
| 876609f2cb | |||
| 12775db94b | |||
| bfaf5ee173 | |||
| fd68330815 | |||
| 0bf4ebf554 | |||
| cab24f58d5 | |||
| b1b933d851 | |||
| 6a86e8befd | |||
| 3fb91a6c29 | |||
| 51561994c5 | |||
| ce0e14bf00 | |||
| dd75ec4aa7 | |||
| 65cd42736a | |||
| 4792e97177 | |||
| 3e9f09e339 | |||
| dba465a094 | |||
| 25d1ee7b43 | |||
| 2556885622 | |||
| 8c088a7026 | |||
| 39db8b86fd | |||
| c5830c5d00 | |||
| b68c450710 | |||
| 6e2e5761d8 |
@@ -0,0 +1,286 @@
|
|||||||
|
name: CICD
|
||||||
|
|
||||||
|
# spell-checker:ignore CICD CODECOV MSVC MacOS Peltoche SHAs buildable clippy esac fakeroot gnueabihf halium libssl mkdir musl popd printf pushd rustfmt softprops toolchain
|
||||||
|
|
||||||
|
env:
|
||||||
|
PROJECT_NAME: dust
|
||||||
|
PROJECT_DESC: "du + rust = dust"
|
||||||
|
PROJECT_AUTH: "bootandy"
|
||||||
|
RUST_MIN_SRV: "1.31.0"
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
style:
|
||||||
|
name: Style
|
||||||
|
runs-on: ${{ matrix.job.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { os: ubuntu-latest }
|
||||||
|
- { os: macos-latest }
|
||||||
|
- { os: windows-latest }
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Initialize workflow variables
|
||||||
|
id: vars
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# '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"
|
||||||
|
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}
|
||||||
|
- name: Install `rust` toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
override: true
|
||||||
|
profile: minimal # minimal component installation (ie, no documentation)
|
||||||
|
components: rustfmt, clippy
|
||||||
|
- name: "`fmt` testing"
|
||||||
|
if: steps.vars.outputs.JOB_DO_FORMAT_TESTING
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: fmt
|
||||||
|
args: --all -- --check
|
||||||
|
- name: "`clippy` testing"
|
||||||
|
if: success() || failure() # run regardless of prior step ("`fmt` testing") success/failure
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: clippy
|
||||||
|
args: ${{ matrix.job.cargo-options }} --features "${{ matrix.job.features }}" -- -D warnings
|
||||||
|
|
||||||
|
min_version:
|
||||||
|
name: MinSRV # Minimum supported rust version
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Install `rust` toolchain (v${{ env.RUST_MIN_SRV }})
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: ${{ env.RUST_MIN_SRV }}
|
||||||
|
profile: minimal # minimal component installation (ie, no documentation)
|
||||||
|
- name: Test
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ${{ matrix.job.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
# { os, target, cargo-options, features, use-cross, toolchain }
|
||||||
|
- { os: ubuntu-latest , target: arm-unknown-linux-gnueabihf , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-18.04 , target: i686-unknown-linux-gnu , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-18.04 , target: i686-unknown-linux-musl , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-18.04 , target: x86_64-unknown-linux-gnu , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-18.04 , target: x86_64-unknown-linux-musl , use-cross: use-cross }
|
||||||
|
- { os: ubuntu-16.04 , target: x86_64-unknown-linux-gnu , 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:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Install any prerequisites
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
case ${{ matrix.job.target }} in
|
||||||
|
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
||||||
|
esac
|
||||||
|
- name: Initialize workflow variables
|
||||||
|
id: vars
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# 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>)
|
||||||
|
case ${{ matrix.job.target }} in *-pc-windows-gnu) TOOLCHAIN="stable-${{ matrix.job.target }}" ;; esac;
|
||||||
|
# * use requested TOOLCHAIN if specified
|
||||||
|
if [ -n "${{ matrix.job.toolchain }}" ]; then TOOLCHAIN="${{ matrix.job.toolchain }}" ; fi
|
||||||
|
echo set-output name=TOOLCHAIN::${TOOLCHAIN}
|
||||||
|
echo ::set-output name=TOOLCHAIN::${TOOLCHAIN}
|
||||||
|
# staging directory
|
||||||
|
STAGING='_staging'
|
||||||
|
echo set-output name=STAGING::${STAGING}
|
||||||
|
echo ::set-output name=STAGING::${STAGING}
|
||||||
|
# determine EXE suffix
|
||||||
|
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}
|
||||||
|
# parse commit reference info
|
||||||
|
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}
|
||||||
|
echo set-output name=REF_NAME::${REF_NAME}
|
||||||
|
echo set-output name=REF_BRANCH::${REF_BRANCH}
|
||||||
|
echo set-output name=REF_TAG::${REF_TAG}
|
||||||
|
echo set-output name=REF_SHAS::${REF_SHAS}
|
||||||
|
echo ::set-output name=REF_NAME::${REF_NAME}
|
||||||
|
echo ::set-output name=REF_BRANCH::${REF_BRANCH}
|
||||||
|
echo ::set-output name=REF_TAG::${REF_TAG}
|
||||||
|
echo ::set-output name=REF_SHAS::${REF_SHAS}
|
||||||
|
# parse target
|
||||||
|
unset TARGET_ARCH ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) TARGET_ARCH=arm ;; 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}
|
||||||
|
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}
|
||||||
|
# package name
|
||||||
|
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_NAME=${PKG_BASENAME}${PKG_suffix}
|
||||||
|
echo set-output name=PKG_suffix::${PKG_suffix}
|
||||||
|
echo set-output name=PKG_BASENAME::${PKG_BASENAME}
|
||||||
|
echo set-output name=PKG_NAME::${PKG_NAME}
|
||||||
|
echo ::set-output name=PKG_suffix::${PKG_suffix}
|
||||||
|
echo ::set-output name=PKG_BASENAME::${PKG_BASENAME}
|
||||||
|
echo ::set-output name=PKG_NAME::${PKG_NAME}
|
||||||
|
# deployable tag? (ie, leading "vM" or "M"; M == version number)
|
||||||
|
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}
|
||||||
|
# target-specific options
|
||||||
|
# * CARGO_USE_CROSS (truthy)
|
||||||
|
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}
|
||||||
|
# # * `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"
|
||||||
|
case ${{ matrix.job.target }} in arm-*) 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}
|
||||||
|
# # * test only binary for arm-type targets
|
||||||
|
unset CARGO_TEST_OPTIONS
|
||||||
|
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-*) 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}
|
||||||
|
# * strip executable?
|
||||||
|
STRIP="strip" ; case ${{ matrix.job.target }} in arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;; *-pc-windows-msvc) STRIP="" ;; esac;
|
||||||
|
echo set-output name=STRIP::${STRIP}
|
||||||
|
echo ::set-output name=STRIP::${STRIP}
|
||||||
|
- name: Create all needed build/work directories
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p '${{ steps.vars.outputs.STAGING }}'
|
||||||
|
mkdir -p '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}'
|
||||||
|
- name: rust toolchain ~ install
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: ${{ steps.vars.outputs.TOOLCHAIN }}
|
||||||
|
target: ${{ matrix.job.target }}
|
||||||
|
override: true
|
||||||
|
profile: minimal # minimal component installation (ie, no documentation)
|
||||||
|
- name: Info
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
gcc --version || true
|
||||||
|
rustup -V
|
||||||
|
rustup toolchain list
|
||||||
|
rustup default
|
||||||
|
cargo -V
|
||||||
|
rustc -V
|
||||||
|
- name: Build
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
|
||||||
|
command: build
|
||||||
|
args: --release --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} --features "${{ matrix.job.features }}"
|
||||||
|
- name: Test
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
use-cross: ${{ steps.vars.outputs.CARGO_USE_CROSS }}
|
||||||
|
command: test
|
||||||
|
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} --features "${{ matrix.job.features }}"
|
||||||
|
- name: Archive executable artifacts
|
||||||
|
uses: actions/upload-artifact@master
|
||||||
|
with:
|
||||||
|
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
|
||||||
|
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# binary
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
cp README.md '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
|
||||||
|
cp LICENSE '${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_BASENAME }}/'
|
||||||
|
# base compressed package
|
||||||
|
pushd '${{ steps.vars.outputs.STAGING }}/' >/dev/null
|
||||||
|
case ${{ matrix.job.target }} in
|
||||||
|
*-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 }}'/* ;;
|
||||||
|
esac;
|
||||||
|
popd >/dev/null
|
||||||
|
- name: Publish
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: steps.vars.outputs.DEPLOY
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
${{ steps.vars.outputs.STAGING }}/${{ steps.vars.outputs.PKG_NAME }}
|
||||||
|
env:
|
||||||
|
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?
|
||||||
|
# coverage:
|
||||||
|
# name: Code Coverage
|
||||||
|
# runs-on: ${{ matrix.job.os }}
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: true
|
||||||
|
# matrix:
|
||||||
|
# # job: [ { os: ubuntu-latest }, { os: macos-latest }, { os: windows-latest } ]
|
||||||
|
# job: [ { os: ubuntu-latest } ] ## cargo-tarpaulin is currently only available on linux
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v1
|
||||||
|
# # - name: Reattach HEAD ## may be needed for accurate code coverage info
|
||||||
|
# # run: git checkout ${{ github.head_ref }}
|
||||||
|
# - name: Initialize workflow variables
|
||||||
|
# id: vars
|
||||||
|
# shell: bash
|
||||||
|
# run: |
|
||||||
|
# # staging directory
|
||||||
|
# STAGING='_staging'
|
||||||
|
# echo set-output name=STAGING::${STAGING}
|
||||||
|
# echo ::set-output name=STAGING::${STAGING}
|
||||||
|
# # check for CODECOV_TOKEN availability (work-around for inaccessible 'secrets' object for 'if'; see <https://github.community/t5/GitHub-Actions/jobs-lt-job-id-gt-if-does-not-work-with-env-secrets/m-p/38549>)
|
||||||
|
# unset HAS_CODECOV_TOKEN
|
||||||
|
# if [ -n $CODECOV_TOKEN ]; then HAS_CODECOV_TOKEN='true' ; fi
|
||||||
|
# echo set-output name=HAS_CODECOV_TOKEN::${HAS_CODECOV_TOKEN}
|
||||||
|
# echo ::set-output name=HAS_CODECOV_TOKEN::${HAS_CODECOV_TOKEN}
|
||||||
|
# env:
|
||||||
|
# CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
|
||||||
|
# - name: Create all needed build/work directories
|
||||||
|
# shell: bash
|
||||||
|
# run: |
|
||||||
|
# mkdir -p '${{ steps.vars.outputs.STAGING }}/work'
|
||||||
|
# - name: Install required packages
|
||||||
|
# run: |
|
||||||
|
# sudo apt-get -y install libssl-dev
|
||||||
|
# pushd '${{ steps.vars.outputs.STAGING }}/work' >/dev/null
|
||||||
|
# wget --no-verbose https://github.com/xd009642/tarpaulin/releases/download/0.9.3/cargo-tarpaulin-0.9.3-travis.tar.gz
|
||||||
|
# tar xf cargo-tarpaulin-0.9.3-travis.tar.gz
|
||||||
|
# cp cargo-tarpaulin "$(dirname -- "$(which cargo)")"/
|
||||||
|
# popd >/dev/null
|
||||||
|
# - name: Generate coverage
|
||||||
|
# run: |
|
||||||
|
# cargo tarpaulin --out Xml
|
||||||
|
# - name: Upload coverage results (CodeCov.io)
|
||||||
|
# # CODECOV_TOKEN (aka, "Repository Upload Token" for REPO from CodeCov.io) ## set via REPO/Settings/Secrets
|
||||||
|
# # if: secrets.CODECOV_TOKEN (not supported {yet?}; see <https://github.community/t5/GitHub-Actions/jobs-lt-job-id-gt-if-does-not-work-with-env-secrets/m-p/38549>)
|
||||||
|
# if: steps.vars.outputs.HAS_CODECOV_TOKEN
|
||||||
|
# run: |
|
||||||
|
# # CodeCov.io
|
||||||
|
# cargo tarpaulin --out Xml
|
||||||
|
# bash <(curl -s https://codecov.io/bash)
|
||||||
|
# env:
|
||||||
|
# CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
|
||||||
@@ -6,3 +6,4 @@
|
|||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
*.swp
|
*.swp
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
*.idea/*
|
||||||
+9
-2
@@ -1,6 +1,12 @@
|
|||||||
# Based on the "trust" template v0.1.2
|
# Based on the "trust" template v0.1.2
|
||||||
# https://github.com/japaric/trust/tree/v0.1.2
|
# https://github.com/japaric/trust/tree/v0.1.2
|
||||||
|
|
||||||
|
# ----------- To do a release ---------
|
||||||
|
# tag a commit and push:
|
||||||
|
# git tag v0.4.0.1
|
||||||
|
# git push origin v0.4.0.1
|
||||||
|
# Remember to do a cargo publish to put it in crates.io
|
||||||
|
|
||||||
dist: trusty
|
dist: trusty
|
||||||
language: rust
|
language: rust
|
||||||
services: docker
|
services: docker
|
||||||
@@ -46,8 +52,9 @@ deploy:
|
|||||||
# - Create a `public_repo` GitHub token. Go to: https://github.com/settings/tokens/new
|
# - Create a `public_repo` GitHub token. Go to: https://github.com/settings/tokens/new
|
||||||
# - Encrypt it: `travis encrypt 0123456789012345678901234567890123456789
|
# - Encrypt it: `travis encrypt 0123456789012345678901234567890123456789
|
||||||
# - Paste the output down here
|
# - Paste the output down here
|
||||||
api_key:
|
# api_key:
|
||||||
secure: UlU73Td7Bkb2N88ws4YGLWR+4U0IMgiou9QQtMnmpouJFjeUNxtLSPMPODVXP7zq4sKt5HR5B3fX9MW4mKm351fvnQEoihETn06pKiXGnY//SlTPTt67MX9ZOYmd9ohJReMDOZDgqhnGLxfymycGtsLAmdjDZnAl+IMqgg0FMyVFj9Cl9aKxnn12lxQyX4zabHKk8TUKD3By8ZoEUnJMHt3gEtOmbDgS4brcTPeHCzqnYFw73LEnkqvz+JP0XwauJY7Cf8lminKm/klmjCkQji8T9SHI52v1g0Fxpx0ucp2o3vulQrLHXaHvZ6Fr7J0cSXXzaFF3rrGLt4t4jU/+9TZm1+n5k5XuPW4x4NTCC9NmIj/z0/z41t82E9qZhzhtm2Jdsg6H2tNk+C774TYqcmR6GCvfRadfjRp3cA5dh0UwDVjH2MJFxlHDVkl6la0mVVRsCGF3oBKZVk0BDl1womfnmI46o/uU+gLknHN6Ed6PHHPPYDViWd3VKdmHKT7XrkMMUF6HjZUtla689DWIOWZSiV++1dVPcl/1TV+6tTmN4bBtPcLuX7SHRuLp2PI2kATvRMECsa7gZRypW4jKpVn7b2yetX9TVI3i1zR5zkQJ3dPg8sATvYPL53aKH/WsqUg4rzoAlbk9so+++R4bQY69LhV3B511B7EAynoZFdM
|
# secure: UlU73Td7Bkb2N88ws4YGLWR+4U0IMgiou9QQtMnmpouJFjeUNxtLSPMPODVXP7zq4sKt5HR5B3fX9MW4mKm351fvnQEoihETn06pKiXGnY//SlTPTt67MX9ZOYmd9ohJReMDOZDgqhnGLxfymycGtsLAmdjDZnAl+IMqgg0FMyVFj9Cl9aKxnn12lxQyX4zabHKk8TUKD3By8ZoEUnJMHt3gEtOmbDgS4brcTPeHCzqnYFw73LEnkqvz+JP0XwauJY7Cf8lminKm/klmjCkQji8T9SHI52v1g0Fxpx0ucp2o3vulQrLHXaHvZ6Fr7J0cSXXzaFF3rrGLt4t4jU/+9TZm1+n5k5XuPW4x4NTCC9NmIj/z0/z41t82E9qZhzhtm2Jdsg6H2tNk+C774TYqcmR6GCvfRadfjRp3cA5dh0UwDVjH2MJFxlHDVkl6la0mVVRsCGF3oBKZVk0BDl1womfnmI46o/uU+gLknHN6Ed6PHHPPYDViWd3VKdmHKT7XrkMMUF6HjZUtla689DWIOWZSiV++1dVPcl/1TV+6tTmN4bBtPcLuX7SHRuLp2PI2kATvRMECsa7gZRypW4jKpVn7b2yetX9TVI3i1zR5zkQJ3dPg8sATvYPL53aKH/WsqUg4rzoAlbk9so+++R4bQY69LhV3B511B7EAynoZFdM
|
||||||
|
api_key: $API_KEY
|
||||||
file_glob: true
|
file_glob: true
|
||||||
file: $CRATE_NAME-$TRAVIS_TAG-$TARGET.*
|
file: $CRATE_NAME-$TRAVIS_TAG-$TARGET.*
|
||||||
on:
|
on:
|
||||||
|
|||||||
Generated
+368
-294
@@ -1,280 +1,407 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ansi_term"
|
name = "ansi_term"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert_cli"
|
name = "assert_cli"
|
||||||
version = "0.5.4"
|
version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.8"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.5"
|
version = "0.3.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace-sys"
|
name = "backtrace-sys"
|
||||||
version = "0.1.16"
|
version = "0.1.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "0.9.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "c2-chacha"
|
||||||
version = "1.0.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bytecount"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cargo_metadata"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.9"
|
version = "1.0.50"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.2"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.31.1"
|
version = "2.33.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colored"
|
name = "colored"
|
||||||
version = "1.6.0"
|
version = "1.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-queue"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "difference"
|
name = "difference"
|
||||||
version = "1.0.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dtoa"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "du-dust"
|
name = "du-dust"
|
||||||
version = "0.2.4"
|
version = "0.4.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"assert_cli 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jwalk 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "environment"
|
name = "environment"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-chain"
|
name = "failure"
|
||||||
version = "0.11.0"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuchsia-zircon"
|
name = "failure_derive"
|
||||||
version = "0.3.3"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuchsia-zircon-sys"
|
name = "getrandom"
|
||||||
version = "0.3.3"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "hermit-abi"
|
||||||
version = "0.2.11"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.1"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "jwalk"
|
||||||
version = "0.2.2"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "0.2.11"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.39"
|
version = "0.2.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "memoffset"
|
||||||
version = "0.2.2"
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.3.2"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pulldown-cmark"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.5.1"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.4.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.1.37"
|
version = "0.1.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_termios"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
version = "0.5.0"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.7"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "rustc_version"
|
||||||
version = "0.1.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "ryu"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
[[package]]
|
||||||
]
|
name = "scopeguard"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -284,167 +411,108 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.37"
|
version = "1.0.104"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive"
|
|
||||||
version = "1.0.37"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_derive_internals"
|
|
||||||
version = "0.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.13"
|
version = "1.0.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "skeptic"
|
|
||||||
version = "0.13.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "0.13.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempdir"
|
|
||||||
version = "0.3.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempfile"
|
|
||||||
version = "3.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "termion"
|
|
||||||
version = "1.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vec_map"
|
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "syn"
|
||||||
version = "1.0.7"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "synstructure"
|
||||||
version = "2.1.4"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "tempfile"
|
||||||
version = "0.2.8"
|
version = "3.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.4"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-build"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -452,60 +520,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||||
"checksum assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72342c21057a3cb5f7c2d849bf7999a83795434dd36d74fa8c24680581bd1930"
|
"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
|
"checksum assert_cli 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a29ab7c0ed62970beb0534d637a8688842506d0ff9157de83286dacd065c8149"
|
||||||
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
|
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b"
|
||||||
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
|
"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
|
||||||
"checksum bytecount 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af27422163679dea46a1a7239dffff64d3dcdc3ba5fe9c49c789fbfe0eb949de"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
"checksum cargo_metadata 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f56ec3e469bca7c276f2eea015aa05c5e381356febdbb0683c2580189604537"
|
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||||
"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
|
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||||
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
|
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200"
|
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||||
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
|
"checksum colored 1.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8815e2ab78f3a59928fc32e141fbeece88320a240e43f47b2fd64ea3a88a5b3d"
|
||||||
"checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
|
"checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
|
||||||
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
|
"checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
|
||||||
|
"checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"
|
||||||
|
"checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
|
||||||
|
"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
|
||||||
|
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
|
||||||
|
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||||
|
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||||
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
|
"checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee"
|
||||||
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
|
||||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
|
||||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
|
||||||
"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
|
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum jwalk 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b3dbf0a8f61baee43a2918ff50ac6a2d3b2c105bc08ed53bc298779f1263409"
|
||||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
|
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
|
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
|
||||||
"checksum proc-macro2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "681c2c8e039ff358cb926dbc5151d561cbd0249089986ace39dfe8e405bb7511"
|
"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
|
||||||
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
|
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||||
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
|
"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
|
||||||
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
|
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||||
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
|
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||||
"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
|
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
|
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
||||||
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
|
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
||||||
"checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b"
|
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||||
|
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||||
|
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
|
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||||
|
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||||
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
|
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
|
||||||
"checksum serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "f1711ab8b208541fa8de00425f6a577d90f27bb60724d2bb5fd911314af9668f"
|
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
|
||||||
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
|
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
|
"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
|
||||||
"checksum skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8431f8fca168e2db4be547bd8329eac70d095dff1444fee4b0fa0fabc7df75a"
|
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||||
"checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||||
"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99"
|
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||||
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
|
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
|
||||||
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
|
|
||||||
"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
|
|
||||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
|
||||||
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
|
|
||||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|||||||
+12
-6
@@ -1,8 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "du-dust"
|
name = "du-dust"
|
||||||
description = "A more intuitive version of du"
|
description = "A more intuitive version of du"
|
||||||
version = "0.3.0"
|
version = "0.4.4"
|
||||||
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
|
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
documentation = "https://github.com/bootandy/dust"
|
documentation = "https://github.com/bootandy/dust"
|
||||||
homepage = "https://github.com/bootandy/dust"
|
homepage = "https://github.com/bootandy/dust"
|
||||||
@@ -20,9 +21,14 @@ name = "dust"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ansi_term = "0.11"
|
ansi_term = "=0.12"
|
||||||
clap = "2.31"
|
clap = "=2.33"
|
||||||
assert_cli = "0.5"
|
jwalk = "0.4.0"
|
||||||
tempfile = "3"
|
num_cpus = "1.12"
|
||||||
walkdir = "2"
|
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi-util = "0.1"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert_cli = "=0.6"
|
||||||
|
tempfile = "=3"
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ du + rust = dust. Like du but more intuitive
|
|||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
### Cargo
|
#### Cargo Install
|
||||||
|
|
||||||
* cargo install du-dust
|
* cargo install du-dust
|
||||||
|
|
||||||
### Download
|
#### Download Install
|
||||||
|
|
||||||
* 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_
|
||||||
@@ -32,12 +32,16 @@ Dust assumes that’s what you wanted to do in the first place, and takes care o
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
|
Usage: dust
|
||||||
Usage: dust <dir>
|
Usage: dust <dir>
|
||||||
Usage: dust <dir> <another_dir> <and_more>
|
Usage: dust <dir> <another_dir> <and_more>
|
||||||
Usage: dust -p <dir> (full-path - does not shorten the path of the subdirectories)
|
Usage: dust -p <dir> (full-path - does not shorten the path of the subdirectories)
|
||||||
Usage: dust -s <dir> (apparent-size - shows the length of the file as opposed to the amount of disk space it uses)
|
Usage: dust -s <dir> (apparent-size - shows the length of the file as opposed to the amount of disk space it uses)
|
||||||
Usage: dust -n 30 <dir> (Shows 30 directories not 20)
|
Usage: dust -n 30 <dir> (Shows 30 directories not 20)
|
||||||
Usage: dust -d 3 <dir> (Shows 3 levels of subdirectories)
|
Usage: dust -d 3 <dir> (Shows 3 levels of subdirectories)
|
||||||
|
Usage: dust -r <dir> (Reverse order of output, with root at the lowest)
|
||||||
|
Usage: dust -x <dir> (Only show directories on same filesystem)
|
||||||
|
Usage: dust -X ignore <dir> (Ignore all files and directories containing the string 'ignore')
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -62,7 +66,7 @@ djin:git/dust> dust
|
|||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
Dust is currently about 4 times slower than du.
|
Dust uses a parallel fetching implementation that greatly improves performance for directory trees with reasonable amount of files (read more than 20) compared to du. This can be as much as 7x faster than du on a clean cache.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# This script takes care of building your crate and packaging it for release
|
# This script takes care of building your crate and packaging it for release
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
# This script takes care of testing your crate
|
# This script takes care of testing your crate
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|||||||
+122
-102
@@ -1,111 +1,53 @@
|
|||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
|
|
||||||
use self::ansi_term::Colour::Fixed;
|
use self::ansi_term::Colour::Fixed;
|
||||||
|
use self::ansi_term::Style;
|
||||||
|
use crate::utils::Node;
|
||||||
|
|
||||||
static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
|
static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
|
||||||
|
|
||||||
pub fn draw_it(
|
pub struct DisplayData {
|
||||||
permissions: bool,
|
pub short_paths: bool,
|
||||||
short_paths: bool,
|
pub is_reversed: bool,
|
||||||
depth: Option<u64>,
|
pub colors_on: bool,
|
||||||
base_dirs: Vec<String>,
|
|
||||||
to_display: Vec<(String, u64)>,
|
|
||||||
) -> () {
|
|
||||||
if !permissions {
|
|
||||||
eprintln!("Did not have permissions for all directories");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for f in base_dirs {
|
impl DisplayData {
|
||||||
display_node(f, &to_display, true, short_paths, depth, "")
|
fn get_first_chars(&self) -> &str {
|
||||||
}
|
if self.is_reversed {
|
||||||
}
|
"─┴"
|
||||||
|
|
||||||
fn get_size(nodes: &Vec<(String, u64)>, node_to_print: &String) -> Option<u64> {
|
|
||||||
for &(ref k, ref v) in nodes.iter() {
|
|
||||||
if *k == *node_to_print {
|
|
||||||
return Some(*v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn display_node<S: Into<String>>(
|
|
||||||
node_to_print: String,
|
|
||||||
to_display: &Vec<(String, u64)>,
|
|
||||||
is_biggest: bool,
|
|
||||||
short_paths: bool,
|
|
||||||
depth: Option<u64>,
|
|
||||||
indentation_str: S,
|
|
||||||
) {
|
|
||||||
let new_depth = match depth {
|
|
||||||
None => None,
|
|
||||||
Some(0) => return,
|
|
||||||
Some(d) => Some(d - 1),
|
|
||||||
};
|
|
||||||
match get_size(to_display, &node_to_print) {
|
|
||||||
None => println!("Can not find path: {}", node_to_print),
|
|
||||||
Some(size) => {
|
|
||||||
let mut is = indentation_str.into();
|
|
||||||
let ntp: &str = node_to_print.as_ref();
|
|
||||||
|
|
||||||
print_this_node(ntp, size, is_biggest, short_paths, is.as_ref());
|
|
||||||
|
|
||||||
is = is.replace("└─┬", " ");
|
|
||||||
is = is.replace("└──", " ");
|
|
||||||
is = is.replace("├──", "│ ");
|
|
||||||
is = is.replace("├─┬", "│ ");
|
|
||||||
|
|
||||||
let printable_node_slashes = node_to_print.matches('/').count();
|
|
||||||
|
|
||||||
let mut num_siblings = to_display.iter().fold(0, |a, b| {
|
|
||||||
if b.0.starts_with(ntp) && b.0.matches('/').count() == printable_node_slashes + 1 {
|
|
||||||
a + 1
|
|
||||||
} else {
|
} else {
|
||||||
a
|
"─┬"
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut is_biggest = true;
|
|
||||||
for &(ref k, _) in to_display.iter() {
|
|
||||||
if k.starts_with(ntp) && k.matches('/').count() == printable_node_slashes + 1 {
|
|
||||||
num_siblings -= 1;
|
|
||||||
|
|
||||||
let mut has_children = false;
|
|
||||||
if new_depth.is_none() || new_depth.unwrap() != 1 {
|
|
||||||
for &(ref k2, _) in to_display.iter() {
|
|
||||||
let kk: &str = k.as_ref();
|
|
||||||
if k2.starts_with(kk)
|
|
||||||
&& k2.matches('/').count() == printable_node_slashes + 2
|
|
||||||
{
|
|
||||||
has_children = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
display_node(
|
#[allow(clippy::collapsible_if)]
|
||||||
k.to_string(),
|
fn get_tree_chars(
|
||||||
to_display,
|
&self,
|
||||||
is_biggest,
|
num_siblings: u64,
|
||||||
short_paths,
|
max_siblings: u64,
|
||||||
new_depth,
|
has_children: bool,
|
||||||
is.to_string() + get_tree_chars(num_siblings, has_children),
|
) -> &'static str {
|
||||||
);
|
if self.is_reversed {
|
||||||
is_biggest = false;
|
if num_siblings == max_siblings - 1 {
|
||||||
|
if has_children {
|
||||||
|
"┌─┴"
|
||||||
|
} else {
|
||||||
|
"┌──"
|
||||||
}
|
}
|
||||||
|
} else if has_children {
|
||||||
|
"├─┴"
|
||||||
|
} else {
|
||||||
|
"├──"
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_tree_chars(num_siblings: u64, has_children: bool) -> &'static str {
|
|
||||||
if num_siblings == 0 {
|
if num_siblings == 0 {
|
||||||
if has_children {
|
if has_children {
|
||||||
"└─┬"
|
"└─┬"
|
||||||
} else {
|
} else {
|
||||||
"└──"
|
"└──"
|
||||||
}
|
}
|
||||||
} else {
|
} else if has_children {
|
||||||
if has_children {
|
|
||||||
"├─┬"
|
"├─┬"
|
||||||
} else {
|
} else {
|
||||||
"├──"
|
"├──"
|
||||||
@@ -113,46 +55,124 @@ fn get_tree_chars(num_siblings: u64, has_children: bool) -> &'static str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_biggest(&self, num_siblings: u64, max_siblings: u64) -> bool {
|
||||||
|
if self.is_reversed {
|
||||||
|
num_siblings == 0
|
||||||
|
} else {
|
||||||
|
num_siblings == max_siblings - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_children_from_node(&self, node: Node) -> impl Iterator<Item = Node> {
|
||||||
|
if self.is_reversed {
|
||||||
|
let n: Vec<Node> = node.children.into_iter().rev().map(|a| a).collect();
|
||||||
|
n.into_iter()
|
||||||
|
} else {
|
||||||
|
node.children.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_it(
|
||||||
|
permissions: bool,
|
||||||
|
use_full_path: bool,
|
||||||
|
is_reversed: bool,
|
||||||
|
no_colors: bool,
|
||||||
|
root_node: Node,
|
||||||
|
) {
|
||||||
|
if !permissions {
|
||||||
|
eprintln!("Did not have permissions for all directories");
|
||||||
|
}
|
||||||
|
let display_data = DisplayData {
|
||||||
|
short_paths: !use_full_path,
|
||||||
|
is_reversed,
|
||||||
|
colors_on: !no_colors,
|
||||||
|
};
|
||||||
|
|
||||||
|
for c in display_data.get_children_from_node(root_node) {
|
||||||
|
let first_tree_chars = display_data.get_first_chars();
|
||||||
|
display_node(c, true, first_tree_chars, &display_data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &DisplayData) {
|
||||||
|
let mut num_siblings = node.children.len() as u64;
|
||||||
|
let max_sibling = num_siblings;
|
||||||
|
let new_indent = clean_indentation_string(indent);
|
||||||
|
let name = node.name.clone();
|
||||||
|
let size = node.size;
|
||||||
|
|
||||||
|
if !display_data.is_reversed {
|
||||||
|
print_this_node(&*name, size, is_biggest, display_data, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
for c in display_data.get_children_from_node(node) {
|
||||||
|
num_siblings -= 1;
|
||||||
|
let chars = display_data.get_tree_chars(num_siblings, max_sibling, !c.children.is_empty());
|
||||||
|
let is_biggest = display_data.is_biggest(num_siblings, max_sibling);
|
||||||
|
let full_indent = new_indent.clone() + chars;
|
||||||
|
display_node(c, is_biggest, &*full_indent, display_data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if display_data.is_reversed {
|
||||||
|
print_this_node(&*name, size, is_biggest, display_data, indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clean_indentation_string(s: &str) -> String {
|
||||||
|
let mut is: String = s.into();
|
||||||
|
// For reversed:
|
||||||
|
is = is.replace("┌─┴", " ");
|
||||||
|
is = is.replace("┌──", " ");
|
||||||
|
is = is.replace("├─┴", "│ ");
|
||||||
|
is = is.replace("─┴", " ");
|
||||||
|
// For normal
|
||||||
|
is = is.replace("└─┬", " ");
|
||||||
|
is = is.replace("└──", " ");
|
||||||
|
is = is.replace("├─┬", "│ ");
|
||||||
|
is = is.replace("─┬", " ");
|
||||||
|
// For both
|
||||||
|
is = is.replace("├──", "│ ");
|
||||||
|
is
|
||||||
|
}
|
||||||
|
|
||||||
fn print_this_node(
|
fn print_this_node(
|
||||||
node_name: &str,
|
name: &str,
|
||||||
size: u64,
|
size: u64,
|
||||||
is_biggest: bool,
|
is_biggest: bool,
|
||||||
short_paths: bool,
|
display_data: &DisplayData,
|
||||||
indentation: &str,
|
indentation: &str,
|
||||||
) {
|
) {
|
||||||
let pretty_size = format!("{:>5}", human_readable_number(size),);
|
let pretty_size = format!("{:>5}", human_readable_number(size),);
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
format_string(
|
format_string(name, is_biggest, display_data, &*pretty_size, indentation)
|
||||||
node_name,
|
|
||||||
is_biggest,
|
|
||||||
short_paths,
|
|
||||||
pretty_size.as_ref(),
|
|
||||||
indentation
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_string(
|
pub fn format_string(
|
||||||
dir_name: &str,
|
dir_name: &str,
|
||||||
is_biggest: bool,
|
is_biggest: bool,
|
||||||
short_paths: bool,
|
display_data: &DisplayData,
|
||||||
size: &str,
|
size: &str,
|
||||||
indentation: &str,
|
indentation: &str,
|
||||||
) -> String {
|
) -> String {
|
||||||
let printable_name = {
|
let printable_name = {
|
||||||
if short_paths && dir_name.contains('/') {
|
if display_data.short_paths {
|
||||||
dir_name.split('/').last().unwrap()
|
dir_name
|
||||||
|
.split(std::path::is_separator)
|
||||||
|
.last()
|
||||||
|
.unwrap_or(dir_name)
|
||||||
} else {
|
} else {
|
||||||
dir_name
|
dir_name
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
format!(
|
format!(
|
||||||
"{} {} {}",
|
"{} {} {}",
|
||||||
if is_biggest {
|
if is_biggest && display_data.colors_on {
|
||||||
Fixed(196).paint(size)
|
Fixed(196).paint(size)
|
||||||
} else {
|
} else {
|
||||||
Fixed(7).paint(size)
|
Style::new().paint(size)
|
||||||
},
|
},
|
||||||
indentation,
|
indentation,
|
||||||
printable_name,
|
printable_name,
|
||||||
|
|||||||
+135
-32
@@ -1,20 +1,30 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate assert_cli;
|
|
||||||
extern crate walkdir;
|
|
||||||
|
|
||||||
use self::display::draw_it;
|
use self::display::draw_it;
|
||||||
|
use crate::utils::is_a_parent_of;
|
||||||
use clap::{App, AppSettings, Arg};
|
use clap::{App, AppSettings, Arg};
|
||||||
use std::io::{self, Write};
|
use utils::{find_big_ones, get_dir_tree, simplify_dir_names, sort, trim_deep_ones, Node};
|
||||||
use utils::{find_big_ones, get_dir_tree, sort};
|
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
static DEFAULT_NUMBER_OF_LINES: &'static str = "20";
|
static DEFAULT_NUMBER_OF_LINES: usize = 20;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn init_color() {
|
||||||
|
ansi_term::enable_ansi_support().expect("Couldn't enable color support");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
fn init_color() {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
init_color();
|
||||||
|
let def_num_str = DEFAULT_NUMBER_OF_LINES.to_string();
|
||||||
let options = App::new("Dust")
|
let options = App::new("Dust")
|
||||||
|
.about("Like du but more intuitive")
|
||||||
|
.version(crate_version!())
|
||||||
.setting(AppSettings::TrailingVarArg)
|
.setting(AppSettings::TrailingVarArg)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("depth")
|
Arg::with_name("depth")
|
||||||
@@ -23,13 +33,20 @@ fn main() {
|
|||||||
.help("Depth to show")
|
.help("Depth to show")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("threads")
|
||||||
|
.short("t")
|
||||||
|
.long("threads")
|
||||||
|
.help("Number of threads to spawn simultaneously")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("number_of_lines")
|
Arg::with_name("number_of_lines")
|
||||||
.short("n")
|
.short("n")
|
||||||
.long("number-of-lines")
|
.long("number-of-lines")
|
||||||
.help("Number of lines of output to show")
|
.help("Number of lines of output to show")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.default_value(DEFAULT_NUMBER_OF_LINES),
|
.default_value(def_num_str.as_ref()),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("display_full_paths")
|
Arg::with_name("display_full_paths")
|
||||||
@@ -37,62 +54,148 @@ fn main() {
|
|||||||
.long("full-paths")
|
.long("full-paths")
|
||||||
.help("If set sub directories will not have their path shortened"),
|
.help("If set sub directories will not have their path shortened"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("ignore_directory")
|
||||||
|
.short("X")
|
||||||
|
.long("ignore-directory")
|
||||||
|
.takes_value(true)
|
||||||
|
.number_of_values(1)
|
||||||
|
.multiple(true)
|
||||||
|
.help("Exclude any file or directory with contains this substring."),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("limit_filesystem")
|
||||||
|
.short("x")
|
||||||
|
.long("limit-filesystem")
|
||||||
|
.help("Only count the files and directories in the same filesystem as the supplied directory"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("display_apparent_size")
|
Arg::with_name("display_apparent_size")
|
||||||
.short("s")
|
.short("s")
|
||||||
.long("apparent-size")
|
.long("apparent-size")
|
||||||
.help("If set will use file length. Otherwise we use blocks"),
|
.help("If set will use file length. Otherwise we use blocks"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("reverse")
|
||||||
|
.short("r")
|
||||||
|
.long("reverse")
|
||||||
|
.help("If applied tree will be printed upside down (biggest lowest)"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("no_colors")
|
||||||
|
.short("c")
|
||||||
|
.long("no_colors")
|
||||||
|
.help("If applied no colors will be printed (normally largest directories are marked in red"),
|
||||||
|
)
|
||||||
.arg(Arg::with_name("inputs").multiple(true))
|
.arg(Arg::with_name("inputs").multiple(true))
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let filenames = {
|
let target_dirs = {
|
||||||
match options.values_of("inputs") {
|
match options.values_of("inputs") {
|
||||||
None => vec!["."],
|
None => vec!["."],
|
||||||
Some(r) => r.collect(),
|
Some(r) => r.collect(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let number_of_lines = value_t!(options.value_of("number_of_lines"), usize).unwrap();
|
let number_of_lines = match value_t!(options.value_of("number_of_lines"), usize) {
|
||||||
let depth = {
|
Ok(v) => v,
|
||||||
if options.is_present("depth") {
|
Err(_) => {
|
||||||
match value_t!(options.value_of("depth"), u64) {
|
eprintln!("Ignoring bad value for number_of_lines");
|
||||||
Ok(v) => Some(v + 1),
|
DEFAULT_NUMBER_OF_LINES
|
||||||
Err(_) => None,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if options.is_present("depth")
|
|
||||||
&& options.value_of("number_of_lines").unwrap() != DEFAULT_NUMBER_OF_LINES
|
let temp_threads = options.value_of("threads").and_then(|threads| {
|
||||||
{
|
threads
|
||||||
io::stderr()
|
.parse::<usize>()
|
||||||
.write(b"Use either -n for number of directories to show. Or -d for depth. Not both")
|
.map_err(|_| eprintln!("Ignoring bad value for threads: {:?}", threads))
|
||||||
.expect("Error writing to stderr. Oh the irony!");
|
.ok()
|
||||||
|
});
|
||||||
|
// Bug in JWalk
|
||||||
|
// https://github.com/jessegrosjean/jwalk/issues/15
|
||||||
|
// We force it to use 2 threads if there is only 1 cpu
|
||||||
|
// as JWalk breaks if it tries to run on a single cpu
|
||||||
|
let threads = {
|
||||||
|
if temp_threads.is_none() && num_cpus::get() == 1 {
|
||||||
|
Some(2)
|
||||||
|
} else {
|
||||||
|
temp_threads
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let depth = options.value_of("depth").and_then(|depth| {
|
||||||
|
depth
|
||||||
|
.parse::<u64>()
|
||||||
|
.map(|v| v + 1)
|
||||||
|
.map_err(|_| eprintln!("Ignoring bad value for depth"))
|
||||||
|
.ok()
|
||||||
|
});
|
||||||
|
if options.is_present("depth") && number_of_lines != DEFAULT_NUMBER_OF_LINES {
|
||||||
|
eprintln!("Use either -n or -d. Not both");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let use_apparent_size = options.is_present("display_apparent_size");
|
let use_apparent_size = options.is_present("display_apparent_size");
|
||||||
let use_full_path = options.is_present("display_full_paths");
|
let limit_filesystem = options.is_present("limit_filesystem");
|
||||||
|
let ignore_directories = options.values_of("ignore_directory").map(|r| r.collect());
|
||||||
|
|
||||||
let (permissions, nodes, top_level_names) = get_dir_tree(&filenames, use_apparent_size);
|
let simplified_dirs = simplify_dir_names(target_dirs);
|
||||||
|
let (permissions, nodes) = get_dir_tree(
|
||||||
|
&simplified_dirs,
|
||||||
|
ignore_directories,
|
||||||
|
use_apparent_size,
|
||||||
|
limit_filesystem,
|
||||||
|
threads,
|
||||||
|
);
|
||||||
let sorted_data = sort(nodes);
|
let sorted_data = sort(nodes);
|
||||||
let biggest_ones = {
|
let biggest_ones = {
|
||||||
if depth.is_none() {
|
match depth {
|
||||||
find_big_ones(sorted_data, number_of_lines)
|
None => find_big_ones(sorted_data, number_of_lines + simplified_dirs.len()),
|
||||||
} else {
|
Some(d) => trim_deep_ones(sorted_data, d, &simplified_dirs),
|
||||||
sorted_data
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let tree = build_tree(biggest_ones, depth);
|
||||||
|
|
||||||
draw_it(
|
draw_it(
|
||||||
permissions,
|
permissions,
|
||||||
!use_full_path,
|
options.is_present("display_full_paths"),
|
||||||
depth,
|
options.is_present("reverse"),
|
||||||
top_level_names,
|
options.is_present("no_colors"),
|
||||||
biggest_ones,
|
tree,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_tree(biggest_ones: Vec<(String, u64)>, depth: Option<u64>) -> Node {
|
||||||
|
let mut top_parent = Node::default();
|
||||||
|
|
||||||
|
// assume sorted order
|
||||||
|
for b in biggest_ones {
|
||||||
|
let n = Node {
|
||||||
|
name: b.0,
|
||||||
|
size: b.1,
|
||||||
|
children: Vec::default(),
|
||||||
|
};
|
||||||
|
recursively_build_tree(&mut top_parent, n, depth);
|
||||||
|
}
|
||||||
|
top_parent
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recursively_build_tree(parent_node: &mut Node, new_node: Node, depth: Option<u64>) {
|
||||||
|
let new_depth = match depth {
|
||||||
|
None => None,
|
||||||
|
Some(0) => return,
|
||||||
|
Some(d) => Some(d - 1),
|
||||||
|
};
|
||||||
|
if let Some(c) = parent_node
|
||||||
|
.children
|
||||||
|
.iter_mut()
|
||||||
|
.find(|c| is_a_parent_of(&c.name, &new_node.name))
|
||||||
|
{
|
||||||
|
recursively_build_tree(c, new_node, new_depth);
|
||||||
|
} else {
|
||||||
|
parent_node.children.push(new_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
hello
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hello
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hello
|
||||||
+274
-136
@@ -1,112 +1,217 @@
|
|||||||
extern crate ansi_term;
|
|
||||||
extern crate tempfile;
|
|
||||||
use self::tempfile::Builder;
|
|
||||||
use self::tempfile::TempDir;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use crate::display::DisplayData;
|
||||||
use display::format_string;
|
use display::format_string;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use tempfile::Builder;
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_main() {
|
pub fn test_main() {
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&["src/test_dir"])
|
.with_args(&["src/test_dir"])
|
||||||
.stdout()
|
.stdout()
|
||||||
.is(main_output(true))
|
.is(main_output(true).as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_main_long_paths() {
|
pub fn test_main_long_paths() {
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&["-p", "src/test_dir"])
|
.with_args(&["-p", "src/test_dir"])
|
||||||
.stdout()
|
.stdout()
|
||||||
.is(main_output(false))
|
.is(main_output(false).as_str())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
|
#[test]
|
||||||
|
pub fn test_main_multi_arg() {
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["src/test_dir/many/", "src/test_dir/", "src/test_dir"])
|
||||||
|
.stdout()
|
||||||
|
.is(main_output(true).as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn main_output(short_paths: bool) -> String {
|
fn main_output(short_paths: bool) -> String {
|
||||||
|
let d = DisplayData {
|
||||||
|
short_paths,
|
||||||
|
is_reversed: false,
|
||||||
|
colors_on: true,
|
||||||
|
};
|
||||||
format!(
|
format!(
|
||||||
"{}
|
"{}
|
||||||
{}
|
{}
|
||||||
{}
|
{}
|
||||||
{}",
|
{}",
|
||||||
format_string("src/test_dir", true, short_paths, " 4.0K", ""),
|
format_string("src/test_dir", true, &d, " 4.0K", "─┬"),
|
||||||
format_string("src/test_dir/many", true, short_paths, " 4.0K", "└─┬",),
|
format_string("src/test_dir/many", true, &d, " 4.0K", " └─┬",),
|
||||||
format_string(
|
format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
|
||||||
"src/test_dir/many/hello_file",
|
format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
|
||||||
true,
|
|
||||||
short_paths,
|
|
||||||
" 4.0K",
|
|
||||||
" ├──",
|
|
||||||
),
|
|
||||||
format_string(
|
|
||||||
"src/test_dir/many/a_file",
|
|
||||||
false,
|
|
||||||
short_paths,
|
|
||||||
" 0B",
|
|
||||||
" └──",
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn main_output(short_paths: bool) -> String {
|
fn main_output(short_paths: bool) -> String {
|
||||||
|
let d = DisplayData {
|
||||||
|
short_paths,
|
||||||
|
is_reversed: false,
|
||||||
|
colors_on: true,
|
||||||
|
};
|
||||||
format!(
|
format!(
|
||||||
"{}
|
"{}
|
||||||
{}
|
{}
|
||||||
{}
|
{}
|
||||||
{}",
|
{}",
|
||||||
format_string("src/test_dir", true, short_paths, " 12K", ""),
|
format_string("src/test_dir", true, &d, " 12K", "─┬"),
|
||||||
format_string("src/test_dir/many", true, short_paths, " 8.0K", "└─┬",),
|
format_string("src/test_dir/many", true, &d, " 8.0K", " └─┬",),
|
||||||
format_string(
|
format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
|
||||||
"src/test_dir/many/hello_file",
|
format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
|
||||||
true,
|
|
||||||
short_paths,
|
|
||||||
" 4.0K",
|
|
||||||
" ├──",
|
|
||||||
),
|
|
||||||
format_string(
|
|
||||||
"src/test_dir/many/a_file",
|
|
||||||
false,
|
|
||||||
short_paths,
|
|
||||||
" 0B",
|
|
||||||
" └──",
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn test_apparent_size() {
|
fn main_output(short_paths: bool) -> String {
|
||||||
let r = format!(
|
let d = DisplayData {
|
||||||
"{}",
|
short_paths,
|
||||||
|
is_reversed: false,
|
||||||
|
colors_on: true,
|
||||||
|
};
|
||||||
|
format!(
|
||||||
|
"{}
|
||||||
|
{}
|
||||||
|
{}
|
||||||
|
{}",
|
||||||
|
format_string("src/test_dir", true, &d, " 6B", "─┬"),
|
||||||
|
format_string("src/test_dir\\many", true, &d, " 6B", " └─┬",),
|
||||||
format_string(
|
format_string(
|
||||||
"src/test_dir/many/hello_file",
|
"src/test_dir\\many\\hello_file",
|
||||||
true,
|
|
||||||
true,
|
true,
|
||||||
|
&d,
|
||||||
" 6B",
|
" 6B",
|
||||||
" ├──",
|
" ├──",
|
||||||
),
|
),
|
||||||
|
format_string("src/test_dir\\many\\a_file", false, &d, " 0B", " └──",),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
|
#[test]
|
||||||
|
pub fn test_no_color_flag() {
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["-c", "src/test_dir/"])
|
||||||
|
.stdout()
|
||||||
|
.is(no_color_flag_output().as_str())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn no_color_flag_output() -> String {
|
||||||
|
"
|
||||||
|
4.0K ─┬ test_dir
|
||||||
|
4.0K └─┬ many
|
||||||
|
4.0K ├── hello_file
|
||||||
|
0B └── a_file
|
||||||
|
"
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn no_color_flag_output() -> String {
|
||||||
|
"
|
||||||
|
12K ─┬ test_dir
|
||||||
|
8.0K └─┬ many
|
||||||
|
4.0K ├── hello_file
|
||||||
|
0B └── a_file
|
||||||
|
"
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn no_color_flag_output() -> String {
|
||||||
|
"
|
||||||
|
6B ─┬ test_dir
|
||||||
|
6B └─┬ many
|
||||||
|
6B ├── hello_file
|
||||||
|
0B └── a_file
|
||||||
|
"
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
|
#[test]
|
||||||
|
pub fn test_apparent_size() {
|
||||||
|
let d = DisplayData {
|
||||||
|
short_paths: true,
|
||||||
|
is_reversed: false,
|
||||||
|
colors_on: true,
|
||||||
|
};
|
||||||
|
let r = format!(
|
||||||
|
"{}",
|
||||||
|
format_string("src/test_dir/many/hello_file", true, &d, " 6B", " ├──",),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&["-s", "src/test_dir"])
|
.with_args(&["-s", "src/test_dir"])
|
||||||
.stdout()
|
.stdout()
|
||||||
.contains(r)
|
.contains(r.as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_temp_file(dir: &TempDir) -> (PathBuf) {
|
#[test]
|
||||||
|
pub fn test_reverse_flag() {
|
||||||
|
// variable names the same length make the output easier to read
|
||||||
|
let a = " ┌── a_file";
|
||||||
|
let b = " ├── hello_file";
|
||||||
|
let c = " ┌─┴ many";
|
||||||
|
let d = " ─┴ test_dir";
|
||||||
|
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["-r", "src/test_dir"])
|
||||||
|
.stdout()
|
||||||
|
.contains(a)
|
||||||
|
.stdout()
|
||||||
|
.contains(b)
|
||||||
|
.stdout()
|
||||||
|
.contains(c)
|
||||||
|
.stdout()
|
||||||
|
.contains(d)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_d_flag_works() {
|
||||||
|
// We should see the top level directory but not the sub dirs / files:
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["-d", "1", "-s", "src/test_dir"])
|
||||||
|
.stdout()
|
||||||
|
.doesnt_contain("hello_file")
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_temp_file(dir: &TempDir) -> PathBuf {
|
||||||
let file_path = dir.path().join("notes.txt");
|
let file_path = dir.path().join("notes.txt");
|
||||||
let mut file = File::create(&file_path).unwrap();
|
let mut file = File::create(&file_path).unwrap();
|
||||||
writeln!(file, "I am a temp file").unwrap();
|
writeln!(file, "I am a temp file").unwrap();
|
||||||
file_path
|
file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix! [rivy; 2020-01-22] possible on "windows"?; `ln` is not usually an available command; creation of symbolic links requires special enhanced permissions
|
||||||
|
// ... ref: <https://superuser.com/questions/343074/directory-junction-vs-directory-symbolic-link> @@ <https://archive.is/gpTLE>
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_soft_sym_link() {
|
pub fn test_soft_sym_link() {
|
||||||
let dir = Builder::new().tempdir().unwrap();
|
let dir = Builder::new().tempdir().unwrap();
|
||||||
@@ -123,42 +228,23 @@ pub fn test_soft_sym_link() {
|
|||||||
.output();
|
.output();
|
||||||
assert!(c.is_ok());
|
assert!(c.is_ok());
|
||||||
|
|
||||||
let r = soft_sym_link_output(dir_s, file_path_s, link_name_s);
|
let a = format!(" ─┬ {}", dir_s);
|
||||||
|
let b = format!(" ├── {}", file_path_s);
|
||||||
|
let c = format!(" └── {}", link_name_s);
|
||||||
|
|
||||||
// We cannot guarantee which version will appear first.
|
|
||||||
// TODO: Consider adding predictable itteration order (sort file entries by name?)
|
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&[dir_s])
|
.with_args(&["-p", &dir_s])
|
||||||
.stdout()
|
.stdout()
|
||||||
.contains(r)
|
.contains(a.as_str())
|
||||||
|
.stdout()
|
||||||
|
.contains(b.as_str())
|
||||||
|
.stdout()
|
||||||
|
.contains(c.as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
|
|
||||||
format!(
|
|
||||||
"{}
|
|
||||||
{}
|
|
||||||
{}",
|
|
||||||
format_string(dir, true, true, " 8.0K", ""),
|
|
||||||
format_string(file_path, true, true, " 4.0K", "├──",),
|
|
||||||
format_string(link_name, false, true, " 4.0K", "└──",),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
|
|
||||||
format!(
|
|
||||||
"{}
|
|
||||||
{}
|
|
||||||
{}",
|
|
||||||
format_string(dir, true, true, " 8.0K", ""),
|
|
||||||
format_string(file_path, true, true, " 4.0K", "├──",),
|
|
||||||
format_string(link_name, false, true, " 0B", "└──",),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hard links are ignored as the inode is the same as the file
|
// Hard links are ignored as the inode is the same as the file
|
||||||
|
// fix! [rivy; 2020-01-22] may fail on "usual" windows hosts as `ln` is not usually an available command
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_hard_sym_link() {
|
pub fn test_hard_sym_link() {
|
||||||
let dir = Builder::new().tempdir().unwrap();
|
let dir = Builder::new().tempdir().unwrap();
|
||||||
@@ -174,62 +260,36 @@ pub fn test_hard_sym_link() {
|
|||||||
.output();
|
.output();
|
||||||
assert!(c.is_ok());
|
assert!(c.is_ok());
|
||||||
|
|
||||||
let (r, r2) = hard_link_output(dir_s, file_path_s, link_name_s);
|
let a = format!(" ─┬ {}", dir_s);
|
||||||
|
let b = format!(" └── {}", link_name_s);
|
||||||
|
let b2 = format!(" └── {}", file_path_s);
|
||||||
|
|
||||||
// Because this is a hard link the file and hard link look identicle. Therefore
|
// Because this is a hard link the file and hard link look identical. Therefore
|
||||||
// we cannot guarantee which version will appear first.
|
// we cannot guarantee which version will appear first.
|
||||||
// TODO: Consider adding predictable itteration order (sort file entries by name?)
|
|
||||||
let result = panic::catch_unwind(|| {
|
let result = panic::catch_unwind(|| {
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&[dir_s])
|
.with_args(&["-p", dir_s])
|
||||||
.stdout()
|
.stdout()
|
||||||
.contains(r)
|
.contains(a.as_str())
|
||||||
|
.stdout()
|
||||||
|
.contains(b.as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
});
|
});
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&[dir_s])
|
.with_args(&["-p", dir_s])
|
||||||
.stdout()
|
.stdout()
|
||||||
.contains(r2)
|
.contains(a.as_str())
|
||||||
|
.stdout()
|
||||||
|
.contains(b2.as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
|
|
||||||
let r = format!(
|
|
||||||
"{}
|
|
||||||
{}",
|
|
||||||
format_string(dir_s, true, true, " 4.0K", ""),
|
|
||||||
format_string(file_path_s, true, true, " 4.0K", "└──")
|
|
||||||
);
|
|
||||||
let r2 = format!(
|
|
||||||
"{}
|
|
||||||
{}",
|
|
||||||
format_string(dir_s, true, true, " 4.0K", ""),
|
|
||||||
format_string(link_name_s, true, true, " 4.0K", "└──")
|
|
||||||
);
|
|
||||||
(r, r2)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
|
|
||||||
let r = format!(
|
|
||||||
"{}
|
|
||||||
{}",
|
|
||||||
format_string(dir_s, true, true, " 8.0K", ""),
|
|
||||||
format_string(file_path_s, true, true, " 4.0K", "└──")
|
|
||||||
);
|
|
||||||
let r2 = format!(
|
|
||||||
"{}
|
|
||||||
{}",
|
|
||||||
format_string(dir_s, true, true, " 8.0K", ""),
|
|
||||||
format_string(link_name_s, true, true, " 4.0K", "└──")
|
|
||||||
);
|
|
||||||
(r, r2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check we don't recurse down an infinite symlink tree
|
// Check we don't recurse down an infinite symlink tree
|
||||||
|
// fix! [rivy; 2020-01-22] possible on "windows"?; `ln` is not usually an available command; creation of symbolic links requires special enhanced permissions
|
||||||
|
// ... ref: <https://superuser.com/questions/343074/directory-junction-vs-directory-symbolic-link> @@ <https://archive.is/gpTLE>
|
||||||
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_recursive_sym_link() {
|
pub fn test_recursive_sym_link() {
|
||||||
let dir = Builder::new().tempdir().unwrap();
|
let dir = Builder::new().tempdir().unwrap();
|
||||||
@@ -245,30 +305,108 @@ pub fn test_recursive_sym_link() {
|
|||||||
.output();
|
.output();
|
||||||
assert!(c.is_ok());
|
assert!(c.is_ok());
|
||||||
|
|
||||||
|
let a = format!(" ─┬ {}", dir_s);
|
||||||
|
let b = format!(" └── {}", link_name_s);
|
||||||
|
|
||||||
assert_cli::Assert::main_binary()
|
assert_cli::Assert::main_binary()
|
||||||
.with_args(&[dir_s])
|
.with_args(&["-p", dir_s])
|
||||||
.stdout()
|
.stdout()
|
||||||
.contains(recursive_sym_link_output(dir_s, link_name_s))
|
.contains(a.as_str())
|
||||||
|
.stdout()
|
||||||
|
.contains(b.as_str())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
// Check against directories and files whos names are substrings of each other
|
||||||
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
|
// fix! [rivy; 2020-22-01] "windows" result data can vary by host (size seems to be variable by one byte); fix code vs test and re-enable
|
||||||
format!(
|
#[cfg_attr(target_os = "windows", ignore)]
|
||||||
"{}
|
#[test]
|
||||||
{}",
|
pub fn test_substring_of_names() {
|
||||||
format_string(dir, true, true, " 4.0K", ""),
|
assert_cli::Assert::main_binary()
|
||||||
format_string(link_name, true, true, " 4.0K", "└──",),
|
.with_args(&["-c", "src/test_dir2"])
|
||||||
)
|
.stdout()
|
||||||
}
|
.is(no_substring_of_names_output().as_str())
|
||||||
#[cfg(target_os = "linux")]
|
.unwrap();
|
||||||
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
|
|
||||||
format!(
|
|
||||||
"{}
|
|
||||||
{}",
|
|
||||||
format_string(dir, true, true, " 4.0K", ""),
|
|
||||||
format_string(link_name, true, true, " 0B", "└──",),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add test for bad path
|
#[cfg(target_os = "linux")]
|
||||||
|
fn no_substring_of_names_output() -> String {
|
||||||
|
"
|
||||||
|
24K ─┬ test_dir2
|
||||||
|
8.0K ├─┬ dir
|
||||||
|
4.0K │ └── hello
|
||||||
|
8.0K ├─┬ dir_substring
|
||||||
|
4.0K │ └── hello
|
||||||
|
4.0K └── dir_name_clash
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn no_substring_of_names_output() -> String {
|
||||||
|
"
|
||||||
|
12K ─┬ test_dir2
|
||||||
|
4.0K ├─┬ dir
|
||||||
|
4.0K │ └── hello
|
||||||
|
4.0K ├── dir_name_clash
|
||||||
|
4.0K └─┬ dir_substring
|
||||||
|
4.0K └── hello
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn no_substring_of_names_output() -> String {
|
||||||
|
"
|
||||||
|
16B ─┬ test_dir2
|
||||||
|
6B ├─┬ dir_substring
|
||||||
|
6B │ └── hello
|
||||||
|
5B ├─┬ dir
|
||||||
|
5B │ └── hello
|
||||||
|
5B └── dir_name_clash
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check against directories and files whos names are substrings of each other
|
||||||
|
#[test]
|
||||||
|
pub fn test_ignore_dir() {
|
||||||
|
assert_cli::Assert::main_binary()
|
||||||
|
.with_args(&["-c", "-X", "dir_substring", "src/test_dir2"])
|
||||||
|
.stdout()
|
||||||
|
.is(ignore_dir_output().as_str())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn ignore_dir_output() -> String {
|
||||||
|
"
|
||||||
|
16K ─┬ test_dir2
|
||||||
|
8.0K ├─┬ dir
|
||||||
|
4.0K │ └── hello
|
||||||
|
4.0K └── dir_name_clash
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn ignore_dir_output() -> String {
|
||||||
|
"
|
||||||
|
8.0K ─┬ test_dir2
|
||||||
|
4.0K ├─┬ dir
|
||||||
|
4.0K │ └── hello
|
||||||
|
4.0K └── dir_name_clash
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn ignore_dir_output() -> String {
|
||||||
|
"
|
||||||
|
10B ─┬ test_dir2
|
||||||
|
5B ├─┬ dir
|
||||||
|
5B │ └── hello
|
||||||
|
5B └── dir_name_clash
|
||||||
|
"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|||||||
+307
-49
@@ -1,87 +1,218 @@
|
|||||||
|
use jwalk::DirEntry;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use walkdir::WalkDir;
|
use jwalk::WalkDir;
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
mod platform;
|
mod platform;
|
||||||
use self::platform::*;
|
use self::platform::*;
|
||||||
|
|
||||||
pub fn get_dir_tree(
|
#[derive(Debug, Default, Eq)]
|
||||||
filenames: &Vec<&str>,
|
pub struct Node {
|
||||||
apparent_size: bool,
|
pub name: String,
|
||||||
) -> (bool, HashMap<String, u64>, Vec<String>) {
|
pub size: u64,
|
||||||
let mut permissions = 0;
|
pub children: Vec<Node>,
|
||||||
let mut inodes: HashSet<(u64, u64)> = HashSet::new();
|
}
|
||||||
let mut data: HashMap<String, u64> = HashMap::new();
|
|
||||||
let mut top_level_names = Vec::new();
|
|
||||||
|
|
||||||
for b in filenames {
|
impl Ord for Node {
|
||||||
let top_level_name = strip_end_slashes(b);
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
if self.size == other.size {
|
||||||
|
self.name.cmp(&other.name)
|
||||||
|
} else {
|
||||||
|
self.size.cmp(&other.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Node {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Node {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.name == other.name && self.size == other.size && self.children == other.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_a_parent_of(parent: &str, child: &str) -> bool {
|
||||||
|
let path_parent = std::path::Path::new(parent);
|
||||||
|
let path_child = std::path::Path::new(child);
|
||||||
|
(path_child.starts_with(path_parent) && !path_parent.starts_with(path_child))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
|
||||||
|
let mut top_level_names: HashSet<String> = HashSet::with_capacity(filenames.len());
|
||||||
|
let mut to_remove: Vec<String> = Vec::with_capacity(filenames.len());
|
||||||
|
|
||||||
|
for t in filenames {
|
||||||
|
let top_level_name = normalize_path(t);
|
||||||
|
let mut can_add = true;
|
||||||
|
|
||||||
|
for tt in top_level_names.iter() {
|
||||||
|
if is_a_parent_of(&top_level_name, tt) {
|
||||||
|
to_remove.push(tt.to_string());
|
||||||
|
} else if is_a_parent_of(tt, &top_level_name) {
|
||||||
|
can_add = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
to_remove.sort_unstable();
|
||||||
|
top_level_names.retain(|tr| to_remove.binary_search(tr).is_err());
|
||||||
|
to_remove.clear();
|
||||||
|
if can_add {
|
||||||
|
top_level_names.insert(normalize_path(t).to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
top_level_names
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_dir_tree(
|
||||||
|
top_level_names: &HashSet<String>,
|
||||||
|
ignore_directories: Option<Vec<&str>>,
|
||||||
|
apparent_size: bool,
|
||||||
|
limit_filesystem: bool,
|
||||||
|
threads: Option<usize>,
|
||||||
|
) -> (bool, HashMap<String, u64>) {
|
||||||
|
let mut permissions = 0;
|
||||||
|
let mut data: HashMap<String, u64> = HashMap::new();
|
||||||
|
let restricted_filesystems = if limit_filesystem {
|
||||||
|
get_allowed_filesystems(top_level_names)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
for b in top_level_names.iter() {
|
||||||
examine_dir(
|
examine_dir(
|
||||||
&Path::new(&top_level_name).to_path_buf(),
|
&b,
|
||||||
apparent_size,
|
apparent_size,
|
||||||
&mut inodes,
|
&restricted_filesystems,
|
||||||
|
&ignore_directories,
|
||||||
&mut data,
|
&mut data,
|
||||||
&mut permissions,
|
&mut permissions,
|
||||||
|
threads,
|
||||||
);
|
);
|
||||||
top_level_names.push(top_level_name);
|
|
||||||
}
|
}
|
||||||
(permissions == 0, data, top_level_names)
|
(permissions == 0, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn strip_end_slashes(s: &str) -> String {
|
fn get_allowed_filesystems(top_level_names: &HashSet<String>) -> Option<HashSet<u64>> {
|
||||||
let mut new_name = String::from(s);
|
let mut limit_filesystems: HashSet<u64> = HashSet::new();
|
||||||
while new_name.chars().last() == Some('/') && new_name.len() != 1 {
|
for file_name in top_level_names.iter() {
|
||||||
new_name.pop();
|
if let Ok(a) = get_filesystem(file_name) {
|
||||||
|
limit_filesystems.insert(a);
|
||||||
}
|
}
|
||||||
new_name
|
}
|
||||||
|
Some(limit_filesystems)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize_path<P: AsRef<std::path::Path>>(path: P) -> std::string::String {
|
||||||
|
// normalize path ...
|
||||||
|
// 1. removing repeated separators
|
||||||
|
// 2. removing interior '.' ("current directory") path segments
|
||||||
|
// 3. removing trailing extra separators and '.' ("current directory") path segments
|
||||||
|
// * `Path.components()` does all the above work; ref: <https://doc.rust-lang.org/std/path/struct.Path.html#method.components>
|
||||||
|
// 4. changing to os preferred separator (automatically done by recollecting components back into a PathBuf)
|
||||||
|
path.as_ref()
|
||||||
|
.components()
|
||||||
|
.collect::<std::path::PathBuf>()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examine_dir(
|
fn examine_dir(
|
||||||
top_dir: &PathBuf,
|
top_dir: &str,
|
||||||
apparent_size: bool,
|
apparent_size: bool,
|
||||||
inodes: &mut HashSet<(u64, u64)>,
|
filesystems: &Option<HashSet<u64>>,
|
||||||
|
ignore_directories: &Option<Vec<&str>>,
|
||||||
data: &mut HashMap<String, u64>,
|
data: &mut HashMap<String, u64>,
|
||||||
permissions: &mut u64,
|
file_count_no_permission: &mut u64,
|
||||||
|
threads: Option<usize>,
|
||||||
) {
|
) {
|
||||||
for entry in WalkDir::new(top_dir) {
|
let mut inodes: HashSet<(u64, u64)> = HashSet::new();
|
||||||
match entry {
|
let mut iter = WalkDir::new(top_dir)
|
||||||
Ok(e) => {
|
.preload_metadata(true)
|
||||||
|
.skip_hidden(false);
|
||||||
|
if let Some(threads_to_start) = threads {
|
||||||
|
iter = iter.num_threads(threads_to_start);
|
||||||
|
}
|
||||||
|
'entry: for entry in iter {
|
||||||
|
if let Ok(e) = entry {
|
||||||
let maybe_size_and_inode = get_metadata(&e, apparent_size);
|
let maybe_size_and_inode = get_metadata(&e, apparent_size);
|
||||||
|
if let Some(d) = ignore_directories {
|
||||||
|
for s in d {
|
||||||
|
if e.path().to_string_lossy().contains(*s) {
|
||||||
|
continue 'entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match maybe_size_and_inode {
|
match maybe_size_and_inode {
|
||||||
Some((size, maybe_inode)) => {
|
Some((size, maybe_inode)) => {
|
||||||
|
if !should_ignore_file(apparent_size, filesystems, &mut inodes, maybe_inode) {
|
||||||
|
process_file_with_size_and_inode(top_dir, data, e, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => *file_count_no_permission += 1,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*file_count_no_permission += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_ignore_file(
|
||||||
|
apparent_size: bool,
|
||||||
|
restricted_filesystems: &Option<HashSet<u64>>,
|
||||||
|
inodes: &mut HashSet<(u64, u64)>,
|
||||||
|
maybe_inode: Option<(u64, u64)>,
|
||||||
|
) -> bool {
|
||||||
if !apparent_size {
|
if !apparent_size {
|
||||||
if let Some(inode_dev_pair) = maybe_inode {
|
if let Some(inode_dev_pair) = maybe_inode {
|
||||||
|
// Ignore files on different devices (if flag applied)
|
||||||
|
if restricted_filesystems.is_some()
|
||||||
|
&& !restricted_filesystems
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.contains(&inode_dev_pair.1)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Ignore files already visited or symlinked
|
||||||
if inodes.contains(&inode_dev_pair) {
|
if inodes.contains(&inode_dev_pair) {
|
||||||
continue;
|
return true;
|
||||||
}
|
}
|
||||||
inodes.insert(inode_dev_pair);
|
inodes.insert(inode_dev_pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut e_path = e.path().to_path_buf();
|
false
|
||||||
loop {
|
}
|
||||||
let path_name = e_path.to_string_lossy().to_string();
|
|
||||||
let s = data.entry(path_name).or_insert(0);
|
fn process_file_with_size_and_inode(
|
||||||
|
top_dir: &str,
|
||||||
|
data: &mut HashMap<String, u64>,
|
||||||
|
e: DirEntry,
|
||||||
|
size: u64,
|
||||||
|
) {
|
||||||
|
// This path and all its parent paths have their counter incremented
|
||||||
|
for path_name in e.path().ancestors() {
|
||||||
|
// This is required due to bug in Jwalk that adds '/' to all sub dir lists
|
||||||
|
// see: https://github.com/jessegrosjean/jwalk/issues/13
|
||||||
|
if path_name.to_string_lossy() == "/" && top_dir != "/" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let path_name = path_name.to_string_lossy();
|
||||||
|
let s = data.entry(path_name.to_string()).or_insert(0);
|
||||||
*s += size;
|
*s += size;
|
||||||
if e_path == *top_dir {
|
if path_name == top_dir {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e_path.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => *permissions += 1,
|
|
||||||
}
|
pub fn sort_by_size_first_name_second(a: &(String, u64), b: &(String, u64)) -> Ordering {
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn compare_tuple(a :&(String, u64), b: &(String, u64)) -> Ordering {
|
|
||||||
let result = b.1.cmp(&a.1);
|
let result = b.1.cmp(&a.1);
|
||||||
if result == Ordering::Equal {
|
if result == Ordering::Equal {
|
||||||
a.0.cmp(&b.0)
|
a.0.cmp(&b.0)
|
||||||
@@ -90,16 +221,143 @@ pub fn compare_tuple(a :&(String, u64), b: &(String, u64)) -> Ordering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sort<'a>(data: HashMap<String, u64>) -> Vec<(String, u64)> {
|
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
|
||||||
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
|
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
|
||||||
new_l.sort_by(|a, b| compare_tuple(&a, &b));
|
new_l.sort_unstable_by(sort_by_size_first_name_second);
|
||||||
new_l
|
new_l
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_big_ones<'a>(new_l: Vec<(String, u64)>, max_to_show: usize) -> Vec<(String, u64)> {
|
pub fn find_big_ones(new_l: Vec<(String, u64)>, max_to_show: usize) -> Vec<(String, u64)> {
|
||||||
if max_to_show > 0 && new_l.len() > max_to_show {
|
if max_to_show > 0 && new_l.len() > max_to_show {
|
||||||
new_l[0..max_to_show + 1].to_vec()
|
new_l[0..max_to_show].to_vec()
|
||||||
} else {
|
} else {
|
||||||
new_l
|
new_l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trim_deep_ones(
|
||||||
|
input: Vec<(String, u64)>,
|
||||||
|
max_depth: u64,
|
||||||
|
top_level_names: &HashSet<String>,
|
||||||
|
) -> Vec<(String, u64)> {
|
||||||
|
let mut result: Vec<(String, u64)> = Vec::with_capacity(input.len() * top_level_names.len());
|
||||||
|
|
||||||
|
for name in top_level_names {
|
||||||
|
let my_max_depth = name.matches(std::path::is_separator).count() + max_depth as usize;
|
||||||
|
let name_ref: &str = name.as_ref();
|
||||||
|
|
||||||
|
for &(ref k, ref v) in input.iter() {
|
||||||
|
if k.starts_with(name_ref) && k.matches(std::path::is_separator).count() <= my_max_depth
|
||||||
|
{
|
||||||
|
result.push((k.clone(), *v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
mod tests {
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert("a".to_string());
|
||||||
|
assert_eq!(simplify_dir_names(vec!["a"]), correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir_rm_subdir() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert(
|
||||||
|
["a", "b"]
|
||||||
|
.iter()
|
||||||
|
.collect::<std::path::PathBuf>()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(simplify_dir_names(vec!["a/b", "a/b/c", "a/b/d/f"]), correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir_duplicates() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert(
|
||||||
|
["a", "b"]
|
||||||
|
.iter()
|
||||||
|
.collect::<std::path::PathBuf>()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
correct.insert("c".to_string());
|
||||||
|
assert_eq!(
|
||||||
|
simplify_dir_names(vec![
|
||||||
|
"a/b",
|
||||||
|
"a/b//",
|
||||||
|
"a/././b///",
|
||||||
|
"c",
|
||||||
|
"c/",
|
||||||
|
"c/.",
|
||||||
|
"c/././",
|
||||||
|
"c/././."
|
||||||
|
]),
|
||||||
|
correct
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir_rm_subdir_and_not_substrings() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert("b".to_string());
|
||||||
|
correct.insert(
|
||||||
|
["c", "a", "b"]
|
||||||
|
.iter()
|
||||||
|
.collect::<std::path::PathBuf>()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
correct.insert(
|
||||||
|
["a", "b"]
|
||||||
|
.iter()
|
||||||
|
.collect::<std::path::PathBuf>()
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
assert_eq!(simplify_dir_names(vec!["a/b", "c/a/b/", "b"]), correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir_dots() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert("src".to_string());
|
||||||
|
assert_eq!(simplify_dir_names(vec!["src/."]), correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simplify_dir_substring_names() {
|
||||||
|
let mut correct = HashSet::new();
|
||||||
|
correct.insert("src".to_string());
|
||||||
|
correct.insert("src_v2".to_string());
|
||||||
|
assert_eq!(simplify_dir_names(vec!["src/", "src_v2"]), correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_a_parent_of() {
|
||||||
|
assert!(is_a_parent_of("/usr", "/usr/andy"));
|
||||||
|
assert!(is_a_parent_of("/usr", "/usr/andy/i/am/descendant"));
|
||||||
|
assert!(!is_a_parent_of("/usr", "/usr/."));
|
||||||
|
assert!(!is_a_parent_of("/usr", "/usr/"));
|
||||||
|
assert!(!is_a_parent_of("/usr", "/usr"));
|
||||||
|
assert!(!is_a_parent_of("/usr/", "/usr"));
|
||||||
|
assert!(!is_a_parent_of("/usr/andy", "/usr"));
|
||||||
|
assert!(!is_a_parent_of("/usr/andy", "/usr/sibling"));
|
||||||
|
assert!(!is_a_parent_of("/usr/folder", "/usr/folder_not_a_child"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_a_parent_of_root() {
|
||||||
|
assert!(is_a_parent_of("/", "/usr/andy"));
|
||||||
|
assert!(is_a_parent_of("/", "/usr"));
|
||||||
|
assert!(!is_a_parent_of("/", "/"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+45
-43
@@ -1,63 +1,65 @@
|
|||||||
use walkdir::DirEntry;
|
use jwalk::DirEntry;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use std::fs;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
fn get_block_size() -> u64 {
|
fn get_block_size() -> u64 {
|
||||||
// All os specific implementations of MetatdataExt seem to define a block as 512 bytes
|
// All os specific implementations of MetatdataExt seem to define a block as 512 bytes
|
||||||
// https://doc.rust-lang.org/std/os/linux/fs/trait.MetadataExt.html#tymethod.st_blocks
|
// https://doc.rust-lang.org/std/os/linux/fs/trait.MetadataExt.html#tymethod.st_blocks
|
||||||
512
|
512
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_family = "unix")]
|
||||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
|
||||||
use std::os::linux::fs::MetadataExt;
|
|
||||||
match d.metadata().ok() {
|
|
||||||
Some(md) => {
|
|
||||||
let inode = Some((md.st_ino(), md.st_dev()));
|
|
||||||
if use_apparent_size {
|
|
||||||
Some((md.len(), inode))
|
|
||||||
} else {
|
|
||||||
Some((md.st_blocks() * get_block_size(), inode))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "unix")]
|
|
||||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
match d.metadata().ok() {
|
d.metadata.as_ref().unwrap().as_ref().ok().map(|md| {
|
||||||
Some(md) => {
|
|
||||||
let inode = Some((md.ino(), md.dev()));
|
let inode = Some((md.ino(), md.dev()));
|
||||||
if use_apparent_size {
|
if use_apparent_size {
|
||||||
Some((md.len(), inode))
|
(md.len(), inode)
|
||||||
} else {
|
} else {
|
||||||
Some((md.blocks() * get_block_size(), inode))
|
(md.blocks() * get_block_size(), inode)
|
||||||
}
|
|
||||||
}
|
|
||||||
None => None,
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_family = "windows")]
|
||||||
pub fn get_metadata(d: &DirEntry, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
pub fn get_metadata(d: &DirEntry, _use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||||
use std::os::macos::fs::MetadataExt;
|
use winapi_util::file::information;
|
||||||
match d.metadata().ok() {
|
use winapi_util::Handle;
|
||||||
Some(md) => {
|
|
||||||
let inode = Some((md.st_ino(), md.st_dev()));
|
let h = Handle::from_path_any(d.path()).ok()?;
|
||||||
if use_apparent_size {
|
let info = information(&h).ok()?;
|
||||||
Some((md.len(), inode))
|
|
||||||
} else {
|
Some((
|
||||||
Some((md.st_blocks() * get_block_size(), inode))
|
info.file_size(),
|
||||||
}
|
Some((info.file_index(), info.volume_serial_number())),
|
||||||
}
|
))
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "unix", target_os = "macos")))]
|
#[cfg(all(not(target_family = "windows"), not(target_family = "unix")))]
|
||||||
pub fn get_metadata(d: &DirEntry, _apparent: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
pub fn get_metadata(d: &DirEntry, _apparent: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||||
match d.metadata().ok() {
|
d.metadata
|
||||||
Some(md) => Some((md.len(), None)),
|
.as_ref()
|
||||||
None => None,
|
.unwrap()
|
||||||
|
.as_ref()
|
||||||
|
.ok()
|
||||||
|
.map(|md| (md.len(), None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
pub fn get_filesystem(file_path: &str) -> Result<u64, io::Error> {
|
||||||
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
let metadata = fs::metadata(file_path)?;
|
||||||
|
Ok(metadata.dev())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
pub fn get_filesystem(file_path: &str) -> Result<u64, io::Error> {
|
||||||
|
use winapi_util::file::information;
|
||||||
|
use winapi_util::Handle;
|
||||||
|
|
||||||
|
let h = Handle::from_path_any(file_path)?;
|
||||||
|
let info = information(&h)?;
|
||||||
|
Ok(info.volume_serial_number())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user