diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 000000000..4097f5701 --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,10 @@ +[advisories] +ignore = [ + # FIXME!: See https://github.com/RustCrypto/RSA/issues/19#issuecomment-1822995643. + # There is no workaround available yet. + "RUSTSEC-2023-0071", + # FIXME!: proc-macro-error's maintainer seems to be unreachable, we use `merge` which is using this. + # `merge` is self-hosted on another platform, we should check if and how to replace it/open upstream + # issue for updating the dependency. + "RUSTSEC-2024-0370", +] diff --git a/.github/renovate.json b/.github/renovate.json index 8eb6fdce5..1e49a3876 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,52 +1,4 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended", - ":dependencyDashboard", - "helpers:pinGitHubActionDigests" - ], - "separateMinorPatch": false, - "prHourlyLimit": 1, - "prConcurrentLimit": 1, - "major": { - "dependencyDashboardApproval": true - }, - "labels": [ - "A-dependencies" - ], - "packageRules": [ - { - "description": "Automerge pin updates for GitHub Actions", - "matchDatasources": [ - "github-actions" - ], - "matchDepTypes": [ - "action" - ], - "matchUpdateTypes": [ - "pin", - "digest", - "pinDigest" - ], - "labels": [ - "A-ci" - ], - "automerge": true - }, - { - "matchDatasources": [ - "cargo" - ], - "extends": [ - "schedule:weekly" - ] - } - ], - "lockFileMaintenance": { - "enabled": true, - "automerge": true, - "extends": [ - "schedule:monthly" - ] - } + "extends": ["local>rustic-rs/.github:renovate-config"] } diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 52735c7e8..22c76d612 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -14,31 +14,36 @@ on: merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: audit: if: ${{ github.repository_owner == 'rustic-rs' }} runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 # Ensure that the latest version of Cargo is installed - name: Install Rust toolchain uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: toolchain: stable - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 - - uses: rustsec/audit-check@dd51754d4e59da7395a4cd9b593f0ff2d61a9b95 # v1.4.1 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 + - uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2.0.0 with: token: ${{ secrets.GITHUB_TOKEN }} + ignore: RUSTSEC-2023-0071 # rsa thingy, ignored for now cargo-deny: name: Run cargo-deny if: ${{ github.repository_owner == 'rustic-rs' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: EmbarkStudios/cargo-deny-action@1e59595bed8fc55c969333d08d7817b36888f0c5 # v1 + - uses: EmbarkStudios/cargo-deny-action@8371184bd11e21dcf8ac82ebf8c9c9f74ebf7268 # v2 with: command: check bans licenses sources diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b833a46e2..f91ffc145 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,12 +15,16 @@ on: merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: fmt: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: @@ -34,17 +38,17 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - feature: [default] + feature: [release] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: toolchain: stable components: clippy - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 - name: Run clippy - run: cargo clippy --all-targets --features ${{ matrix.feature }} -- -D warnings + run: cargo clippy --locked --all-targets --features ${{ matrix.feature }} -- -D warnings test: name: Test @@ -52,18 +56,18 @@ jobs: strategy: matrix: rust: [stable] - feature: [default] + feature: [release] job: - os: macos-latest - os: ubuntu-latest - os: windows-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 if: github.event_name != 'pull_request' with: fetch-depth: 0 - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 if: github.event_name == 'pull_request' with: ref: ${{ github.event.pull_request.head.sha }} @@ -73,7 +77,7 @@ jobs: uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: toolchain: stable - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 - name: Run Cargo Test run: cargo test -r --all-targets --features ${{ matrix.feature }} --workspace @@ -88,12 +92,12 @@ jobs: - os: ubuntu-latest - os: windows-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 if: github.event_name != 'pull_request' with: fetch-depth: 0 - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 if: github.event_name == 'pull_request' with: ref: ${{ github.event.pull_request.head.sha }} @@ -103,7 +107,7 @@ jobs: uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: toolchain: stable - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 - name: Run Cargo Doc run: cargo doc --no-deps --all-features --workspace --examples diff --git a/.github/workflows/cross-ci.yml b/.github/workflows/cross-ci.yml index 15b24ad99..d7a9a8794 100644 --- a/.github/workflows/cross-ci.yml +++ b/.github/workflows/cross-ci.yml @@ -7,8 +7,6 @@ on: push: branches: - main - - "renovate/**" - - "release/**" paths-ignore: - "**/*.md" merge_group: @@ -18,6 +16,10 @@ defaults: run: shell: bash +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: cross-check: name: Cross checking ${{ matrix.job.target }} @@ -26,7 +28,7 @@ jobs: fail-fast: false matrix: rust: [stable] - feature: [default] + feature: [release] job: - os: windows-latest os-name: windows @@ -38,7 +40,7 @@ jobs: target: x86_64-pc-windows-gnu architecture: x86_64 use-cross: false - - os: macos-latest + - os: macos-13 os-name: macos target: x86_64-apple-darwin architecture: x86_64 @@ -63,6 +65,11 @@ jobs: target: aarch64-unknown-linux-gnu architecture: arm64 use-cross: true + - os: ubuntu-latest + os-name: linux + target: aarch64-unknown-linux-musl + architecture: arm64 + use-cross: true - os: ubuntu-latest os-name: linux target: i686-unknown-linux-gnu @@ -81,7 +88,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Run Cross-CI action uses: rustic-rs/cross-ci-action@main diff --git a/.github/workflows/lint-docs.yml b/.github/workflows/lint-docs.yml index 266a0eec0..1051b12c1 100644 --- a/.github/workflows/lint-docs.yml +++ b/.github/workflows/lint-docs.yml @@ -7,11 +7,15 @@ on: merge_group: types: [checks_requested] +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: style: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: dprint/check@2f1cf31537886c3bfb05591c031f7744e48ba8a1 # v2.2 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 549013e53..de3315ed3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -37,7 +37,7 @@ jobs: architecture: x86_64 binary-postfix: ".exe" use-cross: false - - os: macos-latest + - os: macos-13 os-name: macos target: x86_64-apple-darwin architecture: x86_64 @@ -67,6 +67,12 @@ jobs: architecture: arm64 binary-postfix: "" use-cross: true + - os: ubuntu-latest + os-name: linux + target: aarch64-unknown-linux-musl + architecture: arm64 + binary-postfix: "" + use-cross: true - os: ubuntu-latest os-name: linux target: i686-unknown-linux-gnu @@ -89,7 +95,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 # fetch all history so that git describe works - name: Create binary artifact @@ -120,7 +126,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download all workflow run artifacts - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 - name: Releasing nightly builds shell: bash run: | @@ -148,7 +154,7 @@ jobs: mkdir -p $WORKING_DIR/$DEST_DIR # do the copy - for i in binary-*; do cp -a $i/* $WORKING_DIR/$DEST_DIR; done + for artifact_dir in binary-*; do cp -a $artifact_dir/* $WORKING_DIR/$DEST_DIR; done # create the commit cd $WORKING_DIR diff --git a/.github/workflows/prebuilt-pr.yml b/.github/workflows/prebuilt-pr.yml index 0a689e6fc..6780db36a 100644 --- a/.github/workflows/prebuilt-pr.yml +++ b/.github/workflows/prebuilt-pr.yml @@ -10,6 +10,10 @@ on: - "docs/**/*" workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + env: BINARY_NAME: rustic @@ -79,7 +83,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: fetch-depth: 0 # fetch all history so that git describe works - name: Create binary artifact diff --git a/.github/workflows/release-cd.yml b/.github/workflows/release-cd.yml new file mode 100644 index 000000000..5025fdf0d --- /dev/null +++ b/.github/workflows/release-cd.yml @@ -0,0 +1,165 @@ +name: Continuous Deployment (Release) + +on: + push: + tags: + # Run on stable releases + - "v*.*.*" + # Run on release candidates + - "v*.*.*-rc*" + +defaults: + run: + shell: bash + +permissions: + contents: write + discussions: write + +env: + BINARY_NAME: rustic + BINARY_NIGHTLY_DIR: rustic + +jobs: + publish: + if: ${{ github.repository_owner == 'rustic-rs' }} + name: Publishing ${{ matrix.job.target }} + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false # so we upload the artifacts even if one of the jobs fails + matrix: + rust: [stable] + job: + - os: windows-latest + os-name: windows + target: x86_64-pc-windows-msvc + architecture: x86_64 + binary-postfix: ".exe" + use-cross: false + - os: windows-latest + os-name: windows + target: x86_64-pc-windows-gnu + architecture: x86_64 + binary-postfix: ".exe" + use-cross: false + - os: macos-13 + os-name: macos + target: x86_64-apple-darwin + architecture: x86_64 + binary-postfix: "" + use-cross: false + - os: macos-latest + os-name: macos + target: aarch64-apple-darwin + architecture: arm64 + binary-postfix: "" + use-cross: true + - os: ubuntu-latest + os-name: linux + target: x86_64-unknown-linux-gnu + architecture: x86_64 + binary-postfix: "" + use-cross: false + - os: ubuntu-latest + os-name: linux + target: x86_64-unknown-linux-musl + architecture: x86_64 + binary-postfix: "" + use-cross: false + - os: ubuntu-latest + os-name: linux + target: aarch64-unknown-linux-gnu + architecture: arm64 + binary-postfix: "" + use-cross: true + - os: ubuntu-latest + os-name: linux + target: aarch64-unknown-linux-musl + architecture: arm64 + binary-postfix: "" + use-cross: true + - os: ubuntu-latest + os-name: linux + target: i686-unknown-linux-gnu + architecture: i686 + binary-postfix: "" + use-cross: true + # TODO!: This needs a fix, linking `execinfo` fails + # - os: ubuntu-latest + # os-name: netbsd + # target: x86_64-unknown-netbsd + # architecture: x86_64 + # binary-postfix: "" + # use-cross: true + - os: ubuntu-latest + os-name: linux + target: armv7-unknown-linux-gnueabihf + architecture: armv7 + binary-postfix: "" + use-cross: true + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 # fetch all history so that git describe works + - name: Create binary artifact + uses: rustic-rs/create-binary-artifact-action@main # dev + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.job.target }} + use-cross: ${{ matrix.job.use-cross }} + binary-postfix: ${{ matrix.job.binary-postfix }} + os: ${{ runner.os }} + binary-name: ${{ env.BINARY_NAME }} + package-secondary-name: ${{ matrix.job.target}} + github-token: ${{ secrets.GITHUB_TOKEN }} + gpg-release-private-key: ${{ secrets.GPG_RELEASE_PRIVATE_KEY }} + gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }} + rsign-release-private-key: ${{ secrets.RSIGN_RELEASE_PRIVATE_KEY }} + rsign-passphrase: ${{ secrets.RSIGN_PASSPHRASE }} + github-ref: ${{ github.ref }} + sign-release: true + hash-release: true + use-project-version: true + use-tag-version: true # IMPORTANT: this is being used to make sure the tag that is built is in the archive filename, so automation can download the correct version + + create-release: + name: Creating release with artifacts + needs: publish + runs-on: ubuntu-latest + steps: + # Need to clone the repo again for the CHANGELOG.md + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 # fetch all history so that git describe works + + - name: Download all workflow run artifacts + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + + - name: Creating Release + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2 + with: + discussion_category_name: "Announcements" + draft: true + body_path: ${{ github.workspace }}/CHANGELOG.md + fail_on_unmatched_files: true + files: | + binary-*/${{ env.BINARY_NAME }}-*.tar.gz* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + result: + if: ${{ github.repository_owner == 'rustic-rs' }} + name: Result (Release CD) + runs-on: ubuntu-latest + needs: + - publish + - create-release + steps: + - name: Mark the job as successful + run: exit 0 + if: success() + - name: Mark the job as unsuccessful + run: exit 1 + if: "!success()" diff --git a/.github/workflows/release-ci.yml b/.github/workflows/release-ci.yml index 96328ea58..3c49efbc4 100644 --- a/.github/workflows/release-ci.yml +++ b/.github/workflows/release-ci.yml @@ -15,6 +15,10 @@ on: # - rustic-rs # - rustic_testing +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + jobs: # determine-package: # name: Determine package to release @@ -39,12 +43,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 with: toolchain: stable - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 - name: Run Cargo Test run: cargo test --release -p rustic-rs --test completions -- --ignored # diff --git a/.github/workflows/release-image.yml b/.github/workflows/release-image.yml new file mode 100644 index 000000000..8bfde9f47 --- /dev/null +++ b/.github/workflows/release-image.yml @@ -0,0 +1,25 @@ +name: Release Docker Image + +on: [release] + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3 + + - name: Login to Docker Hub + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6 + with: + push: true + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/rustic-rs/rustic:latest,ghcr.io/rustic-rs/rustic:${{ github.ref_name }} + build-args: RUSTIC_VERSION=${{ github.ref_name }} diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 000000000..5ceab6a02 --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,36 @@ +name: Release-plz + +permissions: + pull-requests: write + contents: write + +on: + push: + branches: + - main + +jobs: + release-plz: + name: Release-plz + if: ${{ github.repository_owner == 'rustic-rs' }} + runs-on: ubuntu-latest + steps: + - name: Generate GitHub token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1 + id: generate-token + with: + app-id: ${{ secrets.RELEASE_PLZ_APP_ID }} + private-key: ${{ secrets.RELEASE_PLZ_APP_PRIVATE_KEY }} + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Run release-plz + uses: MarcoIeni/release-plz-action@394e0e463367550953346be95d427f80f4f7ae30 # v0.5 + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml deleted file mode 100644 index 707032345..000000000 --- a/.github/workflows/release-pr.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Open a release PR -on: - workflow_dispatch: - inputs: - crate: - description: Crate to release - required: true - type: choice - options: - - rustic-rs - version: - description: Version to release - required: true - type: string - -jobs: - make-release-pr: - if: ${{ github.repository_owner == 'rustic-rs' }} - permissions: - id-token: write # Enable OIDC - pull-requests: write - contents: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: chainguard-dev/actions/setup-gitsign@main - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 - - name: Install cargo-release - uses: taiki-e/install-action@f7c663c03b51ed0d93e9cec22a575d3f02175989 # v2 - with: - tool: cargo-release - - uses: cargo-bins/release-pr@deeacca5a38bacc74a3f444b798f4b9bba40f6ad # v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - version: ${{ inputs.version }} - crate-name: ${{ inputs.crate }} - check-semver: false # FIXME: Set back to true and check rustic-rs library API diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index fcbf9e219..000000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,122 +0,0 @@ -on: - push: - -name: Build release binaries - -jobs: - publish: - if: startsWith(github.ref, 'refs/tags/') - name: Publishing ${{ matrix.job.target }} - runs-on: ${{ matrix.job.os }} - strategy: - matrix: - rust: [stable] - job: - - os: windows-latest - os-name: windows - target: x86_64-pc-windows-msvc - architecture: x86_64 - binary-postfix: "" - use-cross: false - - os: macos-latest - os-name: macos - target: x86_64-apple-darwin - architecture: x86_64 - binary-postfix: "" - use-cross: false - - os: macos-latest - os-name: macos - target: aarch64-apple-darwin - architecture: arm64 - binary-postfix: "" - use-cross: true - - os: ubuntu-latest - os-name: linux - target: x86_64-unknown-linux-gnu - architecture: x86_64 - binary-postfix: "" - use-cross: false - - os: ubuntu-latest - os-name: linux - target: x86_64-unknown-linux-musl - architecture: x86_64 - binary-postfix: "" - use-cross: false - - os: ubuntu-latest - os-name: linux - target: aarch64-unknown-linux-gnu - architecture: arm64 - binary-postfix: "" - use-cross: true - - os: ubuntu-latest - os-name: linux - target: i686-unknown-linux-gnu - architecture: i686 - binary-postfix: "" - use-cross: true - - os: ubuntu-latest - os-name: netbsd - target: x86_64-unknown-netbsd - architecture: x86_64 - binary-postfix: "" - use-cross: true - - steps: - - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - with: - fetch-depth: 0 - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 # v1 - with: - toolchain: ${{ matrix.rust }} - targets: ${{ matrix.job.target }} - - name: install compiler - shell: bash - run: | - if [[ ${{ matrix.job.target }} == x86_64-unknown-linux-musl ]]; then - sudo apt update - sudo apt-get install -y musl-tools - fi - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 - with: - key: ${{ matrix.job.target }} - - name: Set Version - shell: bash - run: echo "PROJECT_VERSION=$(git describe --tags)" >> $GITHUB_ENV - - name: Cargo build - uses: ClementTsang/cargo-action@a211c79cf22973eb590277586fbea20269ca3ca0 # v0 (attention: this should be double checked for security issues) - with: - command: build - use-cross: ${{ matrix.job.use-cross }} - toolchain: ${{ matrix.rust }} - args: --release --target ${{ matrix.job.target }} - - - name: Packaging final binary - if: ${{ !contains(github.ref_name, '/') }} - shell: bash - run: | - cd target/${{ matrix.job.target }}/release - - ########## create tar.gz ########## - RELEASE_NAME=rustic-${{ github.ref_name }}-${{ matrix.job.target}} - tar czvf $RELEASE_NAME.tar.gz rustic${{ matrix.job.binary-postfix }} - - ########## create sha256 ########## - if [[ ${{ runner.os }} == 'Windows' ]]; then - certutil -hashfile $RELEASE_NAME.tar.gz sha256 | grep -E [A-Fa-f0-9]{64} > $RELEASE_NAME.sha256 - else - shasum -a 256 $RELEASE_NAME.tar.gz > $RELEASE_NAME.sha256 - fi - - name: Storing binary as artefact - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3 - with: - name: binary-${{ matrix.job.target}} - path: target/${{ matrix.job.target }}/release/rustic-${{ github.ref_name }}-${{ matrix.job.target}}.tar.gz - - name: Releasing release versions - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1 - with: - files: | - target/${{ matrix.job.target }}/release/rustic-*.tar.gz - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 11b4855d2..0204f618d 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -13,4 +13,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ISSUE_URL: ${{ github.event.issue.html_url }} run: | - gh issue edit $ISSUE_URL --add-label "S-triage" + # check if issue doesn't have any labels + if [[ $(gh issue view $ISSUE_URL --json labels -q '.labels | length') -eq 0 ]]; then + # add S-triage label + gh issue edit $ISSUE_URL --add-label "S-triage" + fi diff --git a/.github/workflows/update-completions.yml b/.github/workflows/update-completions.yml index 4e7b503da..5e7e2c258 100644 --- a/.github/workflows/update-completions.yml +++ b/.github/workflows/update-completions.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: ref: refs/heads/${{ inputs.pr_branch }} @@ -28,7 +28,7 @@ jobs: with: toolchain: stable - - uses: Swatinem/rust-cache@a95ba195448af2da9b00fb742d14ffaaf3c21f43 # v2 + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 - name: Run Cargo Install id: generated-fixtures diff --git a/.gitignore b/.gitignore index d8a1c86a0..67adf7187 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,8 @@ mutants.out cargo-test* coverage/*lcov .testscompletions-* + +# Ignore generated test files +/tests/generated/*.toml +/tests/generated/*.log +/tests/generated/test-restore diff --git a/CHANGELOG.md b/CHANGELOG.md index 56efe847e..9d6b1445b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,382 @@ All notable changes to this project will be documented in this file. +## [0.9.4](https://github.com/rustic-rs/rustic/compare/v0.9.3...v0.9.4) - 2024-10-24 + +### Added + +- *(commands)* Add tar output to dump command ([#1328](https://github.com/rustic-rs/rustic/pull/1328)) + +### Fixed + +- clippy lints for new Rust version ([#1329](https://github.com/rustic-rs/rustic/pull/1329)) +- *(deps)* downgrade self-update to fix problems finding right target ([#1323](https://github.com/rustic-rs/rustic/pull/1323)) + +### Other + +- *(deps)* remove once_cell and replace with std::sync::LazyLock, increase MSRV to 1.80.0 ([#1337](https://github.com/rustic-rs/rustic/pull/1337)) +- *(deps)* update tokio, ratatui, and tui-textarea ([#1336](https://github.com/rustic-rs/rustic/pull/1336)) +- *(deps)* update rustic_core and rustic_backend ([#1334](https://github.com/rustic-rs/rustic/pull/1334)) +- *(deps)* update abscissa framework ([#1330](https://github.com/rustic-rs/rustic/pull/1330)) +- introduce a new feature 'release' that includes the 'self-update' feature ([#1307](https://github.com/rustic-rs/rustic/pull/1307)) + +## [0.9.3](https://github.com/rustic-rs/rustic/compare/v0.9.2...v0.9.3) - 2024-10-10 + +### Fixed + +- *(deps)* update rustic_core to version 0.5.3 ([#1314](https://github.com/rustic-rs/rustic/pull/1314)) + +### Other + +- add status badge for docker image build and shorten workflow name ([#1311](https://github.com/rustic-rs/rustic/pull/1311)) + +## [0.9.2](https://github.com/rustic-rs/rustic/compare/v0.9.1...v0.9.2) - 2024-10-09 + +### Added + +- *(config)* Add hooks ([#1218](https://github.com/rustic-rs/rustic/pull/1218)) + +### Other + +- *(deps)* update rustic_core ([#1309](https://github.com/rustic-rs/rustic/pull/1309)) +- build and publish docker image on release ([#1297](https://github.com/rustic-rs/rustic/pull/1297)) + +## [0.9.1](https://github.com/rustic-rs/rustic/compare/v0.9.0...v0.9.1) - 2024-10-03 + +### Added + +- *(config)* add more filters ([#1263](https://github.com/rustic-rs/rustic/pull/1263)) +- *(check)* Allow to only check trees+packs for given snapshots ([#1230](https://github.com/rustic-rs/rustic/pull/1230)) +- *(commands)* add a `docs` command to easily access the user, dev and config documentation ([#1276](https://github.com/rustic-rs/rustic/pull/1276)) + +### Fixed + +- *(docs/cli)* improve the descriptions of the CLI commands ([#1277](https://github.com/rustic-rs/rustic/pull/1277)) +- *(deps)* update rustic_core and other dependencies and fix merge precedence ([#1282](https://github.com/rustic-rs/rustic/pull/1282)) +- *(docs)* update configuration documentation to align with recent changes ([#1280](https://github.com/rustic-rs/rustic/pull/1280)) + +### Other + +- *(deps)* upgrade dependencies ([#1289](https://github.com/rustic-rs/rustic/pull/1289)) +- add triage label to new issues only if no label has been set when creating it ([#1287](https://github.com/rustic-rs/rustic/pull/1287)) +- *(interactive)* use update methods for refreshing snapshots ([#1285](https://github.com/rustic-rs/rustic/pull/1285)) + +## [0.9.0](https://github.com/rustic-rs/rustic/compare/v0.8.1...v0.9.0) - 2024-09-29 + +### Bug Fixes + +- [**breaking**] use multiple options only as array in config profile + ([#1240](https://github.com/rustic-rs/rustic/pull/1240)) +- Allow snapshots to be modified and marked to forget + ([#1253](https://github.com/rustic-rs/rustic/pull/1253)) +- make ls and find show the year of mtime date + ([#1249](https://github.com/rustic-rs/rustic/pull/1249)) +- ls: Remove printing trailing space + ([#1247](https://github.com/rustic-rs/rustic/pull/1247)) +- webdav/forget: correctly use application config + ([#1241](https://github.com/rustic-rs/rustic/pull/1241)) + +### Features + +- [**breaking**] copy: Use config profile as target + ([#1131](https://github.com/rustic-rs/rustic/pull/1131)) +- backup: Add option `stdin-command` + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- Add list indexpacks and list indexcontent commands + ([#1254](https://github.com/rustic-rs/rustic/pull/1254)) +- Add option `--only-identical` for `diff` to allow for bitrot check + ([#1250](https://github.com/rustic-rs/rustic/pull/1250)) +- ls: Add option --json ([#1251](https://github.com/rustic-rs/rustic/pull/1251)) +- backup: Add option `--long` + ([#1159](https://github.com/rustic-rs/rustic/pull/1159)) + +### Documentation + +- update installation instructions in readme to use `--locked` flag for install + from crates.io +- update RepositoryErrorKind rustdoc following rustic_core change + ([#1237](https://github.com/rustic-rs/rustic/pull/1237)) + +### Other + +- Remove self-update from default crate features + ([#1139](https://github.com/rustic-rs/rustic/pull/1139)) +- Reduce memory usage of restore + ([#1069](https://github.com/rustic-rs/rustic/pull/1069)) +- *(deps)* update rust crate libc to v0.2.159 + ([#1257](https://github.com/rustic-rs/rustic/pull/1257)) +- *(deps)* lock file maintenance + ([#1269](https://github.com/rustic-rs/rustic/pull/1269)) +- *(deps)* update rust crate rstest to 0.23 + ([#1267](https://github.com/rustic-rs/rustic/pull/1267)) +- *(deps)* update rust crate tempfile to v3.13.0 + ([#1266](https://github.com/rustic-rs/rustic/pull/1266)) +- *(deps)* update marcoieni/release-plz-action digest to 8b0f89a + ([#1265](https://github.com/rustic-rs/rustic/pull/1265)) +- *(deps)* update embarkstudios/cargo-deny-action action to v2 + ([#1259](https://github.com/rustic-rs/rustic/pull/1259)) +- *(deps)* update rustsec/audit-check action to v2 + ([#1260](https://github.com/rustic-rs/rustic/pull/1260)) +- *(deps)* update softprops/action-gh-release action to v2 + ([#1258](https://github.com/rustic-rs/rustic/pull/1258)) +- *(deps)* update embarkstudios/cargo-deny-action digest to 3f4a782 + ([#1228](https://github.com/rustic-rs/rustic/pull/1228)) + +## [0.8.1] - 2024-09-08 + +### Bug Fixes + +- Allow to compile without tui feature + ([#1208](https://github.com/rustic-rs/rustic/issues/1208)) +- Use cargo --locked in CI pipeline + ([#1207](https://github.com/rustic-rs/rustic/issues/1207)) +- Return exitcode ([#1220](https://github.com/rustic-rs/rustic/issues/1220)) +- "Incorrect Password" error is now only shown if password is really incorrect. + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.1)) +- Group by now works as expected + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.1)) +- A bug in `keep-tags` and `filter-tags` has been fixed. + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.1)) +- Building OpenBSD platform target is now possible again + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.1)) + +### Documentation + +- Update config profile readme + ([#1221](https://github.com/rustic-rs/rustic/issues/1221)) + +### Features + +- Add autocompletion hints + ([#1225](https://github.com/rustic-rs/rustic/issues/1225)) +- Allow to modify filters + ([#1210](https://github.com/rustic-rs/rustic/issues/1210)) +- Allow to view text files + ([#1216](https://github.com/rustic-rs/rustic/issues/1216)) + +### Generated + +- Updated Completions fixtures + +### Miscellaneous Tasks + +- Bump quinn-proto from 0.11.6 to 0.11.8 + ([#1223](https://github.com/rustic-rs/rustic/issues/1223)) +- Dependency updates ([#1227](https://github.com/rustic-rs/rustic/issues/1227)) + +## [0.8.0] - 2024-08-21 + +### Bug Fixes + +- Add comments for owncloud and nextcloud dependent settings +- Rename service examples +- Ask for password in backup and copy command if it is missing + ([#1061](https://github.com/rustic-rs/rustic/issues/1061)) +- Ask for missing password in copy when initializing + ([#1063](https://github.com/rustic-rs/rustic/issues/1063)) +- Fix possible overflow in progress bar ETA + ([#1079](https://github.com/rustic-rs/rustic/issues/1079)) +- Correct b2.toml ([#1072](https://github.com/rustic-rs/rustic/issues/1072)) +- Show log filename if open/creation failed + ([#1111](https://github.com/rustic-rs/rustic/issues/1111)) +- [**breaking**] Multiple paths in config profile as array + ([#1124](https://github.com/rustic-rs/rustic/issues/1124)) +- Respect delete-protection when running forget with ids + ([#1149](https://github.com/rustic-rs/rustic/issues/1149)) +- Reset terminal no matter what + ([#1175](https://github.com/rustic-rs/rustic/issues/1175)) +- Allow missing fields in snapshot summary (to support restic 0.17.0) + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- Allow non-value/null xattr fields + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- Backup file if listing xattrs fails + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- limit memory usage for restore when having large pack files + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- prune: correct number of packs to repack + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) + +### Features + +- [**breaking**] Show-config now outputs toml + ([#1095](https://github.com/rustic-rs/rustic/issues/1095)) +- [**breaking**] Allow specifying many options in config profile without array + ([#1130](https://github.com/rustic-rs/rustic/issues/1130)) +- Add interactive snapshots mode + ([#1114](https://github.com/rustic-rs/rustic/issues/1114)) +- The find command has been added + ([#1136](https://github.com/rustic-rs/rustic/issues/1136)) +- Allow setting extra repository options via env variables + ([#1081](https://github.com/rustic-rs/rustic/issues/1081)) +- Add --check-index option + ([#1078](https://github.com/rustic-rs/rustic/issues/1078)) +- Add extra check before writing data and add --set-extra-check config option + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- Add append-only repository mode + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- forget: Enforce to have a --keep-* option and add --keep-none. + ([rustic_core](https://github.com/rustic-rs/rustic_core/releases/tag/rustic_core-v0.3.0)) +- Add s3_idrive config and move configs to a services subdirectory + ([#1048](https://github.com/rustic-rs/rustic/issues/1048)) +- Add example config for owncloud and nextcloud + ([#1052](https://github.com/rustic-rs/rustic/issues/1052)) +- Use human-panic to print better error messages in case rustic panics + ([#1065](https://github.com/rustic-rs/rustic/issues/1065)) +- Prune: Add more debug output + ([#1064](https://github.com/rustic-rs/rustic/issues/1064)) +- Add interactive ls mode + ([#1117](https://github.com/rustic-rs/rustic/issues/1117)) +- Add interactive restore + ([#1123](https://github.com/rustic-rs/rustic/issues/1123)) +- Interactive Ls: remember parent position + ([#1126](https://github.com/rustic-rs/rustic/issues/1126)) +- Use RFC3339 time format in logfile + ([#1133](https://github.com/rustic-rs/rustic/issues/1133)) +- Add possibility to change snapshot description + ([#1137](https://github.com/rustic-rs/rustic/issues/1137)) +- Interactive: Allow to delete snapshots + ([#1143](https://github.com/rustic-rs/rustic/issues/1143)) +- Interactive: Prompt before exiting + ([#1146](https://github.com/rustic-rs/rustic/issues/1146)) +- Document opendal options connections and throttle +- Add better progress bars + ([#1152](https://github.com/rustic-rs/rustic/issues/1152)) +- Show diff statistics + ([#1178](https://github.com/rustic-rs/rustic/issues/1178)) + +### Documentaton + +- Update configuration README + ([#1088](https://github.com/rustic-rs/rustic/issues/1088)) +- Fix typo in find.rs ([#1187](https://github.com/rustic-rs/rustic/issues/1187)) + +### Miscellaneous Tasks + +- Fix cargo-binstall metadata +- Move rustic_testing into rustic_core +- Break old ci jobs when new commits are pushed so we don't fill up the queue +- Bump mio from 0.8.10 to 0.8.11 + ([#1089](https://github.com/rustic-rs/rustic/issues/1089)) +- Update deps and adapt to rustic_core changes +- Bump h2 from 0.3.25 to 0.3.26 + ([#1113](https://github.com/rustic-rs/rustic/issues/1113)) +- Bump rustls from 0.21.10 to 0.21.11 + ([#1127](https://github.com/rustic-rs/rustic/issues/1127)) +- Update rustic_core and rustic_backend + ([#1201](https://github.com/rustic-rs/rustic/issues/1201)) + +### Testing + +- Replace missing crates folder with src +- Refactor integration tests to assert_cmd and predicates, test all configs in + config subdirectory ([#1060](https://github.com/rustic-rs/rustic/issues/1060)) + +## [0.7.0] - 2024-02-03 + +### Packaging + +- Enable RPM file build target + ([#951](https://github.com/rustic-rs/rustic/issues/951)) + +### Bug Fixes + +- Remove unmaintained `actions-rs` ci actions +- Remove unmaintained `actions-rs/cargo` ci action with cross. +- Remove unmaintained `actions-rs/toolchain` ci action +- Log config file logs after reading config files + ([#961](https://github.com/rustic-rs/rustic/issues/961)) +- Fix progress for copy command + ([#965](https://github.com/rustic-rs/rustic/issues/965)) +- Enable abscissa_core testing feature only for dev + ([#976](https://github.com/rustic-rs/rustic/issues/976)) +- Update github action to download artifacts, as upload/download actions from + nightly workflow were incompatible with each other +- Update rust crate duct to 0.13.7 + ([#991](https://github.com/rustic-rs/rustic/issues/991)) +- Update rust crate libc to 0.2.151 + ([#992](https://github.com/rustic-rs/rustic/issues/992)) +- Diff: Add local: to path syntax + ([#1000](https://github.com/rustic-rs/rustic/issues/1000)) +- Update rust crate libc to 0.2.152 + ([#1016](https://github.com/rustic-rs/rustic/issues/1016)) +- Error handling when entering passwords + ([#963](https://github.com/rustic-rs/rustic/issues/963)) +- Use hyphen in cli api for numeric-uid-gid + +### Documentation + +- Update changelog +- Fix new lines in changelog +- Update changelog + +### Features + +- Add --quiet option to backup and forget + ([#964](https://github.com/rustic-rs/rustic/issues/964)) +- Allow building without self-update feature + ([#975](https://github.com/rustic-rs/rustic/issues/975)) +- Add option --numeric-uid-gid to ls + ([#1019](https://github.com/rustic-rs/rustic/issues/1019)) +- Add colors to help texts + ([#1007](https://github.com/rustic-rs/rustic/issues/1007)) +- Add webdav command ([#1024](https://github.com/rustic-rs/rustic/issues/1024)) + +### Generated + +- Updated Completions fixtures + +### Miscellaneous Tasks + +- Run actions that need secrets.GITHUB_TOKEN only on rustic-rs org +- Update dtolnay/rust-toolchain +- Update taiki-e/install-action +- Update rustsec/audit-check +- Netbsd nightly builds fail due to missing execinfo, so we don't build on it + for now +- Upgrade dprint config +- Activate automerge for github action digest update +- Activate automerge for github action digest update +- Automerge lockfile maintenance +- Try to fix nightly build +- Display structure of downloaded artifact files +- Display structure of downloaded artifact files II +- Release +- Do not run twice on release branches +- Remove release workflow and fix release continuous deployment +- Run on tag push +- Add release candidates to CD +- Remove conditional for checking tags +- Fix path for release files for CD +- Fix path for release files for CD, second approach with full file name +- Fix binstall pkg-url +- Use tag version in directory names for automation to download new versions +- Set `max-parallel` to 1 for build matrix +- Replace max-parallel with an own job + +### Refactor + +- Adjust to changes in rustic_core for added rustic_backend + ([#966](https://github.com/rustic-rs/rustic/issues/966)) + +### Testing + +- Add missing powershell profile to completions test + +### Build + +- Bump zerocopy from 0.7.25 to 0.7.31 + ([#967](https://github.com/rustic-rs/rustic/issues/967)) +- Bump h2 from 0.3.22 to 0.3.24 + ([#1009](https://github.com/rustic-rs/rustic/issues/1009)) + +### Diff + +- Improve code (better lifetime handling) + +### Ls + +- Add alternative option name --numeric-id + ## [0.6.0] - 2023-10-23 ### Breaking Changes diff --git a/Cargo.lock b/Cargo.lock index d828cbef0..7ffd2d837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "abscissa_core" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8346a52bf3fb445d5949d144c37360ad2f1d7950cfcc6d4e9e4999b1cd1bd42a" +checksum = "de5df09bc18cb069dec8524aff811cbe9d7bf5f4b78ef739ef125a37b9d3f044" dependencies = [ "abscissa_derive", "arc-swap", @@ -21,18 +21,18 @@ dependencies = [ "semver", "serde", "termcolor", - "toml 0.5.11", + "toml", "tracing", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", "wait-timeout", ] [[package]] name = "abscissa_derive" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55bfb86e57d13c06e482c570826ddcddcc8f07fab916760e8911141d4fda8b62" +checksum = "e04c7df69b2c6b9b6dba8422d1295e58ac4bcfc7c9e7e7d4c55a38aaff2ad92a" dependencies = [ "ident_case", "proc-macro2", @@ -56,6 +56,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.5.2" @@ -68,9 +74,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if 1.0.0", "cipher", @@ -79,9 +85,9 @@ dependencies = [ [[package]] name = "aes256ctr_poly1305aes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2926121f4e92f1682d993563f9128b65978dab1fb3879f8f533e97c0697483" +checksum = "c12ce6f8614befd457e18cc05cba86277779cd61a5f94a71368576cef2e6c3c4" dependencies = [ "aead", "aes", @@ -94,27 +100,33 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", "const-random", "getrandom", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -132,63 +144,64 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "array-init" @@ -196,11 +209,186 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" +[[package]] +name = "assert_cmd" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-tls" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ae3c9eba89d472a0e4fe1dea433df78fbbe63d2b764addaf2ba3a6bde89a5e" +dependencies = [ + "futures-core", + "futures-io", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "webpki-roots 0.22.6", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "awaitable" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70af449c9a763cb655c6a1e5338b42d99c67190824ff90658c1e30be844c0775" +dependencies = [ + "awaitable-error", + "cfg-if 1.0.0", +] + +[[package]] +name = "awaitable-error" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "d5b3469636cdf8543cceab175efca534471f36eee12fb8374aba00eb5e7e7f8a" [[package]] name = "backoff" @@ -213,26 +401,49 @@ dependencies = [ "rand", ] +[[package]] +name = "backon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4fa97bb310c33c811334143cf64c5bb2b7b3c06e453db6b095d7061eff8f113" +dependencies = [ + "fastrand", + "gloo-timers", + "tokio", +] + [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] [[package]] name = "base64" -version = "0.21.5" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -240,11 +451,23 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bb8" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b10cf871f3ff2ce56432fddc2615ac7acc3aa22ca321f8fea800846fbb32f188" +dependencies = [ + "async-trait", + "futures-util", + "parking_lot", + "tokio", +] + [[package]] name = "binrw" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a1b8720bedc0a503fd5c90bef3fbdc397144ac7efcc5610b30bde08083d7495" +checksum = "3f36b7cb3ab9ff6a2858650d8dc360e783a5d14dc29594db48c56a3c233cc265" dependencies = [ "array-init", "binrw_derive", @@ -253,9 +476,9 @@ dependencies = [ [[package]] name = "binrw_derive" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0741a1b1a70a36a1e7fb0316bba0828f6487a3b6e577353cf974b59fbbb92081" +checksum = "20ea7a8c5c8eeffffac6d54d172444e15beffac6f817fac714460a9a9aa88da3" dependencies = [ "either", "owo-colors", @@ -272,9 +495,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -285,33 +508,62 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "bstr" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", + "regex-automata 0.4.8", "serde", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] -name = "bytes" +name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytesize" @@ -321,41 +573,42 @@ checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "cached" -version = "0.46.1" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" +checksum = "b4d73155ae6b28cf5de4cfc29aeb02b8a1c6dab883cb015d15cd514e42766846" dependencies = [ + "ahash", "cached_proc_macro", "cached_proc_macro_types", - "hashbrown 0.14.2", - "instant", + "hashbrown 0.14.5", "once_cell", "thiserror", + "web-time", ] [[package]] name = "cached_proc_macro" -version = "0.18.1" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +checksum = "2f42a145ed2d10dce2191e1dcf30cfccfea9026660e143662ba5eec4017d5daa" dependencies = [ - "darling 0.14.4", + "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "cachedir" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e236bf5873ea57ec2877445297f4da008916bfae51567131acfc54a073d694f3" +checksum = "4703f3937077db8fa35bee3c8789343c1aec2585f0146f09d658d4ccc0e8d873" dependencies = [ "tempfile", ] @@ -366,13 +619,39 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" -version = "1.0.84" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ + "jobserver", "libc", + "shlex", ] [[package]] @@ -387,17 +666,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", - "windows-targets 0.48.5", + "wasm-bindgen", + "windows-targets 0.52.6", ] [[package]] @@ -412,9 +699,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -422,9 +709,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -435,36 +722,36 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "9646e2e245bf62f45d39a0f3f36f1171ad1ea0d6967fd114bca72cb02a8fcdfb" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "color-eyre" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" dependencies = [ "backtrace", "eyre", @@ -475,46 +762,102 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "crossterm", + "crossterm 0.27.0", "strum", "strum_macros", - "unicode-width", + "unicode-width 0.1.14", +] + +[[package]] +name = "compact_str" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" +dependencies = [ + "castaway", + "cfg-if 1.0.0", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "concurrent_arena" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388754cc71073ef0e6f1f72d84ac424c12c05d88eaad708c7bc55ee5dcb4e549" +dependencies = [ + "arc-swap", + "parking_lot", + "triomphe", +] + +[[package]] +name = "conflate" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06f57b4959992e02db0da86fcb4b0c80dc112d31b823de27f61576b1c809bc45" +dependencies = [ + "conflate_derive", + "num-traits", +] + +[[package]] +name = "conflate_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9395ace5316656ca6a778aa2c28ab0c4ea2c94a8f7dc942898c20be9b7a9a4b9" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.79", ] [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", - "windows-sys 0.45.0", + "unicode-width 0.1.14", + "windows-sys 0.52.0", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-random" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" dependencies = [ "const-random-macro", ] @@ -532,15 +875,18 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -548,35 +894,43 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossbeam" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "cfg-if 1.0.0", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -586,56 +940,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if 1.0.0", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossterm" @@ -643,13 +987,29 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "crossterm_winapi", "libc", "parking_lot", "winapi", ] +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.6.0", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix", + "signal-hook", + "signal-hook-mio", + "winapi", +] + [[package]] name = "crossterm_winapi" version = "0.9.1" @@ -686,16 +1046,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if 1.0.0", "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -709,94 +1068,122 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "syn 2.0.79", ] [[package]] name = "darling" -version = "0.20.3" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] -name = "darling_core" -version = "0.20.3" +name = "darling_macro" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "fnv", - "ident_case", - "proc-macro2", + "darling_core", "quote", - "strsim", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] -name = "darling_macro" -version = "0.14.4" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", + "cfg-if 1.0.0", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] -name = "darling_macro" -version = "0.20.3" +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "dateparser" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "c2ef451feee09ae5ecd8a02e738bd9adee9266b8fa9b44e22d3ce968d8694238" dependencies = [ - "darling_core 0.20.3", - "quote", - "syn 2.0.39", + "anyhow", + "chrono", + "lazy_static", + "regex", +] + +[[package]] +name = "dav-server" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a9e373ca09a43ad20c0b7805fcb4b489713f049a3ee2750ed61efa72f9cde9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers 0.4.0", + "htmlescape", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "lazy_static", + "log", + "mime_guess", + "percent-encoding", + "pin-project", + "pin-utils", + "regex", + "time", + "tokio", + "url", + "uuid", + "warp", + "xml-rs", + "xmltree", ] [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -813,17 +1200,36 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_destructure2" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b697ac90ff296f0fc031ee5a61c7ac31fb9fff50e3fb32873b09223613fc0c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "derive_more" -version = "0.99.17" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case", "proc-macro2", "quote", - "rustc_version", - "syn 1.0.109", + "syn 2.0.79", + "unicode-xid", ] [[package]] @@ -832,10 +1238,10 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.20.3", + "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -857,6 +1263,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "digest" version = "0.10.7" @@ -864,6 +1276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -912,32 +1325,35 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] -name = "duct" -version = "0.13.6" +name = "dlv-list" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ae3fc31835f74c2a7ceda3aeede378b0ae2e74c8f1c36559fcc9ae2a4e7d3e" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" dependencies = [ - "libc", - "once_cell", - "os_pipe", - "shared_child", + "const-random", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "ed25519" @@ -951,23 +1367,24 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", "signature", + "subtle", "zeroize", ] [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" @@ -977,31 +1394,63 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "enum-map" -version = "2.7.1" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed40247825a1a0393b91b51d475ea1063a6cbbf0847592e7f13fb427aca6a716" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" dependencies = [ "enum-map-derive", ] [[package]] name = "enum-map-derive" -version = "0.15.0" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "enumset" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +dependencies = [ + "enumset_derive", + "serde", +] + +[[package]] +name = "enumset_derive" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7933cd46e720348d29ed1493f89df9792563f272f96d8f13d18afe03b32f8cb8" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" dependencies = [ + "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", +] + +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", ] [[package]] @@ -1012,65 +1461,98 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] -name = "eyre" -version = "0.6.8" +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ - "indenter", - "once_cell", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "fastrand" -version = "1.9.0" +name = "event-listener-strategy" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "instant", + "event-listener 5.3.1", + "pin-project-lite", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fiat-crypto" -version = "0.2.3" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f69037fe1b785e84986b4f2cbcf647381876a00671d25ceef715d7812dd7e1dd" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "libredox", + "windows-sys 0.59.0", ] +[[package]] +name = "flagset" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec" + [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", ] [[package]] @@ -1079,20 +1561,26 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] [[package]] name = "fs-err" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5fd9bcbe8b1087cbd395b51498c01bc997cef73e778a80b77a811af5e2d29f" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" dependencies = [ "autocfg", ] @@ -1103,56 +1591,130 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "fuse_mt" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e098b8dc4cd32e9ba31d9c8cdfef11271d8191233c64c2a671432ff19d354948" +dependencies = [ + "fuser", + "libc", + "log", + "threadpool", +] + +[[package]] +name = "fuser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21370f84640642c8ea36dfb2a6bfc4c55941f476fcf431f6fef25a5ddcf0169b" +dependencies = [ + "libc", + "log", + "memchr", + "page_size", + "pkg-config", + "smallvec", + "zerocopy 0.6.6", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1176,30 +1738,32 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix", + "windows-targets 0.52.6", ] [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -1209,30 +1773,62 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] -name = "h2" -version = "0.3.21" +name = "gloo-timers" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ - "bytes", - "fnv", + "futures-channel", "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.3", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if 1.0.0", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -1247,21 +1843,90 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core 0.2.0", + "http 0.2.12", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core 0.3.0", + "http 1.1.0", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.12", +] + +[[package]] +name = "headers-core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.1.0", +] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hex" @@ -1281,11 +1946,37 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "htmlescape" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" -version = "0.2.11" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1294,20 +1985,43 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "http", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1315,6 +2029,22 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "human-panic" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c5a08ed290eac04006e21e63d32e90086b6182c7cd0452d10f4264def1fec9a" +dependencies = [ + "anstream", + "anstyle", + "backtrace", + "os_info", + "serde", + "serde_derive", + "toml", + "uuid", +] + [[package]] name = "humantime" version = "2.1.0" @@ -1323,28 +2053,47 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -1352,18 +2101,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", - "rustls", + "http 0.2.12", + "hyper 0.14.30", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "rustls 0.23.14", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", + "webpki-roots 0.26.6", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2", "tokio", - "tokio-rustls", + "tower-service", + "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1390,9 +2177,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1400,17 +2187,16 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.20" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ + "crossbeam-deque", "globset", - "lazy_static", "log", "memchr", - "regex", + "regex-automata 0.4.8", "same-file", - "thread_local", "walkdir", "winapi-util", ] @@ -1434,42 +2220,73 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.15.0", "serde", ] [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.1.14", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "inout" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] +[[package]] +name = "insta" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "ron", + "serde", + "similar", +] + +[[package]] +name = "instability" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +dependencies = [ + "quote", + "syn 2.0.79", +] + [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if 1.0.0", ] @@ -1485,33 +2302,49 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] -name = "itertools" -version = "0.11.0" +name = "is-docker" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" dependencies = [ - "either", + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jemalloc-sys" @@ -1544,32 +2377,97 @@ dependencies = [ "jemallocator", ] +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "9.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +dependencies = [ + "base64 0.21.7", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy-regex" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d8e41c97e6bc7ecb552016274b99fbb5d035e8de288c582d9b933af6677bfda" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e1d8b05d672c53cb9c7b920bbba8783845ae4f0b076e02a3db1d02c81b4163" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.79", +] + [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] [[package]] name = "libc" -version = "0.2.150" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libm" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libmimalloc-sys" -version = "0.1.35" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3979b5c37ece694f1f5e51e7ecc871fdb0f517ed04ee45f88d15d6d553cb9664" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" dependencies = [ "cc", "libc", @@ -1577,26 +2475,32 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1604,61 +2508,52 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] [[package]] -name = "matchers" -version = "0.1.0" +name = "lru" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "regex-automata 0.1.10", + "hashbrown 0.15.0", ] [[package]] -name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.9.0" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "autocfg", + "regex-automata 0.1.10", ] [[package]] -name = "merge" -version = "0.1.0" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "merge_derive", - "num-traits", + "cfg-if 1.0.0", + "digest", ] [[package]] -name = "merge_derive" -version = "0.1.0" +name = "memchr" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "mimalloc" -version = "0.1.39" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa01922b5ea280a911e323e4d2fd24b7fe5cc4042e0d2cda3c40775cdc4bdc9c" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" dependencies = [ "libmimalloc-sys", ] @@ -1669,37 +2564,119 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" -version = "0.8.9" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", + "log", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener 5.3.1", + "futures-util", + "once_cell", + "parking_lot", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 0.2.12", + "httparse", + "log", + "memchr", + "mime", + "spin", + "version_check", ] [[package]] name = "nix" -version = "0.27.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "cfg-if 1.0.0", + "cfg_aliases", "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1710,13 +2687,78 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1725,15 +2767,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_threads" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] @@ -1746,24 +2788,165 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "opendal" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e44fc43be9ffe18dad3e3ef9d61c1ae01991ee6f1c8c026978c35777a711bf" +dependencies = [ + "anyhow", + "async-tls", + "async-trait", + "backon", + "base64 0.22.1", + "bb8", + "bytes", + "chrono", + "crc32c", + "flagset", + "futures", + "getrandom", + "governor", + "http 1.1.0", + "log", + "md-5", + "moka", + "once_cell", + "openssh", + "openssh-sftp-client", + "percent-encoding", + "quick-xml 0.36.2", + "reqsign", + "reqwest 0.12.8", + "serde", + "serde_json", + "sha2", + "suppaftp", + "tokio", + "uuid", +] + +[[package]] +name = "openssh" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf397b60b682d691bf2c6125b848304ef0df2023a657aa0fc006fd6769c3d8fa" +dependencies = [ + "libc", + "once_cell", + "shell-escape", + "tempfile", + "thiserror", + "tokio", +] + +[[package]] +name = "openssh-sftp-client" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb57886c859b298b785e20c9cbcd6681fe9106aa4fd19c0e7e8ecd801948e1e" +dependencies = [ + "bytes", + "derive_destructure2", + "futures-core", + "once_cell", + "openssh", + "openssh-sftp-client-lowlevel", + "openssh-sftp-error", + "pin-project", + "scopeguard", + "tokio", + "tokio-io-utility", + "tokio-util", + "tracing", +] + +[[package]] +name = "openssh-sftp-client-lowlevel" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12a5728cca10461b3842f715fb3d8acd7ef11e2635a0aff0eb5eceab2e1f1e4a" +dependencies = [ + "awaitable", + "bytes", + "concurrent_arena", + "derive_destructure2", + "openssh-sftp-error", + "openssh-sftp-protocol", + "pin-project", + "tokio", + "tokio-io-utility", +] + +[[package]] +name = "openssh-sftp-error" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ee6d9ea97e1fd08435222dd1eab26aa6a86674f0ff1a9583b48c98d1ef4801" +dependencies = [ + "awaitable-error", + "openssh", + "openssh-sftp-protocol-error", + "ssh_format_error", + "thiserror", + "tokio", +] + +[[package]] +name = "openssh-sftp-protocol" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf38532d784978966f95d241226223823f351d5bb2a4bebcf6b20b9cb1e393e0" +dependencies = [ + "bitflags 2.6.0", + "num-derive", + "num-traits", + "openssh-sftp-protocol-error", + "serde", + "ssh_format", + "vec-strings", +] + +[[package]] +name = "openssh-sftp-protocol-error" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "0719269eb3f037866ae07ec89cb44ed2c1d63b72b2390cef8e1aa3016a956ff8" +dependencies = [ + "serde", + "thiserror", + "vec-strings", +] [[package]] name = "openssl-probe" @@ -1778,13 +2961,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "os_pipe" -version = "1.1.4" +name = "ordered-multimap" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" dependencies = [ - "libc", - "windows-sys 0.48.0", + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "os_info" +version = "3.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", ] [[package]] @@ -1799,6 +2993,16 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "page_size" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b7663cbd190cfd818d08efa8497f6cd383076688c49a391ef7c0d03cd12b561" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "pariter" version = "0.5.1" @@ -1810,11 +3014,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1822,17 +3032,23 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "path-dedot" version = "3.1.1" @@ -1842,6 +3058,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "pbkdf2" version = "0.12.2" @@ -1852,17 +3074,56 @@ dependencies = [ "hmac", ] +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1870,6 +3131,43 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "aes", + "cbc", + "der", + "pbkdf2", + "scrypt", + "sha2", + "spki", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -1877,107 +3175,275 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", + "pkcs5", + "rand_core", "spki", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy 0.7.35", +] + +[[package]] +name = "predicates" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +dependencies = [ + "anstyle", + "difflib", + "float-cmp", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" + +[[package]] +name = "predicates-tree" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] [[package]] -name = "platforms" -version = "3.2.0" +name = "quanta" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] [[package]] -name = "poly1305" -version = "0.8.0" +name = "quick-xml" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", + "memchr", ] [[package]] -name = "portable-atomic" -version = "1.5.1" +name = "quick-xml" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "86e446ed58cef1bbfe847bc2fda0e2e4ea9f0e57b90c507d4781292590d72a4e" +dependencies = [ + "memchr", + "serde", +] [[package]] -name = "powerfmt" -version = "0.2.0" +name = "quick-xml" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", + "serde", +] [[package]] -name = "ppv-lite86" -version = "0.2.17" +name = "quick_cache" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "7d7c94f8935a9df96bb6380e8592c70edf497a643f94bd23b2f76b399385dbf4" +dependencies = [ + "ahash", + "equivalent", + "hashbrown 0.14.5", + "parking_lot", +] [[package]] -name = "pretty_assertions" -version = "1.4.0" +name = "quickcheck" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" dependencies = [ - "diff", - "yansi", + "env_logger", + "log", + "rand", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "quickcheck_macros" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "b22a693222d716a9587786f37ac3f6b4faedb5b80c23914e7303ff5a1d8016e9" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "quinn" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.14", + "socket2", + "thiserror", + "tokio", + "tracing", ] [[package]] -name = "proc-macro2" -version = "1.0.69" +name = "quinn-proto" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ - "unicode-ident", + "bytes", + "rand", + "ring", + "rustc-hash", + "rustls 0.23.14", + "slab", + "thiserror", + "tinyvec", + "tracing", ] [[package]] -name = "quick-xml" -version = "0.23.1" +name = "quinn-udp" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" dependencies = [ - "memchr", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2012,11 +3478,41 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ratatui" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +dependencies = [ + "bitflags 2.6.0", + "cassowary", + "compact_str", + "crossterm 0.28.1", + "indoc", + "instability", + "itertools", + "lru", + "paste", + "strum", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.2.0", +] + +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -2024,9 +3520,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -2034,27 +3530,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -2063,14 +3550,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -2084,13 +3571,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.5", ] [[package]] @@ -2101,26 +3588,63 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "reqsign" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03dd4ba7c3901dd43e6b8c7446a760d45bc1ea4301002e1a6fa48f97c3a796fa" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.22.1", + "chrono", + "form_urlencoded", + "getrandom", + "hex", + "hmac", + "home", + "http 1.1.0", + "jsonwebtoken", + "log", + "once_cell", + "percent-encoding", + "quick-xml 0.35.0", + "rand", + "reqwest 0.12.8", + "rsa", + "rust-ini", + "serde", + "serde_json", + "sha1", + "sha2", +] [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", "ipnet", "js-sys", "log", @@ -2128,15 +3652,59 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pemfile", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper 0.1.2", "system-configuration", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls 0.27.3", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.14", + "rustls-native-certs", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tokio-rustls 0.26.0", "tokio-util", "tower-service", "url", @@ -2144,18 +3712,18 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", - "winreg", + "webpki-roots 0.26.6", + "windows-registry", ] [[package]] name = "rhai" -version = "1.16.3" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3625f343d89990133d013e39c46e350915178cf94f1bec9f49b0cbef98a3e3c" +checksum = "61797318be89b1a268a018a92a7657096d83f3ecb31418b9e9c16dcbb043b702" dependencies = [ "ahash", - "bitflags 2.4.1", + "bitflags 2.6.0", "instant", "num-traits", "once_cell", @@ -2163,97 +3731,244 @@ dependencies = [ "serde", "smallvec", "smartstring", + "thin-vec", ] [[package]] name = "rhai_codegen" -version = "1.6.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853977598f084a492323fe2f7896b4100a86284ee8473612de60021ea341310f" +checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "ring" -version = "0.17.5" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if 1.0.0", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ron" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" +dependencies = [ + "base64 0.13.1", + "bitflags 1.3.2", + "serde", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if 1.0.0", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.79", + "unicode-ident", +] + +[[package]] +name = "runtime-format" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09958d5b38bca768ede7928c767c89a08ba568144a7b61992aecae79b03c8c94" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "rust-ini" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +dependencies = [ + "cfg-if 1.0.0", + "ordered-multimap", + "trim-in-place", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustic-rs" -version = "0.6.1" +version = "0.9.4" dependencies = [ "abscissa_core", "aho-corasick", "anyhow", + "assert_cmd", "bytesize", + "cached", "chrono", "clap", "clap_complete", "comfy-table", + "conflate", + "convert_case", + "crossterm 0.28.1", + "dateparser", + "dav-server", + "derive_more", "dialoguer", "dircmp", "directories", + "displaydoc", + "fuse_mt", "gethostname", + "globset", + "human-panic", "humantime", "indicatif", - "itertools 0.12.0", + "insta", + "itertools", "jemallocator-global", "libc", "log", - "merge", "mimalloc", - "once_cell", + "open", + "predicates", "pretty_assertions", + "quickcheck", + "quickcheck_macros", + "ratatui", "rhai", + "rstest", + "rustic_backend", "rustic_core", "rustic_testing", + "scopeguard", "self_update", "semver", "serde", - "serde_json", - "serde_with", - "simplelog", - "tempfile", + "serde_json", + "serde_with", + "simplelog", + "tar", + "tempfile", + "thiserror", + "tokio", + "toml", + "tui-textarea", + "warp", +] + +[[package]] +name = "rustic_backend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505fe0c120bb2ad90aa24192790c97a0a1fbed82b8d7c873e4fde589f5758478" +dependencies = [ + "aho-corasick", + "anyhow", + "backoff", + "bytes", + "bytesize", + "clap", + "conflate", + "derive_setters", + "displaydoc", + "hex", + "humantime", + "itertools", + "log", + "opendal", + "rand", + "rayon", + "reqwest 0.12.8", + "rustic_core", + "semver", + "serde", + "strum", + "strum_macros", "thiserror", - "toml 0.8.8", + "tokio", + "typed-path", + "url", + "walkdir", ] [[package]] name = "rustic_core" -version = "0.1.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5932066f9e144fc15043c4e0b9a82bfa16c83910243318bdafbb38496c1518a" +checksum = "dbc1d8eff26bc13c3b0adffc0506b087771fcb54af25ace3ac6d5914aca84d5d" dependencies = [ "aes256ctr_poly1305aes", - "aho-corasick", - "backoff", + "anyhow", "binrw", "bytes", "bytesize", @@ -2261,31 +3976,34 @@ dependencies = [ "cachedir", "chrono", "clap", + "conflate", "crossbeam-channel", + "dav-server", "derivative", "derive_more", "derive_setters", - "directories", "dirs", "displaydoc", "dunce", "enum-map", "enum-map-derive", + "enumset", "filetime", + "futures", "gethostname", "hex", "humantime", "ignore", "integer-sqrt", - "itertools 0.11.0", + "itertools", "log", - "merge", "nix", "pariter", "path-dedot", + "quick_cache", "rand", "rayon", - "reqwest", + "runtime-format", "scrypt", "serde", "serde-aux", @@ -2294,8 +4012,8 @@ dependencies = [ "serde_with", "sha2", "shell-words", + "strum", "thiserror", - "url", "walkdir", "xattr", "zstd", @@ -2303,46 +4021,66 @@ dependencies = [ [[package]] name = "rustic_testing" -version = "0.1.0" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e117dc6316011e224f871f4d3a1ee4915e4be17a63b74dde0da3249531e2dd" dependencies = [ "aho-corasick", - "once_cell", + "anyhow", + "bytes", + "enum-map", + "rustic_core", "tempfile", ] [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.2.0", + "rustls-pki-types", "schannel", "security-framework", ] @@ -2353,9 +4091,24 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", ] +[[package]] +name = "rustls-pki-types" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -2366,17 +4119,28 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "salsa20" @@ -2398,13 +4162,19 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -2434,9 +4204,9 @@ dependencies = [ [[package]] name = "secrecy" -version = "0.8.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" dependencies = [ "serde", "zeroize", @@ -2444,11 +4214,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -2457,9 +4227,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -2467,13 +4237,13 @@ dependencies = [ [[package]] name = "self-replace" -version = "1.3.7" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525db198616b2bcd0f245daf7bfd8130222f7ee6af9ff9984c19a61bf1160c55" +checksum = "03ec815b5eab420ab893f63393878d89c90fdd94c0bcc44c07abb8ad95552fb7" dependencies = [ - "fastrand 1.9.0", + "fastrand", "tempfile", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2484,12 +4254,12 @@ checksum = "1a34ad8e4a86884ab42e9b8690e9343abdcfe5fa38a0318cfe1565ba9ad437b4" dependencies = [ "either", "flate2", - "hyper", + "hyper 0.14.30", "indicatif", "log", - "quick-xml", + "quick-xml 0.23.1", "regex", - "reqwest", + "reqwest 0.11.27", "self-replace", "semver", "serde_json", @@ -2501,27 +4271,27 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.192" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde-aux" -version = "4.2.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3dfe1b7eb6f9dcf011bd6fad169cdeaae75eda0d61b1a99a3f015b41b0cae39" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" dependencies = [ "chrono", "serde", @@ -2530,31 +4300,32 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -2573,16 +4344,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.6.0", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -2590,14 +4362,25 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ - "darling 0.20.3", + "darling", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", ] [[package]] @@ -2614,9 +4397,9 @@ dependencies = [ [[package]] name = "sha2-asm" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27ba7066011e3fb30d808b51affff34f0a66d3a03a58edd787c6e420e40e44e" +checksum = "b845214d6175804686b2bd482bcffe96651bb2d1200742b712003504a2dac1ab" dependencies = [ "cc", ] @@ -2631,14 +4414,10 @@ dependencies = [ ] [[package]] -name = "shared_child" -version = "1.0.0" +name = "shell-escape" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" -dependencies = [ - "libc", - "winapi", -] +checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] name = "shell-words" @@ -2646,20 +4425,75 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "signature" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", + "rand_core", +] + +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", ] [[package]] name = "simplelog" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369" +checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" dependencies = [ "log", "termcolor", @@ -2677,9 +4511,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" dependencies = [ "serde", ] @@ -2698,22 +4532,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2722,16 +4546,51 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", ] +[[package]] +name = "ssh_format" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ab31081d1c9097c327ec23550858cb5ffb4af6b866c1ef4d728455f01f3304" +dependencies = [ + "bytes", + "serde", + "ssh_format_error", +] + +[[package]] +name = "ssh_format_error" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be3c6519de7ca611f71ef7e8a56eb57aa1c818fecb5242d0a0f39c83776c210c" +dependencies = [ + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2740,34 +4599,55 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "suppaftp" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "3d5c3d37ce3092d7148494a30a0f5036f8722792a626b25662a87434d3683c33" +dependencies = [ + "async-std", + "async-tls", + "async-trait", + "chrono", + "futures-lite", + "lazy-regex", + "log", + "pin-project", + "rustls 0.21.12", + "thiserror", +] [[package]] name = "syn" @@ -2782,15 +4662,30 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -2824,11 +4719,17 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tar" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" dependencies = [ "filetime", "libc", @@ -2837,75 +4738,100 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if 1.0.0", - "fastrand 2.0.1", - "redox_syscall 0.4.1", + "fastrand", + "once_cell", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "thin-vec" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" +dependencies = [ + "serde", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if 1.0.0", "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", "powerfmt", "serde", @@ -2921,10 +4847,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -2939,9 +4866,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -2953,59 +4880,95 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "tokio" -version = "1.34.0" +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-io-utility" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d672654d175710e52c7c41f6aec77c62b3c0954e2a7ebce9049d1e94ed7c263" +dependencies = [ + "bytes", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2 0.5.5", - "windows-sys 0.48.0", + "rustls 0.23.14", + "rustls-pki-types", + "tokio", ] [[package]] -name = "tokio-rustls" -version = "0.24.1" +name = "tokio-tungstenite" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ - "rustls", + "futures-util", + "log", "tokio", + "tungstenite", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", ] [[package]] name = "toml" -version = "0.8.8" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -3015,20 +4978,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -3037,9 +5000,9 @@ dependencies = [ [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -3047,6 +5010,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3060,7 +5024,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] @@ -3073,17 +5037,6 @@ dependencies = [ "valuable", ] -[[package]] -name = "tracing-log" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -3110,14 +5063,67 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log 0.2.0", + "tracing-log", +] + +[[package]] +name = "trim-in-place" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +dependencies = [ + "arc-swap", + "serde", + "stable_deref_trait", ] [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tui-textarea" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5318dd619ed73c52a9417ad19046724effc1287fb75cdcc4eca1d6ac1acbae" +dependencies = [ + "crossterm 0.28.1", + "ratatui", + "unicode-width 0.2.0", +] + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typed-path" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "82205ffd44a9697e34fc145491aa47310f9871540bb7909eaa9365e0a9a46607" [[package]] name = "typenum" @@ -3125,38 +5131,70 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools", + "unicode-segmentation", + "unicode-width 0.1.14", +] + [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -3176,9 +5214,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -3191,11 +5229,27 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", + "serde", +] [[package]] name = "valuable" @@ -3203,11 +5257,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "vec-strings" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8509489e2a7ee219522238ad45fd370bec6808811ac15ac6b07453804e77659" +dependencies = [ + "serde", + "thin-vec", +] + [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" @@ -3220,9 +5290,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3237,6 +5307,35 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers 0.3.9", + "http 0.2.12", + "hyper 0.14.30", + "log", + "mime", + "mime_guess", + "multer", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tungstenite", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3245,34 +5344,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887" dependencies = [ "cfg-if 1.0.0", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "65471f79c1022ffa5291d33520cbbb53b7687b01c2f8e83b57d102eed7ed479d" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3282,9 +5382,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3292,28 +5392,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9" [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ "futures-util", "js-sys", @@ -3324,19 +5424,57 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44188d185b5bdcae1052d08bcbcf9091a5524038d4572cc4f4f2bb9d5554ddd9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "winapi" @@ -3356,11 +5494,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -3371,20 +5509,41 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-targets 0.42.2", + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -3397,18 +5556,21 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.6", ] [[package]] @@ -3427,10 +5589,20 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] [[package]] name = "windows_aarch64_gnullvm" @@ -3439,10 +5611,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3451,10 +5623,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3463,10 +5635,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3475,10 +5653,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3487,10 +5665,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3499,10 +5677,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3510,11 +5688,17 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" -version = "0.5.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -3531,91 +5715,118 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", + "linux-raw-sys", + "rustix", ] [[package]] -name = "xtask" -version = "0.1.0" +name = "xml-rs" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" dependencies = [ - "anyhow", - "clap", - "dialoguer", - "duct", - "fs_extra", - "glob", + "xml-rs", ] [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "zerocopy" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.6", +] [[package]] name = "zerocopy" -version = "0.7.31" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" dependencies = [ - "zerocopy-derive", + "proc-macro2", + "quote", + "syn 2.0.79", ] [[package]] name = "zerocopy-derive" -version = "0.7.31" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.79", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zipsign-api" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ba5aa1827d6b1a35a29b3413ec69ce5f796e4d897e3e5b38f461bef41d225ea" +checksum = "6413a546ada9dbcd0b9a3e0b0880581279e35047bce9797e523b3408e1df607c" dependencies = [ - "base64", + "base64 0.22.1", "ed25519-dalek", "thiserror", ] [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 9e5779f4a..c25a13884 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,40 +1,35 @@ -[workspace.package] -version = "0.6.1" -edition = "2021" -license = "Apache-2.0 OR MIT" -repository = "https://github.com/rustic-rs/rustic" -homepage = "https://rustic.cli.rs/" -keywords = ["backup", "restic", "deduplication", "encryption", "cli"] -categories = ["command-line-utilities"] -description = """ -rustic - fast, encrypted, deduplicated backups powered by Rust -""" - [package] name = "rustic-rs" -version = { workspace = true } -authors = ["Alexander Weiss"] -categories = { workspace = true } +version = "0.9.4" +authors = ["the rustic-rs team"] +categories = ["command-line-utilities"] documentation = "https://docs.rs/rustic-rs" -edition = { workspace = true } -homepage = { workspace = true } +edition = "2021" +homepage = "https://rustic.cli.rs/" include = ["src/**/*", "LICENSE-*", "README.md", "config/**/*"] -keywords = { workspace = true } -license = { workspace = true } +keywords = ["backup", "restic", "deduplication", "encryption", "cli"] +license = "Apache-2.0 OR MIT" readme = "README.md" -repository = { workspace = true } +repository = "https://github.com/rustic-rs/rustic" resolver = "2" -rust-version = "1.70.0" -description = { workspace = true } - -[workspace] -members = ["crates/rustic_testing", "xtask"] +rust-version = "1.80.0" +description = """ +rustic - fast, encrypted, deduplicated backups powered by Rust +""" [features] -default = ["self-update"] +default = ["tui", "webdav"] +release = ["default", "self-update"] + +# Allocators mimalloc = ["dep:mimalloc"] jemallocator = ["dep:jemallocator-global"] + +# Commands self-update = ["dep:self_update", "dep:semver"] +tui = ["dep:ratatui", "dep:crossterm", "dep:tui-textarea"] +webdav = ["dep:dav-server", "dep:warp", "dep:tokio", "rustic_core/webdav"] +mount = ["dep:fuse_mt"] [[bin]] name = "rustic" @@ -51,109 +46,91 @@ all-features = true rustdoc-args = ["--document-private-items", "--generate-link-to-definition"] [dependencies] -abscissa_core = { workspace = true } -rustic_core = { workspace = true } - -# errors -anyhow = { workspace = true } -thiserror = { workspace = true } +abscissa_core = { version = "0.8.1", default-features = false, features = ["application"] } +rustic_backend = { version = "0.4.2", features = ["cli"] } +rustic_core = { version = "0.5.5", features = ["cli"] } -# logging -log = { workspace = true } - -# serialization -serde = { workspace = true } -serde_json = { workspace = true } -serde_with = { workspace = true } - -# other dependencies -chrono = { workspace = true } -self_update = { workspace = true, optional = true } -semver = { workspace = true, optional = true } - -# commands -clap = { workspace = true } -clap_complete = { workspace = true } -merge = { workspace = true } - -bytesize = { workspace = true } -comfy-table = { workspace = true } -dialoguer = { workspace = true } -directories = { workspace = true } -gethostname = { workspace = true } -humantime = { workspace = true } -indicatif = { workspace = true } -itertools = { workspace = true } +# allocators jemallocator-global = { version = "0.3.2", optional = true } -mimalloc = { version = "0.1.39", default_features = false, optional = true } -rhai = { workspace = true } -simplelog = { workspace = true } +mimalloc = { version = "0.1.43", default-features = false, optional = true } -[dev-dependencies] -abscissa_core = { workspace = true, features = ["testing"] } -aho-corasick = { workspace = true } -dircmp = { workspace = true } -once_cell = { workspace = true } -pretty_assertions = { workspace = true } -rustic_testing = { path = "crates/rustic_testing" } -tempfile = { workspace = true } -toml = { workspace = true } +# webdav +dav-server = { version = "0.7.0", default-features = false, features = ["warp-compat"], optional = true } +tokio = { version = "1", optional = true } +warp = { version = "0.3.7", optional = true } -[target.'cfg(not(windows))'.dependencies] -libc = "0.2.150" -[workspace.dependencies] -rustic_core = { version = "0.1.2", features = ["cli"] } -abscissa_core = { version = "0.7.0", default-features = false, features = ["application"] } +# tui +crossterm = { version = "0.28", optional = true } +ratatui = { version = "0.29.0", optional = true } +tui-textarea = { version = "0.7.0", optional = true } # logging log = "0.4" # errors -displaydoc = "0.2.4" -thiserror = "1" anyhow = "1" +displaydoc = "0.2.5" +thiserror = "1" # serialization serde = { version = "1", features = ["serde_derive"] } -serde_with = { version = "3.4", features = ["base64"] } serde_json = "1" +serde_with = { version = "3", features = ["base64"] } # other dependencies -aho-corasick = "1.1.2" +aho-corasick = "1" chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] } -rhai = { version = "1.16", features = ["sync", "serde", "no_optimize", "no_module", "no_custom_syntax", "only_i64"] } -semver = "1" +comfy-table = "7" +rhai = { version = "1", features = ["sync", "serde", "no_optimize", "no_module", "no_custom_syntax", "only_i64"] } +scopeguard = "1" +semver = { version = "1", optional = true } simplelog = "0.12" -comfy-table = "7.1.0" # commands -merge = "0.1" -directories = "5" -dialoguer = "0.11.0" -indicatif = "0.17" -gethostname = "0.4" bytesize = "1" -itertools = "0.12" -humantime = "2" -clap_complete = "4" +cached = "0.53.1" clap = { version = "4", features = ["derive", "env", "wrap_help"] } -once_cell = "1.18" -self_update = { version = "0.39", default-features = false, features = ["rustls", "archive-tar", "compression-flate2"] } +clap_complete = "4" +conflate = "0.2" +convert_case = "0.6.0" +dateparser = "0.2.1" +derive_more = { version = "1", features = ["debug"] } +dialoguer = "0.11.0" +directories = "5" +fuse_mt = { version = "0.6", optional = true } +gethostname = "0.5" +globset = "0.4.15" +human-panic = "2" +humantime = "2" +indicatif = "0.17" +itertools = "0.13" +open = "5.3.0" +self_update = { version = "0.39.0", default-features = false, optional = true, features = ["rustls", "archive-tar", "compression-flate2"] } # FIXME: Downgraded to 0.39.0 due to https://github.com/jaemk/self_update/issues/136 +tar = "0.4.42" +toml = "0.8" -# dev dependencies -rstest = "0.18" +[dev-dependencies] +abscissa_core = { version = "0.8.1", default-features = false, features = ["testing"] } +assert_cmd = "2.0.16" +dircmp = "0.2" +insta = { version = "1.40.0", features = ["ron"] } +predicates = "3.1.2" +pretty_assertions = "1.4" quickcheck = "1" quickcheck_macros = "1" -tempfile = "3.8" -pretty_assertions = "1.4" +rstest = "0.23" +rustic_testing = "0.2.3" +tempfile = "3.13" toml = "0.8" -dircmp = "0.2" + +[target.'cfg(not(windows))'.dependencies] +libc = "0.2.159" # cargo-binstall support # https://github.com/cargo-bins/cargo-binstall/blob/HEAD/SUPPORT.md [package.metadata.binstall] -pkg-url = "{ repo }/releases/download/v{ version }/{ repo }-v{ version }-{ target }{ archive-suffix }" -bin-dir = "{ bin }-{ target }/{ bin }{ binary-ext }" +pkg-url = "{ repo }/releases/download/v{ version }/{ bin }-v{ version }-{ target }{ archive-suffix }" +bin-dir = "{ bin }{ binary-ext }" pkg-fmt = "tgz" [package.metadata.binstall.signing] diff --git a/Dockerfile b/Dockerfile index b569e0801..85eaa4a84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,18 @@ -# Improve build speed with cached deps -ARG RUST_VERSION=1.70.0 -FROM lukemathwalker/cargo-chef:latest-rust-${RUST_VERSION} AS chef -WORKDIR /app +FROM alpine AS builder +ARG RUSTIC_VERSION +ARG TARGETARCH +RUN if [ "$TARGETARCH" = "amd64" ]; then \ + ASSET="rustic-${RUSTIC_VERSION}-x86_64-unknown-linux-musl.tar.gz";\ + elif [ "$TARGETARCH" = "arm64" ]; then \ + ASSET="rustic-${RUSTIC_VERSION}-aarch64-unknown-linux-musl.tar.gz"; \ + fi; \ + wget https://github.com/rustic-rs/rustic/releases/download/${RUSTIC_VERSION}/${ASSET} && \ + tar -xzf ${ASSET} && \ + mkdir /etc_files && \ + touch /etc_files/passwd && \ + touch /etc_files/group -FROM chef AS planner -COPY . . -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef AS builder -COPY --from=planner /app/recipe.json recipe.json -# Build dependencies - this is the caching Docker layer! -RUN cargo chef cook --release --recipe-path recipe.json -# Build application -COPY . . -RUN cargo build --release - -# why we dont use alpine for base image - https://andygrove.io/2020/05/why-musl-extremely-slow/ -FROM debian:bookworm-slim as runtime - -COPY --from=builder /app/target/release/rustic /usr/local/bin - -ENTRYPOINT ["/usr/local/bin/rustic"] \ No newline at end of file +FROM scratch +COPY --from=builder /rustic / +COPY --from=builder /etc_files/ /etc/ +ENTRYPOINT ["/rustic"] diff --git a/ECOSYSTEM.md b/ECOSYSTEM.md new file mode 100644 index 000000000..dcffd3271 --- /dev/null +++ b/ECOSYSTEM.md @@ -0,0 +1,66 @@ +# Ecosystem + +## Crates + +### rustic_backend - [Link](https://crates.io/crates/rustic_backend) + +A library for supporting various backends in `rustic` and `rustic_core`. + +### rustic_core - [Link](https://crates.io/crates/rustic_core) + +Core functionality for the `rustic` ecosystem. Can be found +[here](https://github.com/rustic-rs/rustic_core). + +### rustic_scheduler - [Link](https://crates.io/crates/rustic_scheduler) + +Scheduling functionality for the `rustic` ecosystem. + +### rustic_server - [Link](https://crates.io/crates/rustic_server) + +A possible server implementation for `rustic` to support multiple clients when +backing up. + +### rustic_testing (not published) - [Link](https://github.com/rustic-rs/rustic_core/tree/main/crates/testing) + +Testing functionality for the `rustic` ecosystem. + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index a8a3baa98..9dc5d7978 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ +

## About @@ -35,8 +36,8 @@ The `rustic` project is split into multiple crates: - [rustic](https://crates.io/crates/rustic-rs) - the main binary - [rustic-core](https://crates.io/crates/rustic_core) - the core library - - +- [rustic-backend](https://crates.io/crates/rustic_backend) - the library for + supporting various backends ## Features @@ -97,6 +98,12 @@ Or you can check out the Nightly binaries are available [here](https://rustic.cli.rs/docs/nightly_builds.html). +### Docker + +```bash +docker pull ghcr.io/rustic-rs/rustic +``` + ### From source **Beware**: This installs the latest development version, which might be @@ -109,7 +116,7 @@ cargo install --git https://github.com/rustic-rs/rustic.git rustic-rs ### crates.io ```bash -cargo install rustic-rs +cargo install --locked rustic-rs ``` ## Differences to `restic`? @@ -136,7 +143,7 @@ Please make sure, that you read the ## Minimum Rust version policy -This crate's minimum supported `rustc` version is `1.70.0`. +This crate's minimum supported `rustc` version is `1.80.0`. The current policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if `crate 1.0` requires diff --git a/build-dependencies.just b/build-dependencies.just new file mode 100644 index 000000000..3c5c0a214 --- /dev/null +++ b/build-dependencies.just @@ -0,0 +1,40 @@ +### DEFAULT ### + +# Install dependencies for the default feature on x86_64-unknown-linux-musl +install-default-x86_64-unknown-linux-musl: + sudo apt-get update + sudo apt-get install -y musl-tools + +# Install dependencies for the default feature on aarch64-unknown-linux-musl +install-default-aarch64-unknown-linux-musl: + sudo apt-get update + sudo apt-get install -y musl-tools + +### MOUNT ### + +# Install dependencies for the mount feature on x86_64-unknown-linux-gnu +install-mount-x86_64-unknown-linux-gnu: + sudo apt-get update + sudo apt-get install -y fuse3 libfuse3-dev pkg-config + +# Install dependencies for the mount feature on aarch64-unknown-linux-gnu +install-mount-aarch64-unknown-linux-gnu: + sudo apt-get update + sudo apt-get install -y fuse3 libfuse3-dev pkg-config + +# Install dependencies for the mount feature on i686-unknown-linux-gnu +install-mount-i686-unknown-linux-gnu: + sudo apt-get update + sudo apt-get install -y fuse3 libfuse3-dev pkg-config + +# Install dependencies for the mount feature on x86_64-apple-darwin +install-mount-x86_64-apple-darwin: + brew install macfuse + +# Install dependencies for the mount feature on aarch64-apple-darwin +install-mount-aarch64-apple-darwin: + brew install macfuse + +# Install dependencies for the mount feature on x86_64-pc-windows-msvc +install-mount-x86_64-pc-windows-msvc: + winget install winfsp diff --git a/config/README.md b/config/README.md index 7790f4c1f..08920c6b8 100644 --- a/config/README.md +++ b/config/README.md @@ -2,37 +2,57 @@

-# Rustic Configuration Specification +# rustic Configuration Specification -`rustic` is a backup tool that allows users to define their backup options using -a TOML configuration file. The configuration file consists of various sections +`rustic` is a backup tool that allows users to define their backup options in +profiles using TOML files. A configuration profile consists of various sections and attributes that control the behavior of `rustic` for different commands and sources. This specification covers all the available sections and attributes in the -`rustic` configuration file and includes their corresponding environment +`rustic` configuration profile file and includes their corresponding environment variable names. Users can customize their backup behavior by modifying these attributes according to their needs. +## Table of Contents + +- [Merge Precedence](#merge-precedence) +- [Profiles](#profiles) +- [Sections and Attributes](#sections-and-attributes) + - [Global Options `[global]`](#global-options-global) + - [Global Hooks `[global.hooks]`](#global-hooks-globalhooks) + - [Global Options - env variables `[global.env]`](#global-options---env-variables-globalenv) + - [Repository Options `[repository]`](#repository-options-repository) + - [Repository Options (Additional) `[repository.options]`](#repository-options-additional-repositoryoptions) + - [Repository Options for cold repo (Additional) `[repository.options-cold]`](#repository-options-for-cold-repo-additional-repositoryoptions-cold) + - [Repository Options for hot repo (Additional) `[repository.options-hot]`](#repository-options-for-hot-repo-additional-repositoryoptions-hot) + - [Repository Hooks `[repository.hooks]`](#repository-hooks-repositoryhooks) + - [Snapshot-Filter Options `[snapshot-filter]`](#snapshot-filter-options-snapshot-filter) + - [Backup Options `[backup]`](#backup-options-backup) + - [Backup Hooks `[backup.hooks]`](#backup-hooks-backuphooks) + - [Backup Snapshots `[[backup.snapshots]]`](#backup-snapshots-backupsnapshots) + - [Forget Options `[forget]`](#forget-options-forget) + - [Copy Targets `[copy]`](#copy-targets-copy) + - [WebDAV Options `[webdav]`](#webdav-options-webdav) + ## Merge Precedence The merge precedence for values is: - Commandline Arguments >> Environment Variables >> Configuration File + Commandline Arguments >> Environment Variables >> Configuration Profile -Values parsed from the `configuration file` can be overwritten by +Values parsed from the `configuration profile` can be overwritten by `environment variables`, which can be overwritten by `commandline arguments` options. Therefore `commandline arguments` have the highest precedence. **NOTE**: There are the following restrictions: +- Not all options are available as environment variables or commandline + arguments. There are also commandline options which cannot be set in the + profile TOML files. - You can overwrite values, but for most values, you cannot "unset" them on a higher priority level. -- For some integer values, you cannot even overwrite with the value `0`, e.g. - `keep-weekly = 5` in the `[forget]` section of the config file cannot be - overwritten by `--keep-weekly 0`. - ## Profiles Configuration files can be placed in the user's local config directory, e.g. @@ -41,136 +61,234 @@ use different config files, e.g. `myconfig.toml` and use the `-P` option to specify the profile name, e.g. `rustic -P myconfig`. Examples for different configuration files can be found here in the [/config/](/config) directory. +## Services + +We have collected some examples how to configure `rustic` for various services +in the [services/](/config/services/) subdirectory. Please note that these +examples are not complete and may not work out of the box. They are intended to +give you a starting point for your own configuration. + +If you want to contribute your own configuration, please +[open a pull request](https://rustic.cli.rs/dev-docs/contributing-to-rustic.html#submitting-pull-requests). + ## Sections and Attributes -### Global Options +### Global Options `[global]` + +| Attribute | Description | Default Value | Example Value | Environment Variable | CLI Option | +| ----------------- | --------------------------------------------------------------------------------- | ------------- | ----------------- | ------------------------ | ------------------- | +| check-index | If true, check the index and read pack headers if index information is missing. | false | | RUSTIC_CHECK_INDEX | --check-index | +| dry-run | If true, performs a dry run without making any changes. | false | | RUSTIC_DRY_RUN | --dry-run, -n | +| log-level | Logging level. Possible values: "off", "error", "warn", "info", "debug", "trace". | "info" | | RUSTIC_LOG_LEVEL | --log-level | +| log-file | Path to the log file. | No log file | "/log/rustic.log" | RUSTIC_LOG_FILE | --log-file | +| no-progress | If true, disables progress indicators. | false | | RUSTIC_NO_PROGRESS | --no-progress | +| progress-interval | The interval at which progress indicators are shown. | "100ms" | "1m" | RUSTIC_PROGRESS_INTERVAL | --progress-interval | +| use-profiles | Array of profiles to use. Allows to recursively use other profiles. | Empty array | ["2nd", "3rd"] | RUSTIC_USE_PROFILE | --use-profile, -P | + +### Global Hooks `[global.hooks]` + +These external commands are run before and after each commands, respectively. + +**Note**: There are also repository hooks, which should be used for commands +needed to set up the repository (like mounting the repo dir), see below. -| Attribute | Description | Default Value | Example Value | Environment Variable | -| ----------------- | --------------------------------------------------------------------------------- | ------------- | ----------------- | ------------------------ | -| dry-run | If true, performs a dry run without making any changes. | false | | RUSTIC_DRY_RUN | -| log-level | Logging level. Possible values: "off", "error", "warn", "info", "debug", "trace". | "info" | | RUSTIC_LOG_LEVEL | -| log-file | Path to the log file. | No log file | "/log/rustic.log" | RUSTIC_LOG_FILE | -| no-progress | If true, disables progress indicators. | false | | RUSTIC_NO_PROGRESS | -| progress-interval | The interval at which progress indicators are shown. | "100ms" | "1m" | RUSTIC_PROGRESS_INTERVAL | -| use-profile | An array of profiles to use. | Empty array | | RUSTIC_USE_PROFILE | +| Attribute | Description | Default Value | Example Value | Environment Variable | +| ----------- | ------------------------------------------------- | ------------- | ------------- | -------------------- | +| run-before | Run the given commands before execution | not set | ["echo test"] | | +| run-after | Run the given commands after successful execution | not set | ["echo test"] | | +| run-failed | Run the given commands after failed execution | not set | ["echo test"] | | +| run-finally | Run the given commands after every execution | not set | ["echo test"] | | -### Global Options - env variables +### Global Options - env variables `[global.env]` All given environment variables are set before processing. This is handy to configure e.g. the `rclone`-backend or some commands which will be called by rustic. **Important**: Please do not forget to include environment variables set in the -config file as a possible source of errors if you encounter problems. They could -possibly shadow other values that you have already set. - -### Repository Options - -| Attribute | Description | Default Value | Example Value | Environment Variable | -| ---------------- | ---------------------------------------------------------- | ------------------------ | ---------------------- | ----------------------- | -| cache-dir | Path to the cache directory. | ~/.cache/rustic/$REPO_ID | ~/.cache/my_own_cache/ | RUSTIC_CACHE_DIR | -| no-cache | If true, disables caching. | false | | RUSTIC_NO_CACHE | -| repository | The path to the repository. Required. | Not set | "/tmp/rustic" | RUSTIC_REPOSITORY | -| repo-hot | The path to the hot repository. | Not set | | RUSTIC_REPO_HOT | -| password | The password for the repository. | Not set | "mySecretPassword" | RUSTIC_PASSWORD | -| password-file | Path to a file containing the password for the repository. | Not set | | RUSTIC_PASSWORD_FILE | -| password-command | Command to retrieve the password for the repository. | Not set | | RUSTIC_PASSWORD_COMMAND | -| warm-up | If true, warms up the repository by file access. | false | | | -| warm-up-command | Command to warm up the repository. | Not set | | | -| warm-up-wait | The wait time for warming up the repository. | Not set | | | - -### Repository Options (Additional) +config profile as a possible source of errors if you encounter problems. They +could possibly shadow other values that you have already set. + +### Repository Options `[repository]` + +| Attribute | Description | Default Value | Example Value | Environment Variable | CLI Option | +| ---------------- | ---------------------------------------------------------- | ------------------------ | ---------------------- | ----------------------- | ------------------- | +| cache-dir | Path to the cache directory. | ~/.cache/rustic/$REPO_ID | ~/.cache/my_own_cache/ | RUSTIC_CACHE_DIR | --cache-dir | +| no-cache | If true, disables caching. | false | | RUSTIC_NO_CACHE | --no-cache | +| repository | The path to the repository. Required. | Not set | "/tmp/rustic" | RUSTIC_REPOSITORY | --repositoy, -r | +| repo-hot | The path to the hot repository. | Not set | | RUSTIC_REPO_HOT | --repo-hot | +| password | The password for the repository. | Not set | "mySecretPassword" | RUSTIC_PASSWORD | --password | +| password-file | Path to a file containing the password for the repository. | Not set | | RUSTIC_PASSWORD_FILE | --password-file, -p | +| password-command | Command to retrieve the password for the repository. | Not set | | RUSTIC_PASSWORD_COMMAND | --password-command | +| warm-up | If true, warms up the repository by file access. | false | | | ---warm-up | +| warm-up-command | Command to warm up the repository. | Not set | | | --warm-up-command | +| warm-up-wait | The wait time for warming up the repository. | Not set | | | --warm-up-wait | + +### Repository Options (Additional) `[repository.options]` + +Additional repository options - depending on backend. These can be only set in +the config file or using env variables. For env variables use upper snake case +and prefix with "RUSTIC_REPO_OPT_", e.g. `use-password = "true"` becomes +`RUSTIC_REPO_OPT_USE_PASSWORD=true` | Attribute | Description | Default Value | Example Value | | ------------------- | ------------------------------------------------------------------ | ------------- | ------------------------------ | | post-create-command | Command to execute after creating a snapshot in the local backend. | Not set | "par2create -qq -n1 -r5 %file" | | post-delete-command | Command to execute after deleting a snapshot in the local backend. | Not set | "sh -c \"rm -f %file*.par2\"" | -### Snapshot-Filter Options - -| Attribute | Description | Default Value | Example Value | -| ------------ | ------------------------------------- | --------------- | ------------- | -| filter-fn | Custom filter function for snapshots. | Not set | | -| filter-host | Array of hosts to filter snapshots. | Not set | ["myhost"] | -| filter-label | Array of labels to filter snapshots. | No label filter | | -| filter-paths | Array of paths to filter snapshots. | No paths filter | | -| filter-tags | Array of tags to filter snapshots. | No tags filter | | - -### Backup Options - -**Note**: Some options are not source-specific, but if set here, they apply for -all sources, although they can be overwritten in the source-specifc -configuration. - -| Attribute | Description | Default Value | Example Value | -| ---------------- | --------------------------------------------------------- | ------------- | ------------- | -| description | Description for the backup. | Not set | | -| description-from | Path to a file containing the description for the backup. | Not set | | -| delete-never | If true, never delete the backup. | false | | -| delete-after | Time duration after which the backup will be deleted. | Not set | | - -### Backup Sources - -| Attribute | Description | Default Value | Example Value | -| --------- | ------------------------------------ | ------------- | --------------------- | -| source | Source directory or file to back up. | Not set | "/tmp/dir/to_backup/" | - -#### Source-specific options - -**Note**: The following options can be specified for each source individually in -the source-individual section, see below. If they are specified here, they -provide default values for all sources but can still be overwritten in the -source-individual section. - -| Attribute | Description | Default Value | -| ------------------ | --------------------------------------------------------------------------------------- | ------------- | -| as-path | Specifies the path for the backup when the source contains a single path. | Not set | -| exclude-if-present | Array of filenames to exclude from the backup if they are present. | Not set | -| force | If true, forces the backup even if no changes are detected. | Not set | -| git-ignore | If true, use .gitignore rules to exclude files from the backup in the source directory. | true | -| glob-file | Array of glob files specifying additional files to include in the backup. | Not set | -| group-by | Grouping strategy for the backup. | Not set | -| host | Host name for the backup. | Not set | -| ignore-ctime | If true, ignores file change time (ctime) for the backup. | Not set | -| ignore-inode | If true, ignores file inode for the backup. | Not set | -| init | If true, initializes repository if it doesn't exist, yet. | Not set | -| json | If true, returns output of the command as json. | Not set | -| label | Label for the backup. | Not set | -| one-file-system | If true, only backs up files from the same filesystem as the source. | Not set | -| parent | Parent snapshot ID for the backup. | Not set | -| stdin-filename | File name to be used when reading from stdin. | Not set | -| tag | Array of tags for the backup. | Not set | -| with-atime | If true, includes file access time (atime) in the backup. | Not set | - -### Forget Options - -| Attribute | Description | Default Value | Example Value | -| ----------------- | ---------------------------------------------------------- | ------------- | -------------- | -| filter-host | Array of hosts to filter snapshots. | Not set | ["forgethost"] | -| keep-daily | Number of daily backups to keep. | Not set | | -| keep-within-daily | The time duration within which daily backups will be kept. | Not set | "7 days" | -| keep-hourly | Number of hourly backups to keep. | Not set | | -| keep-monthly | Number of monthly backups to keep. | Not set | | -| keep-weekly | Number of weekly backups to keep. | Not set | | -| keep-yearly | Number of yearly backups to keep. | Not set | | -| keep-tags | Array of tags to keep. | Not set | ["mytag"] | - -### Copy Targets - -**Note**: Copy-targets are simply repositories with the same defaults as within -the repository section. - -| Attribute | Description | Default Value | Example Value | -| ------------------- | ---------------------------------------------------------------------- | ------------------------ | ---------------------- | -| cache-dir | Path to the cache directory for the target repository. | ~/.cache/rustic/$REPO_ID | ~/.cache/my_own_cache/ | -| no-cache | If true, disables caching for the target repository. | false | | -| password | The password for the target repository. | Not set | | -| password-file | Path to a file containing the password for the target repository. | Not set | | -| password-command | Command to retrieve the password for the target repository. | Not set | | -| post-create-command | Command to execute after creating a snapshot in the target repository. | Not set | | -| post-delete-command | Command to execute after deleting a snapshot in the target repository. | Not set | | -| repository | The path or URL to the target repository. | Not set | | -| repo-hot | The path or URL to the hot target repository. | Not set | | -| warm-up | If true, warms up the target repository by file access. | Not set | | -| warm-up-command | Command to warm up the target repository. | Not set | | -| warm-up-wait | The wait time for warming up the target repository. | Not set | | +### Repository Options for cold repo (Additional) `[repository.options-cold]` + +Additional repository options for cold repository - depending on backend. These +can be only set in the config file or using env variables. For env variables use +upper snake case and prefix with "RUSTIC_REPO_OPTCOLD_". + +### Repository Options for hot repo (Additional) `[repository.options-hot]` + +Additional repository options for hot repository - depending on backend. These +can be only set in the config file or using env variables. For env variables use +upper snake case and prefix with "RUSTIC_REPO_OPTHOT_". + +see Repository Options + +### Repository Hooks `[repository.hooks]` + +These external commands are run before and after each repository-accessing +commands, respectively. + +See [Global Hooks](#global-hooks-globalhooks). + +### Snapshot-Filter Options `[snapshot-filter]` + +| Attribute | Description | Default Value | Example Value | CLI Option | +| ------------------ | ---------------------------------------------------------------------- | ------------- | ------------------------ | -------------------- | +| filter-hosts | Array of hosts to filter snapshots. | Not set | ["myhost", "host2"] | --filter-host | +| filter-labels | Array of labels to filter snapshots. | Not set | ["mylabal"] | --filter-label | +| filter-paths | Array of pathlists to filter snapshots. | Not set | ["/home,/root"] | --filter-paths | +| filter-paths-exact | Array or string of paths to filter snapshots. Exact match. | Not set | ["path1,path2", "path3"] | --filter-paths-exact | +| filter-tags | Array of taglists to filter snapshots. | Not set | ["tag1,tag2"] | --filter-tags | +| filter-tags-exact | Array or string of tags to filter snapshots. Exact match. | Not set | ["tag1,tag2", "tag3"] | --filter-tags-exact | +| filter-before | Filter snapshots before the given date/time | Not set | "2024-01-01" | --filter-before | +| filter-after | Filter snapshots after the given date/time | Not set | "2023-01-01 11:15:23" | --filter-after | +| filter-size | Filter snapshots for a total size in the size range. | Not set | "1MB..1GB" | --filter-size | +| | If a single value is given, this is taken as lower bound. | | "500 k" | | +| filter-size-added | Filter snapshots for a size added to the repository in the size range. | Not set | "1MB..1GB" | --filter-size-added | +| | If a single value is given, this is taken as lower bound. | | "500 k" | | +| filter-fn | Custom filter function for snapshots. | Not set | | --filter-fn | + +### Backup Options `[backup]` + +**Note**: If set here, the backup options apply for all sources, although they +can be overwritten in the source-specific configuration, see below. + +| Attribute | Description | Default Value | Example Value | CLI Option | +| --------------------- | --------------------------------------------------------------------------------------- | --------------------- | ------------- | ----------------------- | +| as-path | Specifies the path for the backup when the source contains a single path. | Not set | | --as-path | +| command | Set the command saved in the snapshot. | The full command used | | --command | +| custom-ignorefiles | Array of names of custom ignorefiles which will be used to exclude files. | [] | | --custom-ignorefile | +| description | Description for the snapshot. | Not set | | --description | +| description-from | Path to a file containing the description for the snapshot. | Not set | | --description-from | +| delete-never | If true, never delete the snapshot. | false | | --delete-never | +| delete-after | Time duration after which the snapshot be deleted. | Not set | | --delete-after | +| exclude-if-present | Array of filenames to exclude from the backup if they are present. | [] | | --exclude-if-present | +| force | If true, forces the backup even if no changes are detected. | false | | --force | +| git-ignore | If true, use .gitignore rules to exclude files from the backup in the source directory. | false | | --git-ignore | +| globs | Array of globs specifying what to include/exclude in the backup. | [] | | --glob | +| glob-files | Array or string of glob files specifying what to include/exclude in the backup. | [] | | --glob-file | +| group-by | Grouping strategy to find parent snapshot. | "host,label,paths" | | --group-by | +| host | Host name used in the snapshot. | local hostname | | --host | +| iglobs | Like glob, but apply case-insensitive | [] | | --iglob | +| iglob-files | Like glob-file, but apply case-insensitive | [] | | --iglob-file | +| ignore-devid | If true, don't save device ID. | false | | --ignore-devid | +| ignore-ctime | If true, ignore file change time (ctime). | false | | --ignore-ctime | +| ignore-inode | If true, ignore file inode for the backup. | false | | --ignore-inode | +| init | If true, initialize repository if it doesn't exist, yet. | false | | --init | +| json | If true, returns output of the command as json. | false | | --json | +| label | Set label fot the snapshot. | Not set | | --label | +| no-require-git | (with git-ignore:) Apply .git-ignore files even if they are not in a git repository. | false | | --no-require-git | +| no-scan | Don't scan the backup source for its size (disables ETA). | false | | --no-scan | +| one-file-system | If true, only backs up files from the same filesystem as the source. | false | | --one-file-system | +| parent | Parent snapshot ID for the backup. | Not set | | --parent | +| quiet | Don't output backup summary. | false | | --quiet | +| skip-identical-parent | Skip saving of the snapshot if it is identical to the parent. | false | | --skip-identical-parent | +| stdin-filename | File name to be used when reading from stdin. | Not set | | --stdin-filename | +| tags | Array of tags for the backup. | [] | | --tag | +| time | Set the time saved in the snapshot. | current time | | --time | +| with-atime | If true, includes file access time (atime) in the backup. | false | | --with-atime | + +### Backup Hooks `[backup.hooks]` + +These external commands are run before and after each backup, respectively. + +**Note**: Global hooks and repository hooks are run additionaly. + +See [Global Hooks](#global-hooks-globalhooks). + +### Backup Snapshots `[[backup.snapshots]]` + +**Note**: All of the backup options mentioned before can also be used as +snapshot-specific option and then only apply to this snapshot. + +| Attribute | Description | Default Value | Example Value | +| --------- | ------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------- | +| sources | Array of source directories or file(s) to back up. | [] | ["/dir1", "/dir2"] | +| hooks | Hooks to run before and after backing up the defined sources. | Not set | { run-before = [], run-after = [], run-failed = [], run-finally = [] } | + +Source-specific hooks are called additionally to global, repository and backup +hooks when backing up the defined sources into a snapshot. + +### Forget Options `[forget]` + +**Note**: At lest on of the `keep-*` options must be given. Use +`keep-none = true` if you want to remove all snapshots. + +| Attribute | Description | Default Value | Example Value | CLI Option | +| -------------------------- | ----------------------------------------------------------------------- | ------------------ | ---------------------- | ---------------------------- | +| group-by | Group snapshots by given criteria before applying keep policies. | "host,label,paths" | | --group-by | +| keep-last | Number of most recent snapshots to keep. | Not set | 15 | --keep-last, -l | +| keep-hourly, -H | Number of hourly snapshots to keep. | Not set | | --keep-hourly | +| keep-daily, -d | Number of daily snapshots to keep. | Not set | 8 | --keep-daily | +| keep-weekly, -w | Number of weekly snapshots to keep. | Not set | | --keep-weekly | +| keep-monthly, -m | Number of monthly snapshots to keep. | Not set | | --keep-monthly | +| keep-quarter-yearly | Number of quarter-yearly snapshots to keep. | Not set | | --keep-quarter-yearly | +| keep-half-yearly | Number of half-yearly snapshots to keep. | Not set | | --keep-half-yearly | +| keep-yearly, -y | Number of yearly snapshots to keep. | Not set | | --keep-yearly | +| keep-within-hourly | The time duration within which hourly snapshots will be kept. | Not set | "1 day" | --keep-within-hourly | +| keep-within-daily | The time duration within which daily snapshots will be kept. | Not set | "7 days" | --keep-within-daily | +| keep-within-weekly | The time duration within which weekly snapshots will be kept. | Not set | | --keep-within-weekly | +| keep-within-monthly | The time duration within which monthly snapshots will be kept. | Not set | | --keep-within-monthly | +| keep-within-quarter-yearly | The time duration within which quarter-yearly snapshots will be kept. | Not set | | --keep-within-quarter-yearly | +| keep-within-half-yearly | The time duration within which half-yearly snapshots will be kept. | Not set | | --keep-within-half-yearly | +| keep-within-yearly | The time duration within which yearly snapshots will be kept. | Not set | | --keep-within-yearly | +| keep-tags | Keep snapshots containing one of these taglists. | [] | ["keep", "important" ] | --keep-tags | +| keep-ids | Keep snapshots containing one of these IDs. | [] | ["6e58f3d32" ] | --keep-id | +| keep-none | Allow to keep no snapshots. | false | true | --keep-none | +| prune | If set to true, prune the repository after snapshots have been removed. | false | | --prune | + +Additionally extra snapshot filter options can be given for the `forget` command +here, see Snapshot-Filter options. + +### Copy Targets `[copy]` + +**Note**: Copy-targets must be defined in their own config profile files. + +| Attribute | Description | Default Value | Example Value | CLI Option | +| --------- | ------------------ | ------------- | ------------------------ | ---------- | +| targets | Targets to copy to | [] | ["profile1", "profile2"] | --target | + +### WebDAV Options `[webdav]` + +`rustic` supports mounting snapshots via WebDAV. This is useful if you want to +access your snapshots via a file manager. + +**Note**: `https://` and Authentication are not supported yet. + +The following options are available to be used in your configuration file: + +| Attribute | Description | Default Value | Example Value | CLI Option | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------- | --------------- | +| address | Address of the WebDAV server. | localhost:8000 | | --address | +| path-template | The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. | `[{hostname}]/[{label}]/{time}` | | --path-template | +| time-template | The time template to use to display times in the path template. See for format options. | `%Y-%m-%d_%H-%M-%S` | | --time-template | +| symlinks | If true, follows symlinks. | false | | --symlinks | +| file-access | How to handle access to files. | "forbidden" for hot/cold repositories, else "read" | | --file-access | +| snapshot-path | Specify directly which snapshot/path to serve | Not set, this will generate a virtual tree with all snapshots using path-template | | --snapshot-path | diff --git a/config/copy_example.toml b/config/copy_example.toml index 1e7e67df1..9a9f4b085 100644 --- a/config/copy_example.toml +++ b/config/copy_example.toml @@ -8,14 +8,6 @@ repository = "/tmp/repo" password = "test" -# you can specify multiple targets -[[copy.targets]] -repository = "/tmp/repo2" -password = "test" -no-cache = true - -[[copy.targets]] -repository = "rclone:ovh:backup" -repo-hot = "clone:ovh:backup-hot" -password-file = "/root/key-rustic-ovh" -cache-dir = "/var/lib/cache/rustic" # explicitly specify cache dir for remote repository +# you can specify multiple targets. Note that each target must be configured via a config profile file +[copy] +targets = ["full", "rustic"] diff --git a/config/full.toml b/config/full.toml index c28ca65ec..a23e719cf 100644 --- a/config/full.toml +++ b/config/full.toml @@ -8,12 +8,23 @@ # Global options: These options are used for all commands. [global] -use-profile = [] +use-profiles = [] log-level = "info" # any of "off", "error", "warn", "info", "debug", "trace"; default: "info" log-file = "/path/to/rustic.log" # Default: not set no-progress = false progress-interval = "100ms" dry-run = false +check-index = false + +# Global hooks: The given commands are called for every command +[global.hooks] +run-before = [ + # long form giving command and args explicitely and allow to specify failure behavior + { command = "echo", args = ["before"], on-failure = "warn" }, # allowed values for on-failure: "error" (default), "warn", "ignore" +] # Default: [] +run-after = ["echo after"] # Run after if successful, short version, default: [] +run-failed = ["echo failed"] # Default: [] +run-finally = ["echo finally"] # Always run after, default: [] # Global env variables: These are set by rustic before calling a subcommand, e.g. rclone or commands # defined in the repository options. @@ -36,26 +47,60 @@ warm-up = false warm-up-command = "warmup.sh %id" # Default: not set warm-up-wait = "10min" # Default: not set -# Additional repository options - depending on backend. These can be only set in the config file. +# Additional repository options - depending on backend. These can be only set in the config file or using env variables. +# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPT_", e.g. `use-passwort = "true"` becomes +# `RUSTIC_REPO_OPT_USE_PASSWORT=true` [repository.options] post-create-command = "par2create -qq -n1 -r5 %file" # Only local backend; Default: not set post-delete-command = "sh -c \"rm -f %file*.par2\"" # Only local backend; Default: not set -retry = "default" # Only rest/rclone backend; Allowed values: "false"/"off", "default" or number of retries +retry = "default" # Only rest/rclone/all opendal backends; Allowed values: "false"/"off", "default" or number of retries timeout = "10min" # Only rest/rclone backend +rclone-command = "rclone serve restic --addr localhost:0" # Only rclone; Default: not set +use-password = "true" # Only rclone +rest-url = "http://localhost:8000" # Only rclone; Default: determine REST URL from rclone output +connections = "20" # Only opendal backends; Default: Not set +throttle = "10kB,10MB" # limit and burst per second; only opendal backends; Default: Not set +# Note that opendal backends use several service-dependent options which may be specified here, see +# https://opendal.apache.org/docs/rust/opendal/services/index.html + +# Additional repository options for the hot part - depending on backend. These can be only set in the config file or +# using env variables. +# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPTHOT_" +[repository.options-hot] +# see [repository.options] + +# Additional repository options for the cold part - depending on backend. These can be only set in the config file or +# using env variables. +# For env variables use upper snake case and prefix with "RUSTIC_REPO_OPTCOLD_" +[repository.options-cold] +# see [repository.options] + +# Repository hooks: The given commands are called for commands accessing the repository. +[repository.hooks] +run-before = ["echo before"] # Default: [] +run-after = ["echo after"] # Run after if successful, default: [] +run-failed = ["echo failed"] # Default: [] +run-finally = ["echo finally"] # Always run after, default: [] # Snapshot-filter options: These options apply to all commands that use snapshot filters [snapshot-filter] -filter-host = ["host2", "host2"] # Default: no host filter -filter-label = ["label1", "label2"] # Default: no label filter -filter-tags = ["tag1,tag2", "tag3"] # Default: no tags filger -filter-paths = ["path1", "path2,path3"] # Default: no paths filter +filter-hosts = ["host1", "host2"] # Default: [] +filter-labels = ["label1", "label2"] # Default: [] +filter-tags = ["tag1,tag2", "tag3"] # Default: [] +filter-tags-exact = ["tag1,tag2", "tag2"] # Default: [] +filter-paths = ["path1", "path2,path3"] # Default: [] +filter-paths-exact = ["path1", "path2,path3"] # Default: [] +filter-after = "2024-01-01" # Default: not set +filter-before = "2024-02-05 12:15" # Default: not set +filter-size = "200MiB" # Default: not set +filter-size-added = "1 MB..10MB" # Default: not set filter-fn = '|sn| {sn.host == "host1" || sn.description.contains("test")}' # Default: no filter function # Backup options: These options are used for all sources when calling the backup command. # They can be overwritten by source-specific options (see below) or command line options. [backup] label = "label" # Default: not set -tag = ["tag1", "tag2"] +tags = ["tag1", "tag2"] description = "my description" # Default: not set description-from = "/path/to/description.txt" # Default: not set delete-never = false @@ -70,51 +115,47 @@ stdin-filename = "stdin" # Only for stdin source as-path = "/my/path" # Default: not set; Note: This only works if source contains of a single path. with-atime = false ignore-devid = false -glob = [] -iglob = [] -glob-file = [] -iglob-file = [] +globs = [] +iglobs = [] +glob-files = [] +iglob-files = [] git-ignore = false no-require-git = false exclude-if-present = [".nobackup", "CACHEDIR.TAG"] # Default: not set +custom-ignorefiles = [".rusticignore", ".backupignore"] # Default: not set one-file-system = false exclude-larger-than = "100MB" # Default: not set json = false init = false +no-scan = false +quiet = false +skip-identical-parent = false + +# Backup hooks: The given commands are called for the `backup` command +[backup.hooks] +run-before = ["echo before"] # Default: [] +run-after = ["echo after"] # Run after if successful, default: [] +run-failed = ["echo failed"] # Default: [] +run-finally = ["echo finally"] # Always run after, default: [] # Backup options for specific sources - all above options are also available here and replace them for the given source -[[backup.sources]] -source = "/path/to/source1" +[[backup.snapshots]] +sources = ["/path/to/source1"] label = "label" # Default: not set -tag = ["tag1", "tag2"] -description = "my description" # Default: not set -description-from = "/path/to/description.txt" # Default: not set -delete-never = false -delete-after = "5d" # Default: not set -host = "manually_set_host" # Default: host name -group-by = "host,label,paths" # Can be any combination of host,label,paths,tags -parent = "123abc" # Default: not set -force = false -ignore-ctime = false -ignore-inode = false -stdin-filename = "stdin" # Only for stdin source -as-path = "/my/path" # Default: not set; Note: This only works if source contains of a single path. -with-atime = false -ignore-devid = false -glob = [] -iglob = [] -glob-file = [] -iglob-file = [] -git-ignore = false -no-require-git = false -exclude-if-present = [".nobackup", "CACHEDIR.TAG"] # Default: not set -one-file-system = false -exclude-larger-than = "100MB" # Default: not set -json = false -init = false +# .. and so on. see [backup] -[[backup.sources]] -source = "/path/to/source2 /second/path" # multiple local paths are allowd within one source +# Source-specific hooks: The given commands when backing up the defined source +[backup.snapshots.hooks] +run-before = ["echo before"] # Default: [] +run-after = ["echo after"] # Run after if successful, default: [] +run-failed = ["echo failed"] # Default: [] +run-finally = ["echo finally"] # Always run after, default: [] + +[[backup.snapshots]] +sources = [ + "/path/to/source2", + "/second/path", +] # multiple local paths are given as array # ... # forget options @@ -122,17 +163,23 @@ source = "/path/to/source2 /second/path" # multiple local paths are allowd withi prune = false group-by = "host,label,paths" # Can be any combination of host,label,paths,tags # The following filter options can be also defined here and then overwrite the options for the forget command -filter-host = ["host2", "host2"] # Default: no host filter -filter-label = ["label1", "label2"] # Default: no label filter -filter-tags = ["tag1,tag2", "tag3"] # Default: no tags filger -filter-paths = ["path1", "path2,path3"] # Default: no paths filter +filter-hosts = ["host1", "host2"] # Default: [] +filter-labels = ["label1", "label2"] # Default: [] +filter-tags = ["tag1,tag2", "tag3"] # Default: [] +filter-tags-exact = ["tag1,tag2", "tag2"] # Default: [] +filter-paths = ["path1", "path2,path3"] # Default: [] +filter-paths-exact = ["path1", "path2,path3"] # Default: [] +filter-after = "2024-01-01" # Default: not set +filter-before = "2024-02-05 12:15" # Default: not set +filter-size = "200MiB" # Default: not set +filter-size-added = "1 MB..10MB" # Default: not set filter-fn = '|sn| {sn.host == "host1" || sn.description.contains("test")}' # Default: no filter function # The retention options follow. All of these are not set by default. -keep-tags = ["tag1", "tag2,tag3"] +keep-tags = ["tag1", "tag2,tag3"] # Default: not set keep-ids = [ "123abc", "11122233", -] # Keep all snapshots whose ID starts with any of these strings +] # Keep all snapshots whose ID starts with any of these strings, default: not set keep-last = 0 keep-daily = 3 keep-weekly = 0 @@ -148,22 +195,21 @@ keep-withing-quarter-yearly = "0 year" keep-withing-half-yearly = "1 year" keep-within-yearly = "10 years" -# Multiple targets are available for the copy command. Each specify a repository with exactly identical options as in -# the [repository] section. -[[copy.targets]] -repository = "/repo/rustic" # Must be set -repo-hot = "/my/hot/repo" # Default: not set -# one of the three password options must be set -password = "mySecretPassword" -password-file = "/my/password.txt" -password-command = "my_command.sh" -no-cache = false -cache-dir = "/my/rustic/cachedir" # Default: Applications default cache dir, e.g. ~/.cache/rustic -# use either warm-up (warm-up by file access) or warm-up-command to specify warming up -warm-up = false -warm-up-command = "warmup.sh %id" # Default: not set -warm-up-wait = "10min" # Default: not set +[copy] +targets = ["profile1", "profile2"] # Default: [] -[[copy.targets]] -repository = "/repo/rustic2" # Must be set -# ... +[webdav] +address = "localhost:8000" +path-template = "[{hostname}]/[{label}]/{time}" # The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]. Only relevant if no snapshot-path is given. +time-template = "%Y-%m-%d_%H-%M-%S" # only relevant if no snapshot-path is given +symlinks = false +file-access = "read" # Default: "forbidden" for hot/cold repos, else "read" +snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtual tree with all snapshots using path-template + +[mount] +path-template = "[{hostname}]/[{label}]/{time}" # The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]. Only relevant if no snapshot-path is given. +time-template = "%Y-%m-%d_%H-%M-%S" # only relevant if no snapshot-path is given +no-allow-other = true +file-access = "read" # Default: "forbidden" for hot/cold repos, else "read" +mountpoint = "~/mnt" +snapshot-path = "latest:/dir" # Default: not set - if not set, generate a virtual tree with all snapshots using path-template diff --git a/config/hooks.toml b/config/hooks.toml new file mode 100644 index 000000000..b1cecd943 --- /dev/null +++ b/config/hooks.toml @@ -0,0 +1,35 @@ +# Hooks configuration +# +# Hooks are commands that are run during certain events in the application lifecycle. +# They can be used to run custom scripts or commands before or after certain actions. +# The hooks are run in the order they are defined in the configuration file. +# The hooks are divided into 4 categories: global, repository, backup, +# and specific backup sources. +# +# You can also read a more detailed explanation of the hooks in the documentation: +# https://rustic.cli.rs/docs/commands/misc/hooks.html +# +# Please make sure to check the in-repository documentation for the config files +# available at: https://github.com/rustic-rs/rustic/blob/main/config/README.md +# +[global.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[repository.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[backup.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[[backup.snapshots]] +sources = [] +hooks = { run-before = [], run-after = [], run-failed = [], run-finally = [] } diff --git a/config/local.toml b/config/local.toml index 9b378e821..39caa1a15 100644 --- a/config/local.toml +++ b/config/local.toml @@ -17,15 +17,15 @@ keep-yearly = 10 [backup] exclude-if-present = [".nobackup", "CACHEDIR.TAG"] -glob-file = ["/root/rustic-local.glob"] +glob-files = ["/root/rustic-local.glob"] one-file-system = true -[[backup.sources]] -source = "/home" +[[backup.snapshots]] +sources = ["/home"] git-ignore = true -[[backup.sources]] -source = "/etc" +[[backup.snapshots]] +sources = ["/etc"] -[[backup.sources]] -source = "/root" +[[backup.snapshots]] +sources = ["/root"] diff --git a/config/rustic.toml b/config/rustic.toml index 850821984..4e68f90e8 100644 --- a/config/rustic.toml +++ b/config/rustic.toml @@ -17,7 +17,7 @@ password = "mySecretPassword" # snapshot-filter options: These options apply to all commands that use snapshot filters [snapshot-filter] -filter-host = ["myhost"] +filter-hosts = ["myhost"] # backup options: These options are used for all sources when calling the backup command. # They can be overwritten by source-specific options (see below) or command line options. @@ -29,16 +29,16 @@ git-ignore = true # # Note that if you call "rustic backup" without any source, all sources from this config # file will be processed. -[[backup.sources]] -source = "/data/dir" +[[backup.snapshots]] +sources = ["/data/dir"] -[[backup.sources]] -source = "/home" -glob = ["!/home/*/Downloads/*"] +[[backup.snapshots]] +sources = ["/home"] +globs = ["!/home/*/Downloads/*"] # forget options [forget] -filter-host = [ +filter-hosts = [ "forgethost", ] # <- this overwrites the snapshot-filter option defined above keep-tags = ["mytag"] diff --git a/config/services/b2.toml b/config/services/b2.toml new file mode 100644 index 000000000..080b954b0 --- /dev/null +++ b/config/services/b2.toml @@ -0,0 +1,15 @@ +# rustic config file to use B2 storage via Apache OpenDAL +[repository] +repository = "opendal:b2" # just specify the opendal service here +password = "" +# or +# password-file = "/home//etc/secure/rustic_passwd" + +# B2 specific options +[repository.options] +# Here, we give the required b2 options, see https://opendal.apache.org/docs/rust/opendal/services/struct.B2.html +application_key_id = "my_id" # B2 application key ID +application_key = "my_key" # B2 application key secret. Can be also set using OPENDAL_APPLICATION_KEY +bucket = "bucket_name" # B2 bucket name +bucket_id = "bucket_id" # B2 bucket ID +# root = "/" # Set a repository root directory if not using the root directory of the bucket diff --git a/config/ovh-hot-cold.toml b/config/services/rclone_ovh-hot-cold.toml similarity index 72% rename from config/ovh-hot-cold.toml rename to config/services/rclone_ovh-hot-cold.toml index ee490b0d1..431fcd967 100644 --- a/config/ovh-hot-cold.toml +++ b/config/services/rclone_ovh-hot-cold.toml @@ -1,9 +1,9 @@ # rustic config file to backup /home, /etc and /root to a hot/cold repository hosted by OVH # using OVH cloud archive and OVH object storage # -# backup usage: "rustic -P ovh-hot-cold backup -# cleanup: "rustic -P ovh-hot-cold forget --prune -# +# backup usage: "rustic --use-profile ovh-hot-cold backup +# cleanup: "rustic --use-profile ovh-hot-cold forget --prune + [repository] repository = "rclone:ovh:backup-home" repo-hot = "rclone:ovh:backup-home-hot" @@ -20,15 +20,15 @@ keep-yearly = 10 [backup] exclude-if-present = [".nobackup", "CACHEDIR.TAG"] -glob-file = ["/root/rustic-ovh.glob"] +glob-files = ["/root/rustic-ovh.glob"] one-file-system = true -[[backup.sources]] -source = "/home" +[[backup.snapshots]] +sources = ["/home"] git-ignore = true -[[backup.sources]] -source = "/etc" +[[backup.snapshots]] +sources = ["/etc"] -[[backup.sources]] -source = "/root" +[[backup.snapshots]] +sources = ["/root"] diff --git a/config/services/s3_aws.toml b/config/services/s3_aws.toml new file mode 100644 index 000000000..a16770f24 --- /dev/null +++ b/config/services/s3_aws.toml @@ -0,0 +1,13 @@ +# rustic config file to use s3 storage +# Note that this internally uses opendal S3 service, see https://opendal.apache.org/docs/rust/opendal/services/struct.S3.html +# where endpoint, bucket and root are extracted from the repository URL. +[repository] +repository = "opendal:s3" +password = "password" + +# Other options can be given here - note that opendal also support reading config from env files or AWS config dirs, see the opendal S3 docu +[repository.options] +access_key_id = "xxx" # this can be ommited, when AWS config is used +secret_access_key = "xxx" # this can be ommited, when AWS config is used +bucket = "bucket_name" +root = "/path/to/repo" diff --git a/config/services/s3_idrive.toml b/config/services/s3_idrive.toml new file mode 100644 index 000000000..bf1575b1a --- /dev/null +++ b/config/services/s3_idrive.toml @@ -0,0 +1,11 @@ +[repository] +repository = "opendal:s3" +password = "password" + +[repository.options] +root = "/" +bucket = "bucket_name" +endpoint = "https://p7v1.ldn.idrivee2-40.com" +region = "auto" # Explicit region is better, else requests are delayed to determine correct region. +access_key_id = "xxx" +secret_access_key = "xxx" diff --git a/config/services/sftp.toml b/config/services/sftp.toml new file mode 100644 index 000000000..f016ce8bc --- /dev/null +++ b/config/services/sftp.toml @@ -0,0 +1,13 @@ +# rustic config file to use sftp storage +# Note: +# - currently sftp only works on unix +# - Using sftp with password is not supported yet, use key authentication, e.g. use +# ssh-copy-id user@host +[repository] +repository = "opendal:sftp" +password = "mypassword" + +[repository.options] +user = "myuser" +endpoint = "host:port" +root = "path/to/repo" diff --git a/config/services/sftp_hetzner_sbox.toml b/config/services/sftp_hetzner_sbox.toml new file mode 100644 index 000000000..ac6e38541 --- /dev/null +++ b/config/services/sftp_hetzner_sbox.toml @@ -0,0 +1,8 @@ +[repository] +password = "XXXXXX" +repository = "opendal:sftp" + +[repository.options] +endpoint = "ssh://XXXXX.your-storagebox.de:23" +user = "XXXXX" +key = "/root/.ssh/id_XXXXX_ed25519" diff --git a/config/services/webdav_owncloud_nextcloud.toml b/config/services/webdav_owncloud_nextcloud.toml new file mode 100644 index 000000000..b1c53eb81 --- /dev/null +++ b/config/services/webdav_owncloud_nextcloud.toml @@ -0,0 +1,11 @@ +[repository] +repository = "opendal:webdav" +password = "my-backup-password" + +[repository.options] +endpoint = "https://my-owncloud-or-nextcloud-server.com" +# root = "remote.php/webdav/my-folder" # for owncloud +# root = "remote.php/dav/files/" # for nextcloud +username = "user" +# In `Settings -> Security -> App passwords / tokens` you should create a token to be used here. +password = "token" diff --git a/crates/Readme.md b/crates/Readme.md deleted file mode 100644 index 44dbab510..000000000 --- a/crates/Readme.md +++ /dev/null @@ -1,73 +0,0 @@ -# Ecosystem - -**Note**: This is a work in progress. The crates are not yet published. The -descriptions will be updated as soon as the crates are published. We needed to -reserve some crates, because we discovered that another project recently chose -the same name as `rustic`. - -## Crates - -### rustic_core - [Link](https://crates.io/crates/rustic_core) - -Core functionality for the `rustic` ecosystem. Can be found -[here](https://github.com/rustic-rs/rustic_core). - -### rustic_testing (reserved) - [Link](https://crates.io/crates/rustic_testing) - -Testing functionality for the `rustic` ecosystem. Can be found in -[crates/rustic_testing](./rustic_testing/). - -### rustic_ui (reserved) - [Link](https://crates.io/crates/rustic_ui) - -General UI functionality for the `rustic` ecosystem. - -### rustic_gui (reserved) - [Link](https://crates.io/crates/rustic_gui) - -Graphical UI for `rustic`. - -### rustic_tui (reserved) - [Link](https://crates.io/crates/rustic_tui) - -Terminal UI for `rustic`. - -### rustic_cli (reserved) - [Link](https://crates.io/crates/rustic_cli) - -Common used CLI functionality for the `rustic` ecosystem. - -### rustic_web (reserved) - [Link](https://crates.io/crates/rustic_web) - -Possible WASM/WASI functionality for the `rustic` ecosystem. - -### rustic_store (reserved) - [Link](https://crates.io/crates/rustic_store) - -Possible store functionality to support a plugin system for the `rustic` -ecosystem. - -### rustic_plugins (reserved) - [Link](https://crates.io/crates/rustic_plugins) - -Plugin functionality for the `rustic` ecosystem. - -### rustic_scheduler (reserved) - [Link](https://crates.io/crates/rustic_scheduler) - -Scheduling functionality for the `rustic` ecosystem. - -### rustic_daemon (reserved) - [Link](https://crates.io/crates/rustic_daemon) - -A daemon for `rustic` and running it as a service. - -### rustic_backend (reserved) - [Link](https://crates.io/crates/rustic_backend) - -A possible backend implementation for `rustic` to support multi-system backup -management. - -### rustic_server (reserved) - [Link](https://crates.io/crates/rustic_server) - -A possible server implementation for `rustic` to support client-/server -communication (for example for a web GUI or a TUI). - -### rustic_bench (reserved) - [Link](https://crates.io/crates/rustic_bench) - -Benchmarking functionality for the `rustic` ecosystem. - -### rustic_auth (reserved) - [Link](https://crates.io/crates/rustic_auth) - -Authentication functionality for the `rustic` ecosystem. diff --git a/crates/rustic_testing/Cargo.toml b/crates/rustic_testing/Cargo.toml deleted file mode 100644 index 11629e8f5..000000000 --- a/crates/rustic_testing/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "rustic_testing" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -aho-corasick = { workspace = true } -once_cell = { workspace = true } -tempfile = { workspace = true } diff --git a/crates/rustic_testing/src/lib.rs b/crates/rustic_testing/src/lib.rs deleted file mode 100644 index 8b7a1e730..000000000 --- a/crates/rustic_testing/src/lib.rs +++ /dev/null @@ -1,71 +0,0 @@ -use aho_corasick::{AhoCorasick, PatternID}; -use std::{error::Error, ffi::OsStr}; -use tempfile::NamedTempFile; - -pub type TestResult = std::result::Result>; - -pub fn get_matches(patterns: I, output: String) -> TestResult> -where - I: IntoIterator, - P: AsRef<[u8]>, -{ - let ac = AhoCorasick::new(patterns)?; - let mut matches = vec![]; - for mat in ac.find_iter(output.as_str()) { - add_match_to_vector(&mut matches, mat); - } - Ok(matches) -} - -pub fn add_match_to_vector(matches: &mut Vec<(PatternID, usize)>, mat: aho_corasick::Match) { - matches.push((mat.pattern(), mat.end() - mat.start())) -} - -pub fn get_temp_file() -> TestResult { - Ok(NamedTempFile::new()?) -} - -pub fn files_differ( - path_left: impl AsRef, - path_right: impl AsRef, -) -> TestResult { - // diff the directories - #[cfg(not(windows))] - { - let proc = std::process::Command::new("diff") - .arg(path_left) - .arg(path_right) - .output()?; - - if proc.stdout.is_empty() { - return Ok(false); - } - } - - #[cfg(windows)] - { - let proc = std::process::Command::new("fc.exe") - .arg("/L") - .arg(path_left) - .arg(path_right) - .output()?; - - let output = String::from_utf8(proc.stdout)?; - - dbg!(&output); - - let patterns = &["FC: no differences encountered"]; - let ac = AhoCorasick::new(patterns)?; - let mut matches = vec![]; - - for mat in ac.find_iter(output.as_str()) { - matches.push((mat.pattern(), mat.end() - mat.start())); - } - - if matches == vec![(PatternID::must(0), 30)] { - return Ok(false); - } - } - - Ok(true) -} diff --git a/deny.toml b/deny.toml index 37aceb1a7..dec284a6f 100644 --- a/deny.toml +++ b/deny.toml @@ -11,6 +11,9 @@ # Root options +# The graph table configures how the dependency graph is constructed and thus +# which crates the checks are performed against +[graph] # If 1 or more target triples (and optionally, target_features) are specified, # only the specified targets will be checked when running `cargo deny check`. # This means, if a particular package is only ever used as a target specific @@ -21,10 +24,9 @@ # list here is effectively saying which targets you are building for. targets = [ - # The triple can be any string, but only the target triples built in to # rustc (as of 1.40) can be checked against actual config expressions - # { triple = "x86_64-unknown-linux-musl" }, + # "x86_64-unknown-linux-musl", # You can also specify which target_features you promise are enabled for a # particular target. target_features are currently not validated against # the actual valid features supported by the target architecture. @@ -48,6 +50,9 @@ no-default-features = false # If set, these feature will be enabled when collecting metadata. If `--features` # is specified on the cmd line they will take precedence over this option. # features = [] + +# The output table provides options for how/if diagnostics are outputted +[output] # When outputting inclusion graphs in diagnostics that include features, this # option can be used to specify the depth at which feature edges will be added. # This option is included since the graphs can be quite large and the addition @@ -59,37 +64,24 @@ feature-depth = 1 # More documentation for the advisories section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] -# The path where the advisory database is cloned/fetched into -db-path = "~/.cargo/advisory-db" +# The path where the advisory databases are cloned/fetched into +db-path = "$CARGO_HOME/advisory-dbs" # The url(s) of the advisory databases to use db-urls = ["https://github.com/rustsec/advisory-db"] -# The lint level for security vulnerabilities -vulnerability = "deny" -# The lint level for unmaintained crates -unmaintained = "warn" -# The lint level for crates that have been yanked from their source registry -yanked = "warn" -# The lint level for crates with security notices. Note that as of -# 2019-12-17 there are no security notice advisories in -# https://github.com/rustsec/advisory-db -notice = "warn" # A list of advisory IDs to ignore. Note that ignored advisories will still # output a note when they are encountered. ignore = [ - - - # "RUSTSEC-0000-0000", + # FIXME!: See https://github.com/RustCrypto/RSA/issues/19#issuecomment-1822995643. + # There is no workaround available yet. + "RUSTSEC-2023-0071", + # FIXME!: proc-macro-error's maintainer seems to be unreachable, we use `merge` which is using this. + # `merge` is self-hosted on another platform, we should check if and how to replace it/open upstream + # issue for updating the dependency. + "RUSTSEC-2024-0370", + # { id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, + # "a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish + # { crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, ] -# Threshold for security vulnerabilities, any vulnerability with a CVSS score -# lower than the range specified will be ignored. Note that ignored advisories -# will still output a note when they are encountered. -# * None - CVSS Score 0.0 -# * Low - CVSS Score 0.1 - 3.9 -# * Medium - CVSS Score 4.0 - 6.9 -# * High - CVSS Score 7.0 - 8.9 -# * Critical - CVSS Score 9.0 - 10.0 -# severity-threshold = - # If this is true, then cargo deny will use the git executable to fetch advisory database. # If this is false, then it uses a built-in git library. # Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. @@ -100,46 +92,22 @@ ignore = [ # More documentation for the licenses section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html [licenses] -# The lint level for crates which do not have a detectable license -unlicensed = "warn" # List of explicitly allowed licenses # See https://spdx.org/licenses/ for list of possible licenses # [possible values: any SPDX 3.11 short identifier (+ optional exception)]. allow = [ - - - # "MIT", - # "Apache-2.0", - # "Apache-2.0 WITH LLVM-exception", - # "ISC", - # "BSD-3-Clause", - # "CC0-1.0", - # "Unicode-DFS-2016", + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "ISC", + "Unicode-DFS-2016", + "BSD-2-Clause", + "BSD-3-Clause", + "MPL-2.0", + "OpenSSL", + "CC0-1.0", + "Zlib", ] -# List of explicitly disallowed licenses -# See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. -deny = [ - - - # "Nokia", -] -# Lint level for licenses considered copyleft -copyleft = "warn" -# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses -# * both - The license will be approved if it is both OSI-approved *AND* FSF -# * either - The license will be approved if it is either OSI-approved *OR* FSF -# * osi - The license will be approved if it is OSI approved -# * fsf - The license will be approved if it is FSF Free -# * osi-only - The license will be approved if it is OSI-approved *AND NOT* FSF -# * fsf-only - The license will be approved if it is FSF *AND NOT* OSI-approved -# * neither - This predicate is ignored and the default lint level is used -allow-osi-fsf-free = "either" -# Lint level used when no other predicates are matched -# 1. License isn't in the allow or deny lists -# 2. License isn't copyleft -# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" -default = "deny" # The confidence threshold for detecting a license from license text. # The higher the value, the more closely the license text must be to the # canonical license text of a valid SPDX license file. @@ -149,31 +117,28 @@ confidence-threshold = 0.8 # aren't accepted for every possible crate as with the normal allow list exceptions = [ - # Each entry is the crate and version constraint, and its specific allow # list - # { allow = ["Zlib"], name = "adler32", version = "*" }, + # { allow = ["Zlib"], crate = "adler32" }, ] # Some crates don't have (easily) machine readable licensing information, # adding a clarification entry for it allows you to manually specify the # licensing information -# [[licenses.clarify]] -# The name of the crate the clarification applies to -# name = "ring" -# The optional version constraint for the crate -# version = "*" +[[licenses.clarify]] +# The package spec the clarification applies to +crate = "ring" # The SPDX expression for the license requirements of the crate -# expression = "MIT AND ISC AND OpenSSL" +expression = "MIT AND ISC AND OpenSSL" # One or more files in the crate's source used as the "source of truth" for # the license expression. If the contents match, the clarification will be used # when running the license check, otherwise the clarification will be ignored # and the crate will be checked normally, which may produce warnings or errors # depending on the rest of your configuration -# license-files = [ -# Each entry is a crate relative path, and the (opaque) hash of its contents -# { path = "LICENSE", hash = 0xbd0eed23 } -# ] +license-files = [ + # Each entry is a crate relative path, and the (opaque) hash of its contents + { path = "LICENSE", hash = 0xbd0eed23 }, +] [licenses.private] # If true, ignores workspace crates that aren't published, or are only @@ -186,7 +151,6 @@ ignore = false # not have its license(s) checked registries = [ - # "https://sekretz.com/registry ] @@ -195,7 +159,7 @@ registries = [ # https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html [bans] # Lint level for when multiple versions of the same crate are detected -multiple-versions = "warn" +multiple-versions = "allow" # Lint level for when a crate version requirement is `*` wildcards = "allow" # The graph highlighting used when creating dotgraphs for crates @@ -215,27 +179,24 @@ external-default-features = "allow" # List of crates that are allowed. Use with care! allow = [ - - # { name = "ansi_term", version = "=0.11.0" }, + # "ansi_term@0.11.0", + # { crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, ] # List of crates to deny deny = [ - - # Each entry the name of a crate and a version range. If version is - # not specified, all versions will be matched. - # { name = "ansi_term", version = "=0.11.0" }, - # + # "ansi_term@0.11.0", + # { crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, # Wrapper crates can optionally be specified to allow the crate when it # is a direct dependency of the otherwise banned crate - # { name = "ansi_term", version = "=0.11.0", wrappers = [] }, + # { crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, ] # List of features to allow/deny # Each entry the name of a crate and a version range. If version is # not specified, all versions will be matched. # [[bans.features]] -# name = "reqwest" +# crate = "reqwest" # Features to not allow # deny = ["json"] # Features to allow @@ -257,8 +218,8 @@ deny = [ # Certain crates/versions that will be skipped when doing duplicate detection. skip = [ - - # { name = "ansi_term", version = "=0.11.0" }, + # "ansi_term@0.11.0", + # { crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, ] # Similarly to `skip` allows you to skip certain crates during duplicate # detection. Unlike skip, it also includes the entire tree of transitive @@ -266,8 +227,8 @@ skip = [ # by default infinite. skip-tree = [ - - # { name = "ansi_term", version = "=0.11.0", depth = 20 }, + # "ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies + # { crate = "ansi_term@0.11.0", depth = 20 }, ] # This section is considered when running `cargo deny check sources`. @@ -287,9 +248,9 @@ allow-registry = ["https://github.com/rust-lang/crates.io-index"] allow-git = [] [sources.allow-org] -# 1 or more github.com organizations to allow git sources for +# github.com organizations to allow git sources for github = ["rustic-rs"] -# 1 or more gitlab.com organizations to allow git sources for -gitlab = [""] -# 1 or more bitbucket.org organizations to allow git sources for -bitbucket = [""] +# gitlab.com organizations to allow git sources for +gitlab = [] +# bitbucket.org organizations to allow git sources for +bitbucket = [] diff --git a/dprint.json b/dprint.json index d9812d6ca..e999505a9 100644 --- a/dprint.json +++ b/dprint.json @@ -19,11 +19,12 @@ "**/*.{json}" ], "excludes": [ - "target/**/*" + "target/**/*", + "CHANGELOG.md" ], "plugins": [ - "https://plugins.dprint.dev/markdown-0.16.3.wasm", - "https://plugins.dprint.dev/toml-0.5.4.wasm", - "https://plugins.dprint.dev/json-0.19.1.wasm" + "https://plugins.dprint.dev/markdown-0.17.8.wasm", + "https://plugins.dprint.dev/toml-0.6.3.wasm", + "https://plugins.dprint.dev/json-0.19.3.wasm" ] } diff --git a/platform-settings.toml b/platform-settings.toml new file mode 100644 index 000000000..84d9984d3 --- /dev/null +++ b/platform-settings.toml @@ -0,0 +1,10 @@ +[platforms.defaults] +release-features = [ + "release", +] + +# Check if 'build-dependencies.just' needs to be updated +[platforms.x86_64-unknown-linux-gnu] +additional-features = [ + "mount", +] diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 000000000..0e243a90d --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,10 @@ +# configuration spec can be found here https://release-plz.ieni.dev/docs/config + +[workspace] +git_release_enable = false # we currently use our own release process +pr_draft = true +# dependencies_update = true # We don't want to update dependencies automatically, as currently our dependencies tree is broken somewhere +# changelog_config = "cliff.toml" # Don't use this for now, as it will override the default changelog config + +[changelog] +protect_breaking_commits = true diff --git a/src/application.rs b/src/application.rs index 63513b618..028783cc9 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,11 +1,11 @@ //! Rustic Abscissa Application -use std::env; +use std::{env, process}; use abscissa_core::{ - application::{self, AppCell}, + application::{self, fatal_error, AppCell}, config::{self, CfgCell}, terminal::component::Terminal, - Application, Component, FrameworkError, StandardPaths, + Application, Component, FrameworkError, FrameworkErrorKind, Shutdown, StandardPaths, }; use anyhow::Result; @@ -16,6 +16,14 @@ use crate::{commands::EntryPoint, config::RusticConfig}; /// Application state pub static RUSTIC_APP: AppCell = AppCell::new(); +// Constants +pub mod constants { + pub const RUSTIC_DOCS_URL: &str = "https://rustic.cli.rs/docs"; + pub const RUSTIC_DEV_DOCS_URL: &str = "https://rustic.cli.rs/dev-docs"; + pub const RUSTIC_CONFIG_DOCS_URL: &str = + "https://github.com/rustic-rs/rustic/blob/main/config/README.md"; +} + /// Rustic Application #[derive(Debug)] pub struct RusticApp { @@ -95,8 +103,38 @@ impl Application for RusticApp { env::set_var(env, value); } + let global_hooks = config.global.hooks.clone(); self.config.set_once(config); + global_hooks.run_before().map_err(|err| -> FrameworkError { + FrameworkErrorKind::ProcessError.context(err).into() + })?; + Ok(()) } + + /// Shut down this application gracefully + fn shutdown(&self, shutdown: Shutdown) -> ! { + let exit_code = match shutdown { + Shutdown::Crash => 1, + _ => 0, + }; + self.shutdown_with_exitcode(shutdown, exit_code) + } + + /// Shut down this application gracefully, exiting with given exit code. + fn shutdown_with_exitcode(&self, shutdown: Shutdown, exit_code: i32) -> ! { + let hooks = &RUSTIC_APP.config().global.hooks; + match shutdown { + Shutdown::Crash => _ = hooks.run_failed(), + _ => _ = hooks.run_after(), + }; + _ = hooks.run_finally(); + let result = self.state().components().shutdown(self, shutdown); + if let Err(e) = result { + fatal_error(self, &e) + } + + process::exit(exit_code); + } } diff --git a/src/commands.rs b/src/commands.rs index 6ff90ec9d..0b242ea10 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -7,13 +7,17 @@ pub(crate) mod completions; pub(crate) mod config; pub(crate) mod copy; pub(crate) mod diff; +pub(crate) mod docs; pub(crate) mod dump; +pub(crate) mod find; pub(crate) mod forget; pub(crate) mod init; pub(crate) mod key; pub(crate) mod list; pub(crate) mod ls; pub(crate) mod merge; +#[cfg(feature = "mount")] +pub(crate) mod mount; pub(crate) mod prune; pub(crate) mod repair; pub(crate) mod repoinfo; @@ -22,114 +26,146 @@ pub(crate) mod self_update; pub(crate) mod show_config; pub(crate) mod snapshots; pub(crate) mod tag; +#[cfg(feature = "tui")] +pub(crate) mod tui; +#[cfg(feature = "webdav")] +pub(crate) mod webdav; +use std::fmt::Debug; use std::fs::File; use std::path::PathBuf; use std::str::FromStr; -use std::sync::Arc; +#[cfg(feature = "mount")] +use crate::commands::mount::MountCmd; +#[cfg(feature = "webdav")] +use crate::commands::webdav::WebDavCmd; use crate::{ commands::{ backup::BackupCmd, cat::CatCmd, check::CheckCmd, completions::CompletionsCmd, - config::ConfigCmd, copy::CopyCmd, diff::DiffCmd, dump::DumpCmd, forget::ForgetCmd, - init::InitCmd, key::KeyCmd, list::ListCmd, ls::LsCmd, merge::MergeCmd, prune::PruneCmd, - repair::RepairCmd, repoinfo::RepoInfoCmd, restore::RestoreCmd, self_update::SelfUpdateCmd, - show_config::ShowConfigCmd, snapshots::SnapshotCmd, tag::TagCmd, + config::ConfigCmd, copy::CopyCmd, diff::DiffCmd, docs::DocsCmd, dump::DumpCmd, + forget::ForgetCmd, init::InitCmd, key::KeyCmd, list::ListCmd, ls::LsCmd, merge::MergeCmd, + prune::PruneCmd, repair::RepairCmd, repoinfo::RepoInfoCmd, restore::RestoreCmd, + self_update::SelfUpdateCmd, show_config::ShowConfigCmd, snapshots::SnapshotCmd, + tag::TagCmd, }, - config::{progress_options::ProgressOptions, RusticConfig}, - {Application, RUSTIC_APP}, + config::RusticConfig, + Application, RUSTIC_APP, }; use abscissa_core::{ config::Override, terminal::ColorChoice, Command, Configurable, FrameworkError, FrameworkErrorKind, Runnable, Shutdown, }; -use anyhow::{anyhow, Result}; -use dialoguer::Password; +use anyhow::Result; +use clap::builder::{ + styling::{AnsiColor, Effects}, + Styles, +}; +use convert_case::{Case, Casing}; +use human_panic::setup_panic; use log::{log, Level}; -use rustic_core::{OpenStatus, Repository}; use simplelog::{CombinedLogger, LevelFilter, TermLogger, TerminalMode, WriteLogger}; -pub(super) mod constants { - pub(super) const MAX_PASSWORD_RETRIES: usize = 5; -} +use self::find::FindCmd; /// Rustic Subcommands /// Subcommands need to be listed in an enum. #[derive(clap::Parser, Command, Debug, Runnable)] enum RusticCmd { /// Backup to the repository - Backup(BackupCmd), + Backup(Box), - /// Show raw data of repository files and blobs - Cat(CatCmd), + /// Show raw data of files and blobs in a repository + Cat(Box), /// Change the repository configuration - Config(ConfigCmd), + Config(Box), /// Generate shell completions - Completions(CompletionsCmd), + Completions(Box), /// Check the repository - Check(CheckCmd), + Check(Box), + + /// Copy snapshots to other repositories + Copy(Box), - /// Copy snapshots to other repositories. Note: The target repositories must be given in the config file! - Copy(CopyCmd), + /// Compare two snapshots or paths + Diff(Box), - /// Compare two snapshots/paths - /// Note that the exclude options only apply for comparison with a local path - Diff(DiffCmd), + /// Open the documentation + Docs(Box), - /// dump the contents of a file in a snapshot to stdout - Dump(DumpCmd), + /// Dump the contents of a file within a snapshot to stdout + Dump(Box), + + /// Find patterns in given snapshots + Find(Box), /// Remove snapshots from the repository - Forget(ForgetCmd), + Forget(Box), /// Initialize a new repository - Init(InitCmd), + Init(Box), + + /// Manage keys for a repository + Key(Box), - /// Manage keys - Key(KeyCmd), + /// List repository files by file type + List(Box), - /// List repository files - List(ListCmd), + #[cfg(feature = "mount")] + /// Mount a repository as read-only filesystem + Mount(Box), /// List file contents of a snapshot - Ls(LsCmd), + Ls(Box), /// Merge snapshots - Merge(MergeCmd), + Merge(Box), /// Show a detailed overview of the snapshots within the repository - Snapshots(SnapshotCmd), + Snapshots(Box), /// Show the configuration which has been read from the config file(s) - ShowConfig(ShowConfigCmd), + ShowConfig(Box), - /// Update to the latest rustic release + /// Update to the latest stable rustic release #[cfg_attr(not(feature = "self-update"), clap(hide = true))] - SelfUpdate(SelfUpdateCmd), + SelfUpdate(Box), /// Remove unused data or repack repository pack files - Prune(PruneCmd), + Prune(Box), - /// Restore a snapshot/path - Restore(RestoreCmd), + /// Restore (a path within) a snapshot + Restore(Box), - /// Repair a snapshot/path - Repair(RepairCmd), + /// Repair a snapshot or the repository index + Repair(Box), /// Show general information about the repository - Repoinfo(RepoInfoCmd), + Repoinfo(Box), /// Change tags of snapshots - Tag(TagCmd), + Tag(Box), + + /// Start a webdav server which allows to access the repository + #[cfg(feature = "webdav")] + Webdav(Box), +} + +fn styles() -> Styles { + Styles::styled() + .header(AnsiColor::Red.on_default() | Effects::BOLD) + .usage(AnsiColor::Red.on_default() | Effects::BOLD) + .literal(AnsiColor::Blue.on_default() | Effects::BOLD) + .placeholder(AnsiColor::Green.on_default()) } /// Entry point for the application. It needs to be a struct to allow using subcommands! #[derive(clap::Parser, Command, Debug)] -#[command(author, about, name="rustic", version = option_env!("PROJECT_VERSION").unwrap_or(env!("CARGO_PKG_VERSION")))] +#[command(author, about, name="rustic", styles=styles(), version = option_env!("PROJECT_VERSION").unwrap_or(env!("CARGO_PKG_VERSION")))] pub struct EntryPoint { #[command(flatten)] pub config: RusticConfig, @@ -140,6 +176,9 @@ pub struct EntryPoint { impl Runnable for EntryPoint { fn run(&self) { + // Set up panic hook for better error messages and logs + setup_panic!(); + self.commands.run(); RUSTIC_APP.shutdown(Shutdown::Graceful) } @@ -162,14 +201,31 @@ impl Configurable for EntryPoint { // That's why it says `_config`, because it's not read at all and therefore not needed. let mut config = self.config.clone(); + // collect "RUSTIC_REPO_OPT*" and "OPENDAL_*" env variables + for (var, value) in std::env::vars() { + if let Some(var) = var.strip_prefix("RUSTIC_REPO_OPT_") { + let var = var.from_case(Case::UpperSnake).to_case(Case::Kebab); + _ = config.repository.be.options.insert(var, value); + } else if let Some(var) = var.strip_prefix("OPENDAL_") { + let var = var.from_case(Case::UpperSnake).to_case(Case::Snake); + _ = config.repository.be.options.insert(var, value); + } else if let Some(var) = var.strip_prefix("RUSTIC_REPO_OPTHOT_") { + let var = var.from_case(Case::UpperSnake).to_case(Case::Kebab); + _ = config.repository.be.options_hot.insert(var, value); + } else if let Some(var) = var.strip_prefix("RUSTIC_REPO_OPTCOLD_") { + let var = var.from_case(Case::UpperSnake).to_case(Case::Kebab); + _ = config.repository.be.options_cold.insert(var, value); + } + } + // collect logs during merging as we start the logger *after* merging let mut merge_logs = Vec::new(); // get global options from command line / env and config file - if config.global.use_profile.is_empty() { + if config.global.use_profiles.is_empty() { config.merge_profile("rustic", &mut merge_logs, Level::Info)?; } else { - for profile in &config.global.use_profile.clone() { + for profile in &config.global.use_profiles.clone() { config.merge_profile(profile, &mut merge_logs, Level::Warn)?; } } @@ -180,33 +236,44 @@ impl Configurable for EntryPoint { .map_err(|e| FrameworkErrorKind::ConfigError.context(e))?, None => LevelFilter::Info, }; + let term_config = simplelog::ConfigBuilder::new() + .set_time_level(LevelFilter::Off) + .build(); match &config.global.log_file { None => TermLogger::init( level_filter, - simplelog::ConfigBuilder::new() - .set_time_level(LevelFilter::Off) - .build(), + term_config, TerminalMode::Stderr, ColorChoice::Auto, ) .map_err(|e| FrameworkErrorKind::ConfigError.context(e))?, - Some(file) => CombinedLogger::init(vec![ - TermLogger::new( + Some(file) => { + let file_config = simplelog::ConfigBuilder::new() + .set_time_format_rfc3339() + .build(); + let file = File::options() + .create(true) + .append(true) + .open(file) + .map_err(|e| { + FrameworkErrorKind::PathError { + name: Some(file.clone()), + } + .context(e) + })?; + let term_logger = TermLogger::new( level_filter.min(LevelFilter::Warn), - simplelog::ConfigBuilder::new() - .set_time_level(LevelFilter::Off) - .build(), + term_config, TerminalMode::Stderr, ColorChoice::Auto, - ), - WriteLogger::new( - level_filter, - simplelog::Config::default(), - File::options().create(true).append(true).open(file)?, - ), - ]) - .map_err(|e| FrameworkErrorKind::ConfigError.context(e))?, + ); + CombinedLogger::init(vec![ + term_logger, + WriteLogger::new(level_filter, file_config, file), + ]) + .map_err(|e| FrameworkErrorKind::ConfigError.context(e))?; + } } // display logs from merging @@ -216,6 +283,11 @@ impl Configurable for EntryPoint { match &self.commands { RusticCmd::Forget(cmd) => cmd.override_config(config), + RusticCmd::Copy(cmd) => cmd.override_config(config), + #[cfg(feature = "webdav")] + RusticCmd::Webdav(cmd) => cmd.override_config(config), + #[cfg(feature = "mount")] + RusticCmd::Mount(cmd) => cmd.override_config(config), // subcommands that don't need special overrides use a catch all _ => Ok(config), @@ -223,50 +295,6 @@ impl Configurable for EntryPoint { } } -/// Open the repository with the given config -/// -/// # Arguments -/// -/// * `config` - The config file -/// -/// # Errors -/// -/// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed -/// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed -/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed -/// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed -/// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed -/// -/// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed -/// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: crate::error::RepositoryErrorKind::OpeningPasswordFileFailed -/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: crate::error::RepositoryErrorKind::PasswordCommandParsingFailed -/// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: crate::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed -/// [`RepositoryErrorKind::FromSplitError`]: crate::error::RepositoryErrorKind::FromSplitError -fn open_repository(config: &Arc) -> Result> { - let po = config.global.progress_options; - let repo = Repository::new_with_progress(&config.repository, po)?; - match repo.password()? { - // if password is given, directly return the result of find_key_in_backend and don't retry - Some(pass) => { - return Ok(repo.open_with_password(&pass)?); - } - None => { - for _ in 0..constants::MAX_PASSWORD_RETRIES { - let pass = Password::new() - .with_prompt("enter repository password") - .allow_empty_password(true) - .interact()?; - match repo.clone().open_with_password(&pass) { - Ok(repo) => return Ok(repo), - // TODO: fail if error != Password incorrect - Err(_) => continue, - } - } - } - } - Err(anyhow!("incorrect password")) -} - #[cfg(test)] mod tests { use crate::commands::EntryPoint; diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 6dbf570ec..31dca3224 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -3,48 +3,58 @@ use std::path::PathBuf; use crate::{ - commands::open_repository, - helpers::bytes_size_to_string, - {status_err, Application, RUSTIC_APP}, + commands::{init::init, snapshots::fill_table}, + config::hooks::Hooks, + helpers::{bold_cell, bytes_size_to_string, table}, + repository::CliRepo, + status_err, Application, RUSTIC_APP, }; -use abscissa_core::{Command, Runnable, Shutdown}; -use anyhow::{bail, Context, Result}; -use log::{debug, info, warn}; -use merge::Merge; -use serde::Deserialize; +use abscissa_core::{Command, Runnable, Shutdown}; +use anyhow::{anyhow, bail, Context, Result}; +use clap::ValueHint; +use comfy_table::Cell; +use conflate::Merge; +use log::{debug, error, info, warn}; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; use rustic_core::{ - BackupOptions, ConfigOptions, KeyOptions, LocalSourceFilterOptions, LocalSourceSaveOptions, - ParentOptions, PathList, Repository, SnapshotOptions, + BackupOptions, CommandInput, ConfigOptions, IndexedIds, KeyOptions, LocalSourceFilterOptions, + LocalSourceSaveOptions, ParentOptions, PathList, ProgressBars, Repository, SnapshotOptions, }; -use super::init::init; - /// `backup` subcommand -#[derive(Clone, Command, Default, Debug, clap::Parser, Deserialize, Merge)] +#[serde_as] +#[derive(Clone, Command, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] -// Note: using cli_sources, sources and source within this struct is a hack to support serde(deny_unknown_fields) +// Note: using cli_sources, sources and snapshots within this struct is a hack to support serde(deny_unknown_fields) // for deserializing the backup options from TOML // Unfortunately we cannot work with nested flattened structures, see // https://github.com/serde-rs/serde/issues/1547 -// A drawback is that a wrongly set "source(s) = ..." won't get correct error handling and need to be manually checked, see below. +// A drawback is that a wrongly set "snapshots = ..." won't get correct error handling and need to be manually checked, see below. #[allow(clippy::struct_excessive_bools)] pub struct BackupCmd { /// Backup source (can be specified multiple times), use - for stdin. If no source is given, uses all /// sources defined in the config file - #[clap(value_name = "SOURCE")] + #[clap(value_name = "SOURCE", value_hint = ValueHint::AnyPath)] #[merge(skip)] #[serde(skip)] cli_sources: Vec, /// Set filename to be used when backing up from stdin - #[clap(long, value_name = "FILENAME", default_value = "stdin")] + #[clap(long, value_name = "FILENAME", default_value = "stdin", value_hint = ValueHint::FilePath)] #[merge(skip)] stdin_filename: String, + /// Start the given command and use its output as stdin + #[clap(long, value_name = "COMMAND")] + #[merge(strategy=conflate::option::overwrite_none)] + stdin_command: Option, + /// Manually set backup path in snapshot - #[clap(long, value_name = "PATH")] + #[clap(long, value_name = "PATH", value_hint = ValueHint::DirPath)] + #[merge(strategy=conflate::option::overwrite_none)] as_path: Option, /// Ignore save options @@ -52,19 +62,29 @@ pub struct BackupCmd { #[serde(flatten)] ignore_save_opts: LocalSourceSaveOptions, + /// Don't scan the backup source for its size - this disables ETA estimation for backup. + #[clap(long)] + #[merge(strategy=conflate::bool::overwrite_false)] + pub no_scan: bool, + /// Output generated snapshot in json format #[clap(long)] - #[merge(strategy = merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] json: bool, - /// Don't show any output + /// Show detailed information about generated snapshot #[clap(long, conflicts_with = "json")] - #[merge(strategy = merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] + long: bool, + + /// Don't show any output + #[clap(long, conflicts_with_all = ["json", "long"])] + #[merge(strategy=conflate::bool::overwrite_false)] quiet: bool, /// Initialize repository, if it doesn't exist yet #[clap(long)] - #[merge(strategy = merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] init: bool, /// Parent processing options @@ -94,33 +114,51 @@ pub struct BackupCmd { #[merge(skip)] config_opts: ConfigOptions, - /// Backup sources + /// Hooks to use + #[clap(skip)] + hooks: Hooks, + + /// Backup snapshots to generate #[clap(skip)] - #[merge(strategy = merge_sources)] - sources: Vec, + #[merge(strategy = merge_snapshots)] + snapshots: Vec, /// Backup source, used within config file #[clap(skip)] #[merge(skip)] - source: String, + sources: Vec, } -/// Merge backup sources +/// Merge backup snapshots to generate /// -/// If a source is already defined on left, use that. Else add it. +/// If a snapshot is already defined on left, use that. Else add it. /// /// # Arguments /// /// * `left` - Vector of backup sources -pub(crate) fn merge_sources(left: &mut Vec, mut right: Vec) { +pub(crate) fn merge_snapshots(left: &mut Vec, mut right: Vec) { left.append(&mut right); - left.sort_by(|opt1, opt2| opt1.source.cmp(&opt2.source)); - left.dedup_by(|opt1, opt2| opt1.source == opt2.source); + left.sort_by(|opt1, opt2| opt1.sources.cmp(&opt2.sources)); + left.dedup_by(|opt1, opt2| opt1.sources == opt2.sources); } impl Runnable for BackupCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + let config = RUSTIC_APP.config(); + + // manually check for a "source" field, check is not done by serde, see above. + if !config.backup.sources.is_empty() { + status_err!("key \"sources\" is not valid in the [backup] section!"); + RUSTIC_APP.shutdown(Shutdown::Crash); + } + + let snapshot_opts = &config.backup.snapshots; + // manually check for a "sources" field, check is not done by serde, see above. + if snapshot_opts.iter().any(|opt| !opt.snapshots.is_empty()) { + status_err!("key \"snapshots\" is not valid in a [[backup.snapshots]] section!"); + RUSTIC_APP.shutdown(Shutdown::Crash); + } + if let Err(err) = config.repository.run(|repo| self.inner_run(repo)) { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -128,11 +166,10 @@ impl Runnable for BackupCmd { } impl BackupCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliRepo) -> Result<()> { let config = RUSTIC_APP.config(); + let snapshot_opts = &config.backup.snapshots; - let po = config.global.progress_options; - let repo = Repository::new_with_progress(&config.repository, po)?; // Initialize repository if --init is set and it is not yet initialized let repo = if self.init && repo.config_id()?.is_none() { if config.global.dry_run { @@ -141,31 +178,22 @@ impl BackupCmd { repo.name ); } - init(repo, &self.key_opts, &self.config_opts)? + init(repo.0, &self.key_opts, &self.config_opts)? } else { - open_repository(&config)? + repo.open()? } .to_indexed_ids()?; - // manually check for a "source" field, check is not done by serde, see above. - if !config.backup.source.is_empty() { - bail!("key \"source\" is not valid in the [backup] section!"); - } - - let config_opts = &config.backup.sources; - - // manually check for a "sources" field, check is not done by serde, see above. - if config_opts.iter().any(|opt| !opt.sources.is_empty()) { - bail!("key \"sources\" is not valid in a [[backup.sources]] section!"); - } - - let config_sources: Vec<_> = config_opts + let config_snapshot_sources: Vec<_> = snapshot_opts .iter() .map(|opt| -> Result<_> { - Ok(PathList::from_string(&opt.source)? + Ok(PathList::from_iter(&opt.sources) .sanitize() .with_context(|| { - format!("error sanitizing source=\"{}\" in config file", opt.source) + format!( + "error sanitizing sources=\"{:?}\" in config file", + opt.sources + ) })? .merge()) }) @@ -178,86 +206,130 @@ impl BackupCmd { }) .collect(); - let sources = match (self.cli_sources.is_empty(), config_opts.is_empty()) { + let snapshot_sources = match (self.cli_sources.is_empty(), snapshot_opts.is_empty()) { (false, _) => { - let item = PathList::from_strings(&self.cli_sources).sanitize()?; + let item = PathList::from_iter(&self.cli_sources).sanitize()?; vec![item] } (true, false) => { info!("using all backup sources from config file."); - config_sources.clone() + config_snapshot_sources.clone() } (true, true) => { bail!("no backup source given."); } }; + if snapshot_sources.is_empty() { + return Ok(()); + } - for source in sources { - let mut opts = self.clone(); + let hooks = config.backup.hooks.with_context("backup"); + hooks.use_with(|| -> Result<_> { + let mut is_err = false; + for sources in snapshot_sources { + let mut opts = self.clone(); - // merge Options from config file, if given - if let Some(idx) = config_sources.iter().position(|s| s == &source) { - info!("merging source={source} section from config file"); - opts.merge(config_opts[idx].clone()); - } - if let Some(path) = &opts.as_path { - // as_path only works in combination with a single target - if source.len() > 1 { - bail!("as-path only works with a single target!"); + // merge Options from config file, if given + if let Some(idx) = config_snapshot_sources.iter().position(|s| s == &sources) { + info!("merging sources={sources} section from config file"); + opts.merge(snapshot_opts[idx].clone()); } - // merge Options from config file using as_path, if given - if let Some(path) = path.as_os_str().to_str() { - if let Some(idx) = config_opts.iter().position(|opt| opt.source == path) { - info!("merging source=\"{path}\" section from config file"); - opts.merge(config_opts[idx].clone()); - } + if let Err(err) = opts.backup_snapshot(sources.clone(), &repo) { + error!("error backing up {sources}: {err}"); + is_err = true; } } + if is_err { + Err(anyhow!("Not all snapshots were generated successfully!")) + } else { + Ok(()) + } + }) + } - // merge "backup" section from config file, if given - opts.merge(config.backup.clone()); - - let backup_opts = BackupOptions::default() - .stdin_filename(opts.stdin_filename) - .as_path(opts.as_path) - .parent_opts(opts.parent_opts) - .ignore_save_opts(opts.ignore_save_opts) - .ignore_filter_opts(opts.ignore_filter_opts) - .dry_run(config.global.dry_run); - let snap = repo.backup(&backup_opts, source.clone(), opts.snap_opts.to_snapshot()?)?; - - if opts.json { - let mut stdout = std::io::stdout(); - serde_json::to_writer_pretty(&mut stdout, &snap)?; - } else if !opts.quiet { - let summary = snap.summary.unwrap(); - println!( - "Files: {} new, {} changed, {} unchanged", - summary.files_new, summary.files_changed, summary.files_unmodified - ); - println!( - "Dirs: {} new, {} changed, {} unchanged", - summary.dirs_new, summary.dirs_changed, summary.dirs_unmodified - ); - debug!("Data Blobs: {} new", summary.data_blobs); - debug!("Tree Blobs: {} new", summary.tree_blobs); - println!( - "Added to the repo: {} (raw: {})", - bytes_size_to_string(summary.data_added_packed), - bytes_size_to_string(summary.data_added) - ); - - println!( - "processed {} files, {}", - summary.total_files_processed, - bytes_size_to_string(summary.total_bytes_processed) - ); - println!("snapshot {} successfully saved.", snap.id); + fn backup_snapshot( + mut self, + source: PathList, + repo: &Repository, + ) -> Result<()> { + let config = RUSTIC_APP.config(); + let snapshot_opts = &config.backup.snapshots; + if let Some(path) = &self.as_path { + // as_path only works in combination with a single target + if source.len() > 1 { + bail!("as-path only works with a single source!"); } + // merge Options from config file using as_path, if given + if let Some(path) = path.as_os_str().to_str() { + if let Some(idx) = snapshot_opts + .iter() + .position(|opt| opt.sources == vec![path]) + { + info!("merging snapshot=\"{path}\" section from config file"); + self.merge(snapshot_opts[idx].clone()); + } + } + } - info!("backup of {source} done."); + // use the correct source-specific hooks + let hooks = self.hooks.with_context(&format!("backup {source}")); + + // merge "backup" section from config file, if given + self.merge(config.backup.clone()); + + let backup_opts = BackupOptions::default() + .stdin_filename(self.stdin_filename) + .stdin_command(self.stdin_command) + .as_path(self.as_path) + .parent_opts(self.parent_opts) + .ignore_save_opts(self.ignore_save_opts) + .ignore_filter_opts(self.ignore_filter_opts) + .no_scan(self.no_scan) + .dry_run(config.global.dry_run); + + let snap = hooks.use_with(|| -> Result<_> { + Ok(repo.backup(&backup_opts, &source, self.snap_opts.to_snapshot()?)?) + })?; + + if self.json { + let mut stdout = std::io::stdout(); + serde_json::to_writer_pretty(&mut stdout, &snap)?; + } else if self.long { + let mut table = table(); + + let add_entry = |title: &str, value: String| { + _ = table.add_row([bold_cell(title), Cell::new(value)]); + }; + fill_table(&snap, add_entry); + + println!("{table}"); + } else if !self.quiet { + let summary = snap.summary.unwrap(); + println!( + "Files: {} new, {} changed, {} unchanged", + summary.files_new, summary.files_changed, summary.files_unmodified + ); + println!( + "Dirs: {} new, {} changed, {} unchanged", + summary.dirs_new, summary.dirs_changed, summary.dirs_unmodified + ); + debug!("Data Blobs: {} new", summary.data_blobs); + debug!("Tree Blobs: {} new", summary.tree_blobs); + println!( + "Added to the repo: {} (raw: {})", + bytes_size_to_string(summary.data_added_packed), + bytes_size_to_string(summary.data_added) + ); + + println!( + "processed {} files, {}", + summary.total_files_processed, + bytes_size_to_string(summary.total_bytes_processed) + ); + println!("snapshot {} successfully saved.", snap.id); } + info!("backup of {source} done."); Ok(()) } } diff --git a/src/commands/cat.rs b/src/commands/cat.rs index 2a085eedb..dde621118 100644 --- a/src/commands/cat.rs +++ b/src/commands/cat.rs @@ -1,6 +1,6 @@ //! `cat` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; @@ -59,19 +59,25 @@ impl Runnable for CatCmd { impl CatCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; - let data = match &self.cmd { - CatSubCmd::Config => repo.cat_file(FileType::Config, "")?, - CatSubCmd::Index(opt) => repo.cat_file(FileType::Index, &opt.id)?, - CatSubCmd::Snapshot(opt) => repo.cat_file(FileType::Snapshot, &opt.id)?, - // special treatment for 'cat'ing blobs: read the index and use it to locate the blob - CatSubCmd::TreeBlob(opt) => repo.to_indexed()?.cat_blob(BlobType::Tree, &opt.id)?, - CatSubCmd::DataBlob(opt) => repo.to_indexed()?.cat_blob(BlobType::Data, &opt.id)?, - // special treatment for 'cat'ing a tree within a snapshot - CatSubCmd::Tree(opt) => repo - .to_indexed()? - .cat_tree(&opt.snap, |sn| config.snapshot_filter.matches(sn))?, + CatSubCmd::Config => config + .repository + .run_open(|repo| Ok(repo.cat_file(FileType::Config, "")?))?, + CatSubCmd::Index(opt) => config + .repository + .run_open(|repo| Ok(repo.cat_file(FileType::Index, &opt.id)?))?, + CatSubCmd::Snapshot(opt) => config + .repository + .run_open(|repo| Ok(repo.cat_file(FileType::Snapshot, &opt.id)?))?, + CatSubCmd::TreeBlob(opt) => config + .repository + .run_indexed(|repo| Ok(repo.cat_blob(BlobType::Tree, &opt.id)?))?, + CatSubCmd::DataBlob(opt) => config + .repository + .run_indexed(|repo| Ok(repo.cat_blob(BlobType::Data, &opt.id)?))?, + CatSubCmd::Tree(opt) => config.repository.run_indexed(|repo| { + Ok(repo.cat_tree(&opt.snap, |sn| config.snapshot_filter.matches(sn))?) + })?, }; println!("{}", String::from_utf8(data.to_vec())?); diff --git a/src/commands/check.rs b/src/commands/check.rs index 7de32d048..b25628bb0 100644 --- a/src/commands/check.rs +++ b/src/commands/check.rs @@ -1,14 +1,18 @@ //! `check` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; -use rustic_core::CheckOptions; +use rustic_core::{CheckOptions, SnapshotGroupCriterion}; /// `check` subcommand #[derive(clap::Parser, Command, Debug)] pub(crate) struct CheckCmd { + /// Snapshots to check. If none is given, use filter options to filter from all snapshots + #[clap(value_name = "ID")] + ids: Vec, + /// Check options #[clap(flatten)] opts: CheckOptions, @@ -16,7 +20,11 @@ pub(crate) struct CheckCmd { impl Runnable for CheckCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -24,10 +32,18 @@ impl Runnable for CheckCmd { } impl CheckCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; - repo.check(self.opts)?; + + let groups = repo.get_snapshot_group(&self.ids, SnapshotGroupCriterion::new(), |sn| { + config.snapshot_filter.matches(sn) + })?; + let trees = groups + .into_iter() + .flat_map(|(_, snaps)| snaps) + .map(|snap| snap.tree) + .collect(); + repo.check_with_trees(self.opts, trees)?; Ok(()) } } diff --git a/src/commands/completions.rs b/src/commands/completions.rs index 473f57ce5..8705d6837 100644 --- a/src/commands/completions.rs +++ b/src/commands/completions.rs @@ -53,6 +53,7 @@ mod tests { fn test_completions() { generate_completion(shells::Bash, &mut std::io::sink()); generate_completion(shells::Fish, &mut std::io::sink()); + generate_completion(shells::PowerShell, &mut std::io::sink()); generate_completion(shells::Zsh, &mut std::io::sink()); } } diff --git a/src/commands/config.rs b/src/commands/config.rs index bee33aa8e..5d3481885 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -1,6 +1,6 @@ //! `config` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; @@ -28,9 +28,10 @@ impl Runnable for ConfigCmd { impl ConfigCmd { fn inner_run(&self) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; - let changed = repo.apply_config(&self.config_opts)?; + let changed = config + .repository + .run_open(|repo| Ok(repo.apply_config(&self.config_opts)?))?; if changed { println!("saved new config"); diff --git a/src/commands/copy.rs b/src/commands/copy.rs index fb7d5afd4..8cc728ca1 100644 --- a/src/commands/copy.rs +++ b/src/commands/copy.rs @@ -1,44 +1,67 @@ //! `copy` subcommand use crate::{ - commands::open_repository, helpers::table_with_titles, status_err, Application, RUSTIC_APP, + commands::init::init_password, + helpers::table_with_titles, + repository::{CliIndexedRepo, CliRepo}, + status_err, Application, RusticConfig, RUSTIC_APP, }; -use abscissa_core::{Command, Runnable, Shutdown}; +use abscissa_core::{config::Override, Command, FrameworkError, Runnable, Shutdown}; use anyhow::{bail, Result}; -use log::{error, info}; +use conflate::Merge; +use log::{error, info, log, Level}; +use serde::{Deserialize, Serialize}; -use merge::Merge; -use serde::Deserialize; - -use rustic_core::{CopySnapshot, Id, KeyOptions, Repository, RepositoryOptions}; +use rustic_core::{repofile::SnapshotFile, CopySnapshot, Id, KeyOptions}; /// `copy` subcommand -#[derive(clap::Parser, Command, Debug)] -pub(crate) struct CopyCmd { +#[derive(clap::Parser, Command, Default, Clone, Debug, Serialize, Deserialize, Merge)] +pub struct CopyCmd { /// Snapshots to copy. If none is given, use filter options to filter from all snapshots. #[clap(value_name = "ID")] + #[serde(skip)] + #[merge(skip)] ids: Vec, /// Initialize non-existing target repositories #[clap(long)] + #[serde(skip)] + #[merge(skip)] init: bool, + /// Target repository (can be specified multiple times) + #[clap(long = "target", value_name = "TARGET")] + #[merge(strategy=conflate::vec::overwrite_empty)] + targets: Vec, + /// Key options (when using --init) #[clap(flatten, next_help_heading = "Key options (when using --init)")] + #[serde(skip)] + #[merge(skip)] key_opts: KeyOptions, } -/// Target repository options -#[derive(Default, Clone, Debug, Deserialize, Merge)] -pub struct Targets { - /// Target repositories - #[merge(strategy = merge::vec::overwrite_empty)] - targets: Vec, +impl Override for CopyCmd { + // Process the given command line options, overriding settings from + // a configuration file using explicit flags taken from command-line + // arguments. + fn override_config(&self, mut config: RusticConfig) -> Result { + let mut self_config = self.clone(); + // merge "copy" section from config file, if given + self_config.merge(config.copy); + config.copy = self_config; + Ok(config) + } } impl Runnable for CopyCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + let config = RUSTIC_APP.config(); + if config.copy.targets.is_empty() { + status_err!("No target given. Please specify at least 1 target either in the profile or using --target!"); + RUSTIC_APP.shutdown(Shutdown::Crash); + } + if let Err(err) = config.repository.run_indexed(|repo| self.inner_run(repo)) { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -46,15 +69,8 @@ impl Runnable for CopyCmd { } impl CopyCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - - if config.copy.targets.is_empty() { - status_err!("no [[copy.targets]] section in config file found!"); - RUSTIC_APP.shutdown(Shutdown::Crash); - } - - let repo = open_repository(&config)?.to_indexed()?; let mut snapshots = if self.ids.is_empty() { repo.get_matching_snapshots(|sn| config.snapshot_filter.matches(sn))? } else { @@ -63,70 +79,85 @@ impl CopyCmd { // sort for nicer output snapshots.sort_unstable(); - let poly = repo.config().poly()?; - for target_opt in &config.copy.targets { - let repo_dest = - Repository::new_with_progress(target_opt, config.global.progress_options)?; - - let repo_dest = if self.init && repo_dest.config_id()?.is_none() { - if config.global.dry_run { - error!( - "cannot initialize target {} in dry-run mode!", - repo_dest.name - ); - continue; - } - let mut config_dest = repo.config().clone(); - config_dest.id = Id::random(); - let pass = repo_dest.password()?.unwrap(); - repo_dest.init_with_config(&pass, &self.key_opts, config_dest)? - } else { - repo_dest.open()? - }; - - info!("copying to target {}...", repo_dest.name); - if poly != repo_dest.config().poly()? { - bail!("cannot copy to repository with different chunker parameter (re-chunking not implemented)!"); + for target in &config.copy.targets { + let mut merge_logs = Vec::new(); + let mut target_config = RusticConfig::default(); + target_config.merge_profile(target, &mut merge_logs, Level::Error)?; + // display logs from merging + for (level, merge_log) in merge_logs { + log!(level, "{}", merge_log); } - - let snaps = repo_dest.relevant_copy_snapshots( - |sn| !self.ids.is_empty() || config.snapshot_filter.matches(sn), - &snapshots, - )?; - - let mut table = - table_with_titles(["ID", "Time", "Host", "Label", "Tags", "Paths", "Status"]); - for CopySnapshot { relevant, sn } in snaps.iter() { - let tags = sn.tags.formatln(); - let paths = sn.paths.formatln(); - let time = sn.time.format("%Y-%m-%d %H:%M:%S").to_string(); - _ = table.add_row([ - &sn.id.to_string(), - &time, - &sn.hostname, - &sn.label, - &tags, - &paths, - &(if *relevant { "to copy" } else { "existing" }).to_string(), - ]); + let target_opt = &target_config.repository; + if let Err(err) = + target_opt.run(|target_repo| self.copy(&repo, target_repo, &snapshots)) + { + error!("error copying to target: {err}"); } - println!("{table}"); - - let count = snaps.iter().filter(|sn| sn.relevant).count(); - if count > 0 { - if config.global.dry_run { - info!("would have copied {count} snapshots."); - } else { - repo.copy( - &repo_dest.to_indexed_ids()?, - snaps - .iter() - .filter_map(|CopySnapshot { relevant, sn }| relevant.then_some(sn)), - )?; - } + } + Ok(()) + } + + fn copy( + &self, + repo: &CliIndexedRepo, + target_repo: CliRepo, + snapshots: &[SnapshotFile], + ) -> Result<()> { + let config = RUSTIC_APP.config(); + + info!("copying to target {}...", target_repo.name); + let target_repo = if self.init && target_repo.config_id()?.is_none() { + let mut config_dest = repo.config().clone(); + config_dest.id = Id::random().into(); + let pass = init_password(&target_repo)?; + target_repo + .0 + .init_with_config(&pass, &self.key_opts, config_dest)? + } else { + target_repo.open()? + }; + + if repo.config().poly()? != target_repo.config().poly()? { + bail!("cannot copy to repository with different chunker parameter (re-chunking not implemented)!"); + } + + let snaps = target_repo.relevant_copy_snapshots( + |sn| !self.ids.is_empty() || config.snapshot_filter.matches(sn), + snapshots, + )?; + + let mut table = + table_with_titles(["ID", "Time", "Host", "Label", "Tags", "Paths", "Status"]); + for CopySnapshot { relevant, sn } in snaps.iter() { + let tags = sn.tags.formatln(); + let paths = sn.paths.formatln(); + let time = sn.time.format("%Y-%m-%d %H:%M:%S").to_string(); + _ = table.add_row([ + &sn.id.to_string(), + &time, + &sn.hostname, + &sn.label, + &tags, + &paths, + &(if *relevant { "to copy" } else { "existing" }).to_string(), + ]); + } + println!("{table}"); + + let count = snaps.iter().filter(|sn| sn.relevant).count(); + if count > 0 { + if config.global.dry_run { + info!("would have copied {count} snapshots."); } else { - info!("nothing to copy."); + repo.copy( + &target_repo.to_indexed_ids()?, + snaps + .iter() + .filter_map(|CopySnapshot { relevant, sn }| relevant.then_some(sn)), + )?; } + } else { + info!("nothing to copy."); } Ok(()) } diff --git a/src/commands/diff.rs b/src/commands/diff.rs index a802de947..5333ba9c9 100644 --- a/src/commands/diff.rs +++ b/src/commands/diff.rs @@ -1,17 +1,22 @@ //! `diff` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliIndexedRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; +use clap::ValueHint; +use log::debug; -use std::path::{Path, PathBuf}; +use std::{ + fmt::Display, + path::{Path, PathBuf}, +}; use anyhow::{bail, Context, Result}; use rustic_core::{ - repofile::{BlobType, Node, NodeType}, + repofile::{Node, NodeType}, IndexedFull, LocalDestination, LocalSource, LocalSourceFilterOptions, LocalSourceSaveOptions, - LsOptions, ReadSourceEntry, Repository, RusticResult, + LsOptions, ReadSource, ReadSourceEntry, Repository, RusticResult, }; /// `diff` subcommand @@ -22,7 +27,7 @@ pub(crate) struct DiffCmd { snap1: String, /// New snapshot/path or local path [default for PATH2: PATH1] - #[clap(value_name = "SNAPSHOT2[:PATH2]|PATH2")] + #[clap(value_name = "SNAPSHOT2[:PATH2]|PATH2", value_hint = ValueHint::AnyPath)] snap2: String, /// show differences in metadata @@ -33,6 +38,10 @@ pub(crate) struct DiffCmd { #[clap(long)] no_content: bool, + /// only show differences for identical files, this can be used for a bitrot test on the local path + #[clap(long, conflicts_with = "no_content")] + only_identical: bool, + /// Ignore options #[clap(flatten)] ignore_opts: LocalSourceFilterOptions, @@ -40,7 +49,11 @@ pub(crate) struct DiffCmd { impl Runnable for DiffCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -48,11 +61,9 @@ impl Runnable for DiffCmd { } impl DiffCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed()?; - let (id1, path1) = arg_to_snap_path(&self.snap1, ""); let (id2, path2) = arg_to_snap_path(&self.snap2, path1); @@ -92,6 +103,7 @@ impl DiffCmd { &self.ignore_opts, &[&path2], )? + .entries() .map(|item| -> RusticResult<_> { let ReadSourceEntry { path, node, .. } = item?; let path = if is_dir { @@ -104,13 +116,21 @@ impl DiffCmd { Ok((path, node)) }); - diff( - repo.ls(&node1, &LsOptions::default())?, - src, - self.no_content, - |path, node1, _node2| identical_content_local(&local, &repo, path, node1), - self.metadata, - )?; + if self.only_identical { + diff_identical( + repo.ls(&node1, &LsOptions::default())?, + src, + |path, node1, _node2| identical_content_local(&local, &repo, path, node1), + )?; + } else { + diff( + repo.ls(&node1, &LsOptions::default())?, + src, + self.no_content, + |path, node1, _node2| identical_content_local(&local, &repo, path, node1), + self.metadata, + )?; + } } (None, _) => { bail!("cannot use local path as first argument"); @@ -133,6 +153,7 @@ impl DiffCmd { /// A tuple of the snapshot id and the path fn arg_to_snap_path<'a>(arg: &'a str, default_path: &'a str) -> (Option<&'a str>, &'a str) { match arg.split_once(':') { + Some(("local", path)) => (None, path), Some((id, path)) => (Some(id), path), None => { if arg.contains('/') { @@ -174,7 +195,7 @@ fn identical_content_local( }; for id in node.content.iter().flatten() { - let ie = repo.get_index_entry(BlobType::Data, id)?; + let ie = repo.get_index_entry(id)?; let length = ie.data_length(); if !id.blob_matches_reader(length as usize, &mut open_file) { return Ok(false); @@ -183,6 +204,102 @@ fn identical_content_local( Ok(true) } +/// Statistics about the differences listed with the [`DiffCmd`] command +#[derive(Default)] +struct DiffStatistics { + files_added: usize, + files_removed: usize, + files_changed: usize, + directories_added: usize, + directories_removed: usize, + others_added: usize, + others_removed: usize, + node_type_changed: usize, + metadata_changed: usize, + symlink_added: usize, + symlink_removed: usize, + symlink_changed: usize, +} + +impl DiffStatistics { + fn removed_node(&mut self, node_type: &NodeType) { + match node_type { + NodeType::File => self.files_removed += 1, + NodeType::Dir => self.directories_removed += 1, + NodeType::Symlink { .. } => self.symlink_removed += 1, + _ => self.others_removed += 1, + } + } + + fn added_node(&mut self, node_type: &NodeType) { + match node_type { + NodeType::File => self.files_added += 1, + NodeType::Dir => self.directories_added += 1, + NodeType::Symlink { .. } => self.symlink_added += 1, + _ => self.others_added += 1, + } + } + + fn changed_file(&mut self) { + self.files_changed += 1; + } + + fn changed_node_type(&mut self) { + self.node_type_changed += 1; + } + + fn changed_metadata(&mut self) { + self.metadata_changed += 1; + } + + fn changed_symlink(&mut self) { + self.symlink_changed += 1; + } +} + +impl Display for DiffStatistics { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!( + "Files :\t{} new,\t{} removed,\t{} changed\n", + self.files_added, self.files_removed, self.files_changed + ))?; + // symlink + if self.symlink_added != 0 || self.symlink_removed != 0 || self.symlink_changed != 0 { + f.write_fmt(format_args!( + "Symlinks:\t{} new,\t{} removed,\t{} changed\n", + self.symlink_added, self.symlink_removed, self.symlink_changed + ))?; + } + f.write_fmt(format_args!( + "Dirs :\t{} new,\t{} removed\n", + self.directories_added, self.directories_removed + ))?; + if self.others_added != 0 || self.others_removed != 0 { + f.write_fmt(format_args!( + "Others :\t{} new,\t{} removed\n", + self.others_added, self.others_removed + ))?; + } + + // node type + if self.node_type_changed != 0 { + f.write_fmt(format_args!( + "NodeType:\t{} changed\n", + self.node_type_changed + ))?; + } + + // metadata + if self.metadata_changed != 0 { + f.write_fmt(format_args!( + "Metadata:\t{} changed\n", + self.metadata_changed + ))?; + } + Ok(()) + } +} + /// Compare two streams of nodes and print the differences /// /// # Arguments @@ -206,40 +323,59 @@ fn diff( let mut item1 = tree_streamer1.next().transpose()?; let mut item2 = tree_streamer2.next().transpose()?; + let mut diff_statistics = DiffStatistics::default(); + loop { match (&item1, &item2) { (None, None) => break, (Some(i1), None) => { println!("- {:?}", i1.0); + diff_statistics.removed_node(&i1.1.node_type); item1 = tree_streamer1.next().transpose()?; } (None, Some(i2)) => { println!("+ {:?}", i2.0); + diff_statistics.added_node(&i2.1.node_type); item2 = tree_streamer2.next().transpose()?; } (Some(i1), Some(i2)) if i1.0 < i2.0 => { println!("- {:?}", i1.0); + diff_statistics.removed_node(&i1.1.node_type); item1 = tree_streamer1.next().transpose()?; } (Some(i1), Some(i2)) if i1.0 > i2.0 => { println!("+ {:?}", i2.0); + diff_statistics.added_node(&i2.1.node_type); item2 = tree_streamer2.next().transpose()?; } (Some(i1), Some(i2)) => { let path = &i1.0; let node1 = &i1.1; let node2 = &i2.1; + + let are_both_symlink = matches!(&node1.node_type, NodeType::Symlink { .. }) + && matches!(&node2.node_type, NodeType::Symlink { .. }); match &node1.node_type { - tpe if tpe != &node2.node_type => println!("T {path:?}"), // type was changed + // if node1.node_type != node2.node_type, they could be different symlinks, + // for this reason we check: + // that their type is different AND that they are not both symlinks + tpe if tpe != &node2.node_type && !are_both_symlink => { + // type was changed + println!("T {path:?}"); + diff_statistics.changed_node_type(); + } NodeType::File if !no_content && !file_identical(path, node1, node2)? => { println!("M {path:?}"); + diff_statistics.changed_file(); } NodeType::File if metadata && node1.meta != node2.meta => { println!("U {path:?}"); + diff_statistics.changed_metadata(); } NodeType::Symlink { .. } => { - if node1.node_type.to_link() != node1.node_type.to_link() { + if node1.node_type.to_link() != node2.node_type.to_link() { println!("U {path:?}"); + diff_statistics.changed_symlink(); } } _ => {} // no difference to show @@ -249,6 +385,65 @@ fn diff( } } } + println!("{diff_statistics}"); + Ok(()) +} + +fn diff_identical( + mut tree_streamer1: impl Iterator>, + mut tree_streamer2: impl Iterator>, + file_identical: impl Fn(&Path, &Node, &Node) -> Result, +) -> Result<()> { + let mut item1 = tree_streamer1.next().transpose()?; + let mut item2 = tree_streamer2.next().transpose()?; + let mut checked: usize = 0; + + loop { + match (&item1, &item2) { + (None, None) => break, + (Some(i1), None) => { + let path = &i1.0; + debug!("not checking {}: not present in target", path.display()); + item1 = tree_streamer1.next().transpose()?; + } + (None, Some(i2)) => { + let path = &i2.0; + debug!("not checking {}: not present in source", path.display()); + item2 = tree_streamer2.next().transpose()?; + } + (Some(i1), Some(i2)) if i1.0 < i2.0 => { + let path = &i1.0; + debug!("not checking {}: not present in target", path.display()); + item1 = tree_streamer1.next().transpose()?; + } + (Some(i1), Some(i2)) if i1.0 > i2.0 => { + let path = &i2.0; + debug!("not checking {}: not present in source", path.display()); + item2 = tree_streamer2.next().transpose()?; + } + (Some(i1), Some(i2)) => { + let path = &i1.0; + let node1 = &i1.1; + let node2 = &i2.1; + + if matches!(&node1.node_type, NodeType::File) + && matches!(&node2.node_type, NodeType::File) + && node1.meta == node2.meta + { + debug!("checking {}", path.display()); + checked += 1; + if !file_identical(path, node1, node2)? { + println!("M {path:?}"); + } + } else { + debug!("not checking {}: metadata changed", path.display()); + } + item1 = tree_streamer1.next().transpose()?; + item2 = tree_streamer2.next().transpose()?; + } + } + } + println!("checked {checked} files."); Ok(()) } diff --git a/src/commands/docs.rs b/src/commands/docs.rs new file mode 100644 index 000000000..03460ce9e --- /dev/null +++ b/src/commands/docs.rs @@ -0,0 +1,61 @@ +//! `docs` subcommand + +use abscissa_core::{status_err, Application, Command, Runnable, Shutdown}; +use anyhow::Result; +use clap::Subcommand; + +use crate::{ + application::constants::{RUSTIC_CONFIG_DOCS_URL, RUSTIC_DEV_DOCS_URL, RUSTIC_DOCS_URL}, + RUSTIC_APP, +}; + +#[derive(Command, Debug, Clone, Copy, Default, Subcommand, Runnable)] +enum DocsTypeSubcommand { + #[default] + /// Show the user documentation + User, + /// Show the development documentation + Dev, + /// Show the configuration documentation + Config, +} + +/// Opens the documentation in the default browser. +#[derive(Clone, Command, Default, Debug, clap::Parser)] +pub struct DocsCmd { + #[clap(subcommand)] + cmd: Option, +} + +impl Runnable for DocsCmd { + fn run(&self) { + if let Err(err) = self.inner_run() { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl DocsCmd { + fn inner_run(&self) -> Result<()> { + let user_string = match self.cmd { + // Default to user docs if no subcommand is provided + Some(DocsTypeSubcommand::User) | None => { + open::that(RUSTIC_DOCS_URL)?; + format!("Opening the user documentation at {RUSTIC_DOCS_URL}") + } + Some(DocsTypeSubcommand::Dev) => { + open::that(RUSTIC_DEV_DOCS_URL)?; + format!("Opening the development documentation at {RUSTIC_DEV_DOCS_URL}") + } + Some(DocsTypeSubcommand::Config) => { + open::that(RUSTIC_CONFIG_DOCS_URL)?; + format!("Opening the configuration documentation at {RUSTIC_CONFIG_DOCS_URL}") + } + }; + + println!("{user_string}"); + + Ok(()) + } +} diff --git a/src/commands/dump.rs b/src/commands/dump.rs index a90cc996e..9476f4919 100644 --- a/src/commands/dump.rs +++ b/src/commands/dump.rs @@ -1,9 +1,18 @@ //! `dump` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use std::io::{Read, Write}; + +use crate::{repository::CliIndexedRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; +use log::warn; +use rustic_core::{ + repofile::{Node, NodeType}, + vfs::OpenFile, + LsOptions, +}; +use tar::{Builder, EntryType, Header}; /// `dump` subcommand #[derive(clap::Parser, Command, Debug)] @@ -11,11 +20,19 @@ pub(crate) struct DumpCmd { /// file from snapshot to dump #[clap(value_name = "SNAPSHOT[:PATH]")] snap: String, + + /// Listing options + #[clap(flatten)] + ls_opts: LsOptions, } impl Runnable for DumpCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -23,16 +40,116 @@ impl Runnable for DumpCmd { } impl DumpCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed()?; let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; let mut stdout = std::io::stdout(); - repo.dump(&node, &mut stdout)?; + if node.is_file() { + repo.dump(&node, &mut stdout)?; + } else { + dump_tar(&repo, &node, &mut stdout, &self.ls_opts)?; + } Ok(()) } } + +fn dump_tar( + repo: &CliIndexedRepo, + node: &Node, + w: &mut impl Write, + ls_opts: &LsOptions, +) -> Result<()> { + let mut ar = Builder::new(w); + for item in repo.ls(node, ls_opts)? { + let (path, node) = item?; + let mut header = Header::new_gnu(); + + let entry_type = match &node.node_type { + NodeType::File => EntryType::Regular, + NodeType::Dir => EntryType::Directory, + NodeType::Symlink { .. } => EntryType::Symlink, + NodeType::Dev { .. } => EntryType::Block, + NodeType::Chardev { .. } => EntryType::Char, + NodeType::Fifo => EntryType::Fifo, + NodeType::Socket => { + warn!( + "socket is not supported. Adding {} as empty file", + path.display() + ); + EntryType::Regular + } + }; + header.set_entry_type(entry_type); + header.set_size(node.meta.size); + if let Some(mode) = node.meta.mode { + // TODO: this is some go-mapped mode, but lower bits are the standard unix mode bits -> is this ok? + header.set_mode(mode); + } + if let Some(uid) = node.meta.uid { + header.set_uid(uid.into()); + } + if let Some(gid) = node.meta.gid { + header.set_uid(gid.into()); + } + if let Some(user) = &node.meta.user { + header.set_username(user)?; + } + if let Some(group) = &node.meta.group { + header.set_groupname(group)?; + } + if let Some(mtime) = node.meta.mtime { + header.set_mtime(mtime.timestamp().try_into().unwrap_or_default()); + } + + // handle special files + if node.is_symlink() { + header.set_link_name(node.node_type.to_link())?; + } + match node.node_type { + NodeType::Dev { device } | NodeType::Chardev { device } => { + header.set_device_minor(device as u32)?; + header.set_device_major((device << 32) as u32)?; + } + _ => {} + } + + if node.is_file() { + // write file content if this is a regular file + let open_file = OpenFileReader { + repo, + open_file: repo.open_file(&node)?, + offset: 0, + }; + ar.append_data(&mut header, path, open_file)?; + } else { + let data: &[u8] = &[]; + ar.append_data(&mut header, path, data)?; + } + } + // finish writing + _ = ar.into_inner()?; + Ok(()) +} + +struct OpenFileReader<'a> { + repo: &'a CliIndexedRepo, + open_file: OpenFile, + offset: usize, +} + +impl<'a> Read for OpenFileReader<'a> { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let data = self + .repo + .read_file_at(&self.open_file, self.offset, buf.len()) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?; + let n = data.len(); + buf[..n].copy_from_slice(&data); + self.offset += n; + Ok(n) + } +} diff --git a/src/commands/find.rs b/src/commands/find.rs new file mode 100644 index 000000000..942efdfe5 --- /dev/null +++ b/src/commands/find.rs @@ -0,0 +1,155 @@ +//! `find` subcommand + +use std::path::{Path, PathBuf}; + +use crate::{repository::CliIndexedRepo, status_err, Application, RUSTIC_APP}; + +use abscissa_core::{Command, Runnable, Shutdown}; +use anyhow::Result; +use clap::ValueHint; +use globset::{Glob, GlobBuilder, GlobSetBuilder}; +use itertools::Itertools; + +use rustic_core::{ + repofile::{Node, SnapshotFile}, + FindMatches, FindNode, SnapshotGroupCriterion, +}; + +use super::ls::print_node; + +/// `find` subcommand +#[derive(clap::Parser, Command, Debug)] +pub(crate) struct FindCmd { + /// pattern to find (can be specified multiple times) + #[clap(long, value_name = "PATTERN", conflicts_with = "path")] + glob: Vec, + + /// pattern to find case-insensitive (can be specified multiple times) + #[clap(long, value_name = "PATTERN", conflicts_with = "path")] + iglob: Vec, + + /// exact path to find + #[clap(long, value_name = "PATH", value_hint = ValueHint::AnyPath)] + path: Option, + + /// Snapshots to search in. If none is given, use filter options to filter from all snapshots + #[clap(value_name = "ID")] + ids: Vec, + + /// Group snapshots by any combination of host,label,paths,tags + #[clap( + long, + short = 'g', + value_name = "CRITERION", + default_value = "host,label,paths" + )] + group_by: SnapshotGroupCriterion, + + /// Show all snapshots instead of summarizing snapshots with identical search results + #[clap(long)] + all: bool, + + /// Also show snapshots which don't contain a search result. + #[clap(long)] + show_misses: bool, + + /// Show uid/gid instead of user/group + #[clap(long, long("numeric-uid-gid"))] + numeric_id: bool, +} + +impl Runnable for FindCmd { + fn run(&self) { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl FindCmd { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { + let config = RUSTIC_APP.config(); + + let groups = repo.get_snapshot_group(&self.ids, self.group_by, |sn| { + config.snapshot_filter.matches(sn) + })?; + for (group, mut snapshots) in groups { + snapshots.sort_unstable(); + if !group.is_empty() { + println!("\nsearching in snapshots group {group}..."); + } + let ids = snapshots.iter().map(|sn| sn.tree); + if let Some(path) = &self.path { + let FindNode { nodes, matches } = repo.find_nodes_from_path(ids, path)?; + for (idx, g) in &matches + .iter() + .zip(snapshots.iter()) + .chunk_by(|(idx, _)| *idx) + { + self.print_identical_snapshots(idx.iter(), g.into_iter().map(|(_, sn)| sn)); + if let Some(idx) = idx { + print_node(&nodes[*idx], path, self.numeric_id); + } + } + } else { + let mut builder = GlobSetBuilder::new(); + for glob in &self.glob { + _ = builder.add(Glob::new(glob)?); + } + for glob in &self.iglob { + _ = builder.add(GlobBuilder::new(glob).case_insensitive(true).build()?); + } + let globset = builder.build()?; + let matches = |path: &Path, _: &Node| { + globset.is_match(path) || path.file_name().is_some_and(|f| globset.is_match(f)) + }; + let FindMatches { + paths, + nodes, + matches, + } = repo.find_matching_nodes(ids, &matches)?; + for (idx, g) in &matches + .iter() + .zip(snapshots.iter()) + .chunk_by(|(idx, _)| *idx) + { + self.print_identical_snapshots(idx.iter(), g.into_iter().map(|(_, sn)| sn)); + for (path_idx, node_idx) in idx { + print_node(&nodes[*node_idx], &paths[*path_idx], self.numeric_id); + } + } + } + } + Ok(()) + } + + fn print_identical_snapshots<'a>( + &self, + mut idx: impl Iterator, + mut g: impl Iterator, + ) { + let empty_result = idx.next().is_none(); + let not = if empty_result { "not " } else { "" }; + if self.show_misses || !empty_result { + if self.all { + for sn in g { + let time = sn.time.format("%Y-%m-%d %H:%M:%S"); + println!("{not}found in {} from {time}", sn.id); + } + } else { + let sn = g.next().unwrap(); + let count = g.count(); + let time = sn.time.format("%Y-%m-%d %H:%M:%S"); + match count { + 0 => println!("{not}found in {} from {time}", sn.id), + count => println!("{not}found in {} from {time} (+{count})", sn.id), + }; + } + } + } +} diff --git a/src/commands/forget.rs b/src/commands/forget.rs index f54724179..f95bdb473 100644 --- a/src/commands/forget.rs +++ b/src/commands/forget.rs @@ -1,16 +1,15 @@ //! `forget` subcommand -use crate::{ - commands::open_repository, helpers::table_with_titles, status_err, Application, RusticConfig, - RUSTIC_APP, -}; +use crate::repository::CliOpenRepo; +use crate::{helpers::table_with_titles, status_err, Application, RusticConfig, RUSTIC_APP}; use abscissa_core::{config::Override, Shutdown}; use abscissa_core::{Command, FrameworkError, Runnable}; use anyhow::Result; -use merge::Merge; -use serde::Deserialize; +use chrono::Local; +use conflate::Merge; +use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; use crate::{commands::prune::PruneCmd, filtering::SnapshotFilter}; @@ -63,17 +62,18 @@ impl Override for ForgetCmd { /// Forget options #[serde_as] -#[derive(Clone, Default, Debug, clap::Parser, Deserialize, Merge)] +#[derive(Clone, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] #[serde(default, rename_all = "kebab-case")] pub struct ForgetOptions { /// Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths") #[clap(long, short = 'g', value_name = "CRITERION")] #[serde_as(as = "Option")] + #[merge(strategy=conflate::option::overwrite_none)] group_by: Option, /// Also prune the repository #[clap(long)] - #[merge(strategy = merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] prune: bool, /// Snapshot filter options @@ -89,7 +89,11 @@ pub struct ForgetOptions { impl Runnable for ForgetCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -97,9 +101,11 @@ impl Runnable for ForgetCmd { } impl ForgetCmd { - fn inner_run(&self) -> Result<()> { + /// be careful about self vs `RUSTIC_APP.config()` usage + /// only the `RUSTIC_APP.config()` involves the TOML and ENV merged configurations + /// see + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; let group_by = config.forget.group_by.unwrap_or_default(); @@ -108,15 +114,26 @@ impl ForgetCmd { config.forget.filter.matches(sn) })? } else { + let now = Local::now(); let item = ForgetGroup { group: SnapshotGroup::default(), snapshots: repo .get_snapshots(&self.ids)? .into_iter() - .map(|sn| ForgetSnapshot { - snapshot: sn, - keep: false, - reasons: vec!["id argument".to_string()], + .map(|sn| { + if sn.must_keep(now) { + ForgetSnapshot { + snapshot: sn, + keep: true, + reasons: vec!["snapshot".to_string()], + } + } else { + ForgetSnapshot { + snapshot: sn, + keep: false, + reasons: vec!["id argument".to_string()], + } + } }) .collect(), }; @@ -143,7 +160,7 @@ impl ForgetCmd { (_, _, true) => {} } - if self.config.prune { + if config.forget.prune { let mut prune_opts = self.prune_opts.clone(); prune_opts.opts.ignore_snaps = forget_snaps; prune_opts.run(); diff --git a/src/commands/init.rs b/src/commands/init.rs index d770e62db..6bfa9bb19 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -2,11 +2,10 @@ use abscissa_core::{status_err, Command, Runnable, Shutdown}; use anyhow::{bail, Result}; - -use crate::{Application, RUSTIC_APP}; - use dialoguer::Password; +use crate::{repository::CliRepo, Application, RUSTIC_APP}; + use rustic_core::{ConfigOptions, KeyOptions, OpenStatus, Repository}; /// `init` subcommand @@ -23,7 +22,11 @@ pub(crate) struct InitCmd { impl Runnable for InitCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -31,12 +34,9 @@ impl Runnable for InitCmd { } impl InitCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let po = config.global.progress_options; - let repo = Repository::new_with_progress(&config.repository, po)?; - // Note: This is again checked in repo.init_with_password(), however we want to inform // users before they are prompted to enter a password if repo.config_id()?.is_some() { @@ -51,7 +51,7 @@ impl InitCmd { ); } - let _ = init(repo, &self.key_opts, &self.config_opts)?; + let _ = init(repo.0, &self.key_opts, &self.config_opts)?; Ok(()) } } @@ -69,7 +69,7 @@ impl InitCmd { /// * [`RepositoryErrorKind::OpeningPasswordFileFailed`] - If opening the password file failed /// * [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`] - If reading the password failed /// * [`RepositoryErrorKind::FromSplitError`] - If splitting the password command failed -/// * [`RepositoryErrorKind::PasswordCommandParsingFailed`] - If parsing the password command failed +/// * [`RepositoryErrorKind::PasswordCommandExecutionFailed`] - If executing the password command failed /// * [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`] - If reading the password from the command failed /// /// # Returns @@ -79,13 +79,18 @@ impl InitCmd { /// [`RepositoryErrorKind::OpeningPasswordFileFailed`]: rustic_core::error::RepositoryErrorKind::OpeningPasswordFileFailed /// [`RepositoryErrorKind::ReadingPasswordFromReaderFailed`]: rustic_core::error::RepositoryErrorKind::ReadingPasswordFromReaderFailed /// [`RepositoryErrorKind::FromSplitError`]: rustic_core::error::RepositoryErrorKind::FromSplitError -/// [`RepositoryErrorKind::PasswordCommandParsingFailed`]: rustic_core::error::RepositoryErrorKind::PasswordCommandParsingFailed +/// [`RepositoryErrorKind::PasswordCommandExecutionFailed`]: rustic_core::error::RepositoryErrorKind::PasswordCommandExecutionFailed /// [`RepositoryErrorKind::ReadingPasswordFromCommandFailed`]: rustic_core::error::RepositoryErrorKind::ReadingPasswordFromCommandFailed pub(crate) fn init( repo: Repository, key_opts: &KeyOptions, config_opts: &ConfigOptions, ) -> Result> { + let pass = init_password(&repo)?; + Ok(repo.init_with_password(&pass, key_opts, config_opts)?) +} + +pub(crate) fn init_password(repo: &Repository) -> Result { let pass = repo.password()?.unwrap_or_else(|| { match Password::new() .with_prompt("enter password for new key") @@ -101,5 +106,5 @@ pub(crate) fn init( } }); - Ok(repo.init_with_password(&pass, key_opts, config_opts)?) + Ok(pass) } diff --git a/src/commands/key.rs b/src/commands/key.rs index f00cede3e..9670a378a 100644 --- a/src/commands/key.rs +++ b/src/commands/key.rs @@ -1,6 +1,6 @@ //! `key` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP}; use std::path::PathBuf; @@ -9,7 +9,7 @@ use anyhow::Result; use dialoguer::Password; use log::info; -use rustic_core::{KeyOptions, Repository, RepositoryOptions}; +use rustic_core::{CommandInput, KeyOptions, RepositoryOptions}; /// `key` subcommand #[derive(clap::Parser, Command, Debug)] @@ -27,10 +27,18 @@ enum KeySubCmd { #[derive(clap::Parser, Debug)] pub(crate) struct AddCmd { + /// New password + #[clap(long)] + pub(crate) new_password: Option, + /// File from which to read the new password #[clap(long)] pub(crate) new_password_file: Option, + /// Command to get the new password from + #[clap(long)] + pub(crate) new_password_command: Option, + /// Key options #[clap(flatten)] pub(crate) key_opts: KeyOptions, @@ -44,7 +52,11 @@ impl Runnable for KeyCmd { impl Runnable for AddCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -52,21 +64,15 @@ impl Runnable for AddCmd { } impl AddCmd { - fn inner_run(&self) -> Result<()> { - let config = RUSTIC_APP.config(); - - let repo = open_repository(&config)?; - - // create new "artificial" repo using the given password options - let repo_opts = RepositoryOptions { - password_file: self.new_password_file.clone(), - repository: Some(String::new()), // fake repository to make Repository::new() not bail - ..Default::default() - }; - let repo_newpass = Repository::new(&repo_opts)?; - - let pass = repo_newpass - .password() + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { + // create new Repository options which just contain password information + let mut pass_opts = RepositoryOptions::default(); + pass_opts.password = self.new_password.clone(); + pass_opts.password_file = self.new_password_file.clone(); + pass_opts.password_command = self.new_password_command.clone(); + + let pass = pass_opts + .evaluate_password() .map_err(|err| err.into()) .transpose() .unwrap_or_else(|| -> Result<_> { diff --git a/src/commands/list.rs b/src/commands/list.rs index 4605bd2d9..79ddc728a 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -1,24 +1,29 @@ //! `list` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use std::num::NonZero; -use abscissa_core::{Command, Runnable, Shutdown}; +use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP}; +use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::{bail, Result}; -use rustic_core::repofile::{FileType, IndexFile}; +use rustic_core::repofile::{IndexFile, IndexId, KeyId, PackId, SnapshotId}; /// `list` subcommand #[derive(clap::Parser, Command, Debug)] pub(crate) struct ListCmd { /// File types to list - #[clap(value_parser=["blobs", "index", "packs", "snapshots", "keys"])] + #[clap(value_parser=["blobs", "indexpacks", "indexcontent", "index", "packs", "snapshots", "keys"])] tpe: String, } impl Runnable for ListCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -26,37 +31,73 @@ impl Runnable for ListCmd { } impl ListCmd { - fn inner_run(&self) -> Result<()> { - let config = RUSTIC_APP.config(); - - let repo = open_repository(&config)?; - - let tpe = match self.tpe.as_str() { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { + match self.tpe.as_str() { // special treatment for listing blobs: read the index and display it - "blobs" => { + "blobs" | "indexpacks" | "indexcontent" => { for item in repo.stream_files::()? { let (_, index) = item?; - index.packs.into_iter().for_each(|pack| { - for blob in pack.blobs { - println!("{:?} {:?}", blob.tpe, blob.id); + for pack in index.packs { + match self.tpe.as_str() { + "blobs" => { + for blob in pack.blobs { + println!("{:?} {:?}", blob.tpe, blob.id); + } + } + "indexcontent" => { + for blob in pack.blobs { + println!( + "{:?} {:?} {:?} {} {}", + blob.tpe, + blob.id, + pack.id, + blob.length, + blob.uncompressed_length.map_or(0, NonZero::get) + ); + } + } + "indexpacks" => println!( + "{:?} {:?} {} {}", + pack.blob_type(), + pack.id, + pack.pack_size(), + pack.time.map_or_else(String::new, |time| format!( + "{}", + time.format("%Y-%m-%d %H:%M:%S") + )) + ), + t => { + bail!("invalid type: {}", t); + } } - }); + } + } + } + "index" => { + for id in repo.list::()? { + println!("{id:?}"); + } + } + "packs" => { + for id in repo.list::()? { + println!("{id:?}"); + } + } + "snapshots" => { + for id in repo.list::()? { + println!("{id:?}"); + } + } + "keys" => { + for id in repo.list::()? { + println!("{id:?}"); } - return Ok(()); } - "index" => FileType::Index, - "packs" => FileType::Pack, - "snapshots" => FileType::Snapshot, - "keys" => FileType::Key, t => { bail!("invalid type: {}", t); } }; - for id in repo.list(tpe)? { - println!("{id:?}"); - } - Ok(()) } } diff --git a/src/commands/ls.rs b/src/commands/ls.rs index de0f4b4c4..89e442576 100644 --- a/src/commands/ls.rs +++ b/src/commands/ls.rs @@ -2,7 +2,7 @@ use std::path::Path; -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliIndexedRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; @@ -36,13 +36,21 @@ pub(crate) struct LsCmd { snap: String, /// show summary - #[clap(long, short = 's')] + #[clap(long, short = 's', conflicts_with = "json")] summary: bool, /// show long listing - #[clap(long, short = 'l')] + #[clap(long, short = 'l', conflicts_with = "json")] long: bool, + /// show listing in json + #[clap(long, conflicts_with_all = ["summary", "long"])] + json: bool, + + /// show uid/gid instead of user/group + #[clap(long, long("numeric-uid-gid"))] + numeric_id: bool, + /// Listing options #[clap(flatten)] ls_opts: LsOptions, @@ -50,7 +58,11 @@ pub(crate) struct LsCmd { impl Runnable for LsCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -61,10 +73,10 @@ impl Runnable for LsCmd { /// /// This struct is used to print a summary of the ls command. #[derive(Default)] -struct Summary { - files: usize, - size: u64, - dirs: usize, +pub struct Summary { + pub files: usize, + pub size: u64, + pub dirs: usize, } impl Summary { @@ -73,7 +85,7 @@ impl Summary { /// # Arguments /// /// * `node` - the node to update the summary with - fn update(&mut self, node: &Node) { + pub fn update(&mut self, node: &Node) { if node.is_dir() { self.dirs += 1; } @@ -84,12 +96,43 @@ impl Summary { } } +pub trait NodeLs { + fn mode_str(&self) -> String; + fn link_str(&self) -> String; +} + +impl NodeLs for Node { + fn mode_str(&self) -> String { + format!( + "{:>1}{:>9}", + match self.node_type { + NodeType::Dir => 'd', + NodeType::Symlink { .. } => 'l', + NodeType::Chardev { .. } => 'c', + NodeType::Dev { .. } => 'b', + NodeType::Fifo { .. } => 'p', + NodeType::Socket => 's', + _ => '-', + }, + self.meta + .mode + .map(parse_permissions) + .unwrap_or_else(|| "?????????".to_string()) + ) + } + fn link_str(&self) -> String { + if let NodeType::Symlink { .. } = &self.node_type { + ["->", &self.node_type.to_link().to_string_lossy()].join(" ") + } else { + String::new() + } + } +} + impl LsCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed()?; - let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; @@ -99,14 +142,29 @@ impl LsCmd { let mut summary = Summary::default(); + if self.json { + print!("["); + } + + let mut first_item = true; for item in repo.ls(&node, &ls_opts)? { let (path, node) = item?; summary.update(&node); - if self.long { - print_node(&node, &path); + if self.json { + if !first_item { + print!(","); + } + print!("{}", serde_json::to_string(&path)?); + } else if self.long { + print_node(&node, &path, self.numeric_id); } else { - println!("{path:?} "); + println!("{}", path.display()); } + first_item = false; + } + + if self.json { + println!("]"); } if self.summary { @@ -126,34 +184,28 @@ impl LsCmd { /// /// * `node` - the node to print /// * `path` - the path of the node -fn print_node(node: &Node, path: &Path) { +pub fn print_node(node: &Node, path: &Path, numeric_uid_gid: bool) { println!( - "{:>1}{:>9} {:>8} {:>8} {:>9} {:>12} {path:?} {}", - match node.node_type { - NodeType::Dir => 'd', - NodeType::Symlink { .. } => 'l', - NodeType::Chardev { .. } => 'c', - NodeType::Dev { .. } => 'b', - NodeType::Fifo { .. } => 'p', - NodeType::Socket => 's', - _ => '-', - }, - node.meta - .mode - .map(parse_permissions) - .unwrap_or_else(|| "?????????".to_string()), - node.meta.user.clone().unwrap_or_else(|| "?".to_string()), - node.meta.group.clone().unwrap_or_else(|| "?".to_string()), + "{:>10} {:>8} {:>8} {:>9} {:>17} {path:?} {}", + node.mode_str(), + if numeric_uid_gid { + node.meta.uid.map(|uid| uid.to_string()) + } else { + node.meta.user.clone() + } + .unwrap_or_else(|| "?".to_string()), + if numeric_uid_gid { + node.meta.gid.map(|uid| uid.to_string()) + } else { + node.meta.group.clone() + } + .unwrap_or_else(|| "?".to_string()), node.meta.size, node.meta .mtime - .map(|t| t.format("%_d %b %H:%M").to_string()) + .map(|t| t.format("%_d %b %Y %H:%M").to_string()) .unwrap_or_else(|| "?".to_string()), - if let NodeType::Symlink { .. } = &node.node_type { - ["->", &node.node_type.to_link().to_string_lossy()].join(" ") - } else { - String::new() - } + node.link_str(), ); } diff --git a/src/commands/merge.rs b/src/commands/merge.rs index 2ee7415f8..bb1525e03 100644 --- a/src/commands/merge.rs +++ b/src/commands/merge.rs @@ -1,6 +1,6 @@ //! `merge` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; use log::info; @@ -31,7 +31,11 @@ pub(super) struct MergeCmd { impl Runnable for MergeCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -39,9 +43,9 @@ impl Runnable for MergeCmd { } impl MergeCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed_ids()?; + let repo = repo.to_indexed_ids()?; let snapshots = if self.ids.is_empty() { repo.get_matching_snapshots(|sn| config.snapshot_filter.matches(sn))? diff --git a/src/commands/mount.rs b/src/commands/mount.rs new file mode 100644 index 000000000..8f459198a --- /dev/null +++ b/src/commands/mount.rs @@ -0,0 +1,148 @@ +//! `mount` subcommand + +// ignore markdown clippy lints as we use doc-comments to generate clap help texts +#![allow(clippy::doc_markdown)] + +mod fusefs; +use fusefs::FuseFS; + +use std::{ffi::OsStr, path::PathBuf}; + +use crate::{repository::CliIndexedRepo, status_err, Application, RusticConfig, RUSTIC_APP}; + +use abscissa_core::{config::Override, Command, FrameworkError, Runnable, Shutdown}; +use anyhow::{anyhow, Result}; +use conflate::Merge; +use fuse_mt::{mount, FuseMT}; +use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Command, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] +#[serde(default, rename_all = "kebab-case", deny_unknown_fields)] +pub struct MountCmd { + /// The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + path_template: Option, + + /// The time template to use to display times in the path template. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. [default: "%Y-%m-%d_%H-%M-%S"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + time_template: Option, + + /// Don't allow other users to access the mount point + #[clap(long)] + #[merge(strategy=conflate::bool::overwrite_false)] + no_allow_other: bool, + + /// How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + file_access: Option, + + /// The mount point to use + #[clap(value_name = "PATH")] + #[merge(strategy=conflate::option::overwrite_none)] + mountpoint: Option, + + /// Specify directly which snapshot/path to mount + #[clap(value_name = "SNAPSHOT[:PATH]")] + #[merge(strategy=conflate::option::overwrite_none)] + snapshot_path: Option, +} + +impl Override for MountCmd { + // Process the given command line options, overriding settings from + // a configuration file using explicit flags taken from command-line + // arguments. + fn override_config(&self, mut config: RusticConfig) -> Result { + let mut self_config = self.clone(); + // merge "mount" section from config file, if given + self_config.merge(config.mount); + config.mount = self_config; + Ok(config) + } +} + +impl Runnable for MountCmd { + fn run(&self) { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl MountCmd { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { + let config = RUSTIC_APP.config(); + let mountpoint = config + .mount + .mountpoint + .as_ref() + .ok_or_else(|| anyhow!("please specify a mountpoint"))?; + + let path_template = config + .mount + .path_template + .clone() + .unwrap_or_else(|| "[{hostname}]/[{label}]/{time}".to_string()); + let time_template = config + .mount + .time_template + .clone() + .unwrap_or_else(|| "%Y-%m-%d_%H-%M-%S".to_string()); + + let sn_filter = |sn: &_| config.snapshot_filter.matches(sn); + let vfs = if let Some(snap_path) = &config.mount.snapshot_path { + let node = repo.node_from_snapshot_path(snap_path, sn_filter)?; + Vfs::from_dir_node(&node) + } else { + let snapshots = repo.get_matching_snapshots(sn_filter)?; + Vfs::from_snapshots( + snapshots, + &path_template, + &time_template, + Latest::AsLink, + IdenticalSnapshot::AsLink, + )? + }; + + let name_opt = format!("fsname=rusticfs:{}", repo.config().id); + let mut options = vec![ + OsStr::new("-o"), + OsStr::new(&name_opt), + OsStr::new("-o"), + OsStr::new("kernel_cache"), + ]; + + if !config.mount.no_allow_other { + options.extend_from_slice(&[ + OsStr::new("-o"), + OsStr::new("allow_other"), + OsStr::new("-o"), + OsStr::new("default_permissions"), + ]); + } + + let file_access = config.mount.file_access.as_ref().map_or_else( + || { + if repo.config().is_hot == Some(true) { + Ok(FilePolicy::Forbidden) + } else { + Ok(FilePolicy::Read) + } + }, + |s| s.parse(), + )?; + + let fs = FuseMT::new(FuseFS::new(repo, vfs, file_access), 1); + mount(fs, mountpoint, &options)?; + + Ok(()) + } +} diff --git a/src/commands/mount/fusefs.rs b/src/commands/mount/fusefs.rs new file mode 100644 index 000000000..3fc143dd3 --- /dev/null +++ b/src/commands/mount/fusefs.rs @@ -0,0 +1,238 @@ +#[cfg(not(windows))] +use std::os::unix::prelude::OsStrExt; +use std::{ + collections::BTreeMap, + ffi::{CString, OsStr}, + path::Path, + sync::RwLock, + time::{Duration, SystemTime}, +}; + +use rustic_core::{ + repofile::{Node, NodeType}, + vfs::{FilePolicy, OpenFile, Vfs}, + IndexedFull, Repository, +}; + +use fuse_mt::{ + CallbackResult, DirectoryEntry, FileAttr, FileType, FilesystemMT, RequestInfo, ResultData, + ResultEmpty, ResultEntry, ResultOpen, ResultReaddir, ResultSlice, ResultXattr, Xattr, +}; +use itertools::Itertools; + +pub struct FuseFS { + repo: Repository, + vfs: Vfs, + open_files: RwLock>, + now: SystemTime, + file_policy: FilePolicy, +} + +impl FuseFS { + pub(crate) fn new(repo: Repository, vfs: Vfs, file_policy: FilePolicy) -> Self { + let open_files = RwLock::new(BTreeMap::new()); + + Self { + repo, + vfs, + open_files, + now: SystemTime::now(), + file_policy, + } + } + + fn node_from_path(&self, path: &Path) -> Result { + self.vfs + .node_from_path(&self.repo, path) + .map_err(|_| libc::ENOENT) + } + + fn dir_entries_from_path(&self, path: &Path) -> Result, i32> { + self.vfs + .dir_entries_from_path(&self.repo, path) + .map_err(|_| libc::ENOENT) + } +} + +fn node_to_filetype(node: &Node) -> FileType { + match node.node_type { + NodeType::File => FileType::RegularFile, + NodeType::Dir => FileType::Directory, + NodeType::Symlink { .. } => FileType::Symlink, + NodeType::Chardev { .. } => FileType::CharDevice, + NodeType::Dev { .. } => FileType::BlockDevice, + NodeType::Fifo => FileType::NamedPipe, + NodeType::Socket => FileType::Socket, + } +} + +fn node_type_to_rdev(tpe: &NodeType) -> u32 { + u32::try_from(match tpe { + NodeType::Dev { device } | NodeType::Chardev { device } => *device, + _ => 0, + }) + .unwrap() +} + +fn node_to_linktarget(node: &Node) -> Option<&OsStr> { + if node.is_symlink() { + Some(node.node_type.to_link().as_os_str()) + } else { + None + } +} + +fn node_to_file_attr(node: &Node, now: SystemTime) -> FileAttr { + FileAttr { + // Size in bytes + size: node.meta.size, + // Size in blocks + blocks: 0, + // Time of last access + atime: node.meta.atime.map(SystemTime::from).unwrap_or(now), + // Time of last modification + mtime: node.meta.mtime.map(SystemTime::from).unwrap_or(now), + // Time of last metadata change + ctime: node.meta.ctime.map(SystemTime::from).unwrap_or(now), + // Time of creation (macOS only) + crtime: now, + // Kind of file (directory, file, pipe, etc.) + kind: node_to_filetype(node), + // Permissions + perm: node.meta.mode.unwrap_or(0o755) as u16, + // Number of hard links + nlink: node.meta.links.try_into().unwrap_or(1), + // User ID + uid: node.meta.uid.unwrap_or(0), + // Group ID + gid: node.meta.gid.unwrap_or(0), + // Device ID (if special file) + rdev: node_type_to_rdev(&node.node_type), + // Flags (macOS only; see chflags(2)) + flags: 0, + } +} + +impl FilesystemMT for FuseFS { + fn getattr(&self, _req: RequestInfo, path: &Path, _fh: Option) -> ResultEntry { + let node = self.node_from_path(path)?; + Ok((Duration::from_secs(1), node_to_file_attr(&node, self.now))) + } + + #[cfg(not(windows))] + fn readlink(&self, _req: RequestInfo, path: &Path) -> ResultData { + let target = node_to_linktarget(&self.node_from_path(path)?) + .ok_or(libc::ENOSYS)? + .as_bytes() + .to_vec(); + + Ok(target) + } + + fn open(&self, _req: RequestInfo, path: &Path, _flags: u32) -> ResultOpen { + if matches!(self.file_policy, FilePolicy::Forbidden) { + return Err(libc::ENOTSUP); + } + let node = self.node_from_path(path)?; + let open = self.repo.open_file(&node).map_err(|_| libc::ENOSYS)?; + let fh = { + let mut open_files = self.open_files.write().unwrap(); + let fh = open_files.last_key_value().map_or(0, |(fh, _)| *fh + 1); + _ = open_files.insert(fh, open); + fh + }; + Ok((fh, 0)) + } + + fn release( + &self, + _req: RequestInfo, + _path: &Path, + fh: u64, + _flags: u32, + _lock_owner: u64, + _flush: bool, + ) -> ResultEmpty { + _ = self.open_files.write().unwrap().remove(&fh); + Ok(()) + } + + fn read( + &self, + _req: RequestInfo, + _path: &Path, + fh: u64, + offset: u64, + size: u32, + + callback: impl FnOnce(ResultSlice<'_>) -> CallbackResult, + ) -> CallbackResult { + if let Some(open_file) = self.open_files.read().unwrap().get(&fh) { + if let Ok(data) = + self.repo + .read_file_at(open_file, offset.try_into().unwrap(), size as usize) + { + return callback(Ok(&data)); + } + } + callback(Err(libc::ENOSYS)) + } + + fn opendir(&self, _req: RequestInfo, _path: &Path, _flags: u32) -> ResultOpen { + Ok((0, 0)) + } + + fn readdir(&self, _req: RequestInfo, path: &Path, _fh: u64) -> ResultReaddir { + let nodes = self.dir_entries_from_path(path)?; + + let result = nodes + .into_iter() + .map(|node| DirectoryEntry { + name: node.name(), + kind: node_to_filetype(&node), + }) + .collect(); + Ok(result) + } + + fn releasedir(&self, _req: RequestInfo, _path: &Path, _fh: u64, _flags: u32) -> ResultEmpty { + Ok(()) + } + + fn listxattr(&self, _req: RequestInfo, path: &Path, size: u32) -> ResultXattr { + let node = self.node_from_path(path)?; + let xattrs = node + .meta + .extended_attributes + .into_iter() + // convert into null-terminated [u8] + .map(|a| CString::new(a.name).unwrap().into_bytes_with_nul()) + .concat(); + + if size == 0 { + Ok(Xattr::Size(u32::try_from(xattrs.len()).unwrap())) + } else { + Ok(Xattr::Data(xattrs)) + } + } + + fn getxattr(&self, _req: RequestInfo, path: &Path, name: &OsStr, size: u32) -> ResultXattr { + let node = self.node_from_path(path)?; + match node + .meta + .extended_attributes + .into_iter() + .find(|a| name == OsStr::new(&a.name)) + { + None => Err(libc::ENOSYS), + Some(attr) => { + let value = attr.value.unwrap_or_default(); + if size == 0 { + Ok(Xattr::Size(u32::try_from(value.len()).unwrap())) + } else { + Ok(Xattr::Data(value)) + } + } + } + } +} diff --git a/src/commands/prune.rs b/src/commands/prune.rs index 7e4353974..5fcc6f7bc 100644 --- a/src/commands/prune.rs +++ b/src/commands/prune.rs @@ -1,7 +1,7 @@ //! `prune` subcommand use crate::{ - commands::open_repository, helpers::bytes_size_to_string, status_err, Application, RUSTIC_APP, + helpers::bytes_size_to_string, repository::CliOpenRepo, status_err, Application, RUSTIC_APP, }; use abscissa_core::{Command, Runnable, Shutdown}; use log::debug; @@ -21,7 +21,11 @@ pub(crate) struct PruneCmd { impl Runnable for PruneCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -29,18 +33,17 @@ impl Runnable for PruneCmd { } impl PruneCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; - let pruner = repo.prune_plan(&self.opts)?; + let prune_plan = repo.prune_plan(&self.opts)?; - print_stats(&pruner.stats); + print_stats(&prune_plan.stats); if config.global.dry_run { - repo.warm_up(pruner.repack_packs().into_iter())?; + repo.warm_up(prune_plan.repack_packs().into_iter())?; } else { - pruner.do_prune(&repo, &self.opts)?; + repo.prune(&self.opts, prune_plan)?; } Ok(()) @@ -58,6 +61,9 @@ fn print_stats(stats: &PruneStats) { let blob_stat = stats.blobs_sum(); let size_stat = stats.size_sum(); + debug!("statistics:"); + debug!("{:#?}", stats.debug); + debug!( "used: {:>10} blobs, {:>10}", blob_stat.used, diff --git a/src/commands/repair.rs b/src/commands/repair.rs index 265f0207e..b5242b7a1 100644 --- a/src/commands/repair.rs +++ b/src/commands/repair.rs @@ -1,6 +1,9 @@ //! `repair` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{ + repository::{CliIndexedRepo, CliOpenRepo}, + status_err, Application, RUSTIC_APP, +}; use abscissa_core::{Command, Runnable, Shutdown}; use anyhow::Result; @@ -50,7 +53,8 @@ impl Runnable for RepairCmd { impl Runnable for IndexSubCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + let config = RUSTIC_APP.config(); + if let Err(err) = config.repository.run_open(|repo| self.inner_run(repo)) { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -58,9 +62,8 @@ impl Runnable for IndexSubCmd { } impl IndexSubCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; repo.repair_index(&self.opts, config.global.dry_run)?; Ok(()) } @@ -68,7 +71,8 @@ impl IndexSubCmd { impl Runnable for SnapSubCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + let config = RUSTIC_APP.config(); + if let Err(err) = config.repository.run_indexed(|repo| self.inner_run(repo)) { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -76,9 +80,8 @@ impl Runnable for SnapSubCmd { } impl SnapSubCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?.to_indexed()?; let snaps = if self.ids.is_empty() { repo.get_all_snapshots()? } else { diff --git a/src/commands/repoinfo.rs b/src/commands/repoinfo.rs index 887c42976..5dcf686a2 100644 --- a/src/commands/repoinfo.rs +++ b/src/commands/repoinfo.rs @@ -1,15 +1,16 @@ //! `repoinfo` subcommand use crate::{ - commands::open_repository, helpers::bytes_size_to_string, status_err, Application, RUSTIC_APP, + helpers::{bytes_size_to_string, table_right_from}, + repository::CliRepo, + status_err, Application, RUSTIC_APP, }; use abscissa_core::{Command, Runnable, Shutdown}; use serde::Serialize; -use crate::helpers::table_right_from; use anyhow::Result; -use rustic_core::{IndexInfos, RepoFileInfo, RepoFileInfos, Repository}; +use rustic_core::{IndexInfos, RepoFileInfo, RepoFileInfos}; /// `repoinfo` subcommand #[derive(clap::Parser, Command, Debug)] @@ -29,7 +30,11 @@ pub(crate) struct RepoInfoCmd { impl Runnable for RepoInfoCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -47,22 +52,13 @@ struct Infos { } impl RepoInfoCmd { - fn inner_run(&self) -> Result<()> { - let config = RUSTIC_APP.config(); - + fn inner_run(&self, repo: CliRepo) -> Result<()> { let infos = Infos { files: (!self.only_index) - .then(|| { - let po = config.global.progress_options; - let repo = Repository::new_with_progress(&config.repository, po)?; - repo.infos_files() - }) + .then(|| -> Result<_> { Ok(repo.infos_files()?) }) .transpose()?, index: (!self.only_files) - .then(|| -> Result<_> { - let repo = open_repository(&config)?; - Ok(repo.infos_index()?) - }) + .then(|| -> Result<_> { Ok(repo.open()?.infos_index()?) }) .transpose()?, }; diff --git a/src/commands/restore.rs b/src/commands/restore.rs index 46a2504d2..b651a24aa 100644 --- a/src/commands/restore.rs +++ b/src/commands/restore.rs @@ -1,7 +1,7 @@ //! `restore` subcommand use crate::{ - commands::open_repository, helpers::bytes_size_to_string, status_err, Application, RUSTIC_APP, + helpers::bytes_size_to_string, repository::CliIndexedRepo, status_err, Application, RUSTIC_APP, }; use abscissa_core::{Command, Runnable, Shutdown}; @@ -41,7 +41,11 @@ pub(crate) struct RestoreCmd { } impl Runnable for RestoreCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -49,10 +53,9 @@ impl Runnable for RestoreCmd { } impl RestoreCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { let config = RUSTIC_APP.config(); let dry_run = config.global.dry_run; - let repo = open_repository(&config)?.to_indexed()?; let node = repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?; @@ -64,7 +67,7 @@ impl RestoreCmd { let dest = LocalDestination::new(&self.dest, true, !node.is_dir())?; - let restore_infos = repo.prepare_restore(&self.opts, ls.clone(), &dest, dry_run)?; + let restore_infos = repo.prepare_restore(&self.opts, ls, &dest, dry_run)?; let fs = restore_infos.stats.files; println!( @@ -94,6 +97,10 @@ impl RestoreCmd { if dry_run { repo.warm_up(restore_infos.to_packs().into_iter())?; } else { + // save some memory + let repo = repo.drop_data_from_index(); + + let ls = repo.ls(&node, &ls_opts)?; repo.restore(restore_infos, &self.opts, ls, &dest)?; println!("restore done."); } diff --git a/src/commands/show_config.rs b/src/commands/show_config.rs index 10797fe10..84d8ee9a4 100644 --- a/src/commands/show_config.rs +++ b/src/commands/show_config.rs @@ -1,8 +1,10 @@ //! `show-config` subcommand -use crate::{Application, RUSTIC_APP}; +use crate::{status_err, Application, RUSTIC_APP}; -use abscissa_core::{Command, Runnable}; +use abscissa_core::{Command, Runnable, Shutdown}; +use anyhow::Result; +use toml::to_string_pretty; /// `show-config` subcommand #[derive(clap::Parser, Command, Debug)] @@ -10,7 +12,17 @@ pub(crate) struct ShowConfigCmd {} impl Runnable for ShowConfigCmd { fn run(&self) { - let config = RUSTIC_APP.config(); - println!("{config:#?}"); + if let Err(err) = self.inner_run() { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl ShowConfigCmd { + fn inner_run(&self) -> Result<()> { + let config = to_string_pretty(RUSTIC_APP.config().as_ref())?; + println!("{config}"); + Ok(()) } } diff --git a/src/commands/snapshots.rs b/src/commands/snapshots.rs index e91ca9ff7..27fb8a3e7 100644 --- a/src/commands/snapshots.rs +++ b/src/commands/snapshots.rs @@ -1,8 +1,8 @@ //! `smapshot` subcommand use crate::{ - commands::open_repository, helpers::{bold_cell, bytes_size_to_string, table, table_right_from}, + repository::CliOpenRepo, status_err, Application, RUSTIC_APP, }; @@ -17,6 +17,9 @@ use rustic_core::{ SnapshotGroupCriterion, }; +#[cfg(feature = "tui")] +use super::tui; + /// `snapshot` subcommand #[derive(clap::Parser, Command, Debug)] pub(crate) struct SnapshotCmd { @@ -44,11 +47,20 @@ pub(crate) struct SnapshotCmd { /// Show all snapshots instead of summarizing identical follow-up snapshots #[clap(long, conflicts_with_all = &["long", "json"])] all: bool, + + #[cfg(feature = "tui")] + /// Run in interactive UI mode + #[clap(long, short)] + pub interactive: bool, } impl Runnable for SnapshotCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -56,9 +68,13 @@ impl Runnable for SnapshotCmd { } impl SnapshotCmd { - fn inner_run(&self) -> Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { + #[cfg(feature = "tui")] + if self.interactive { + return tui::run(self.group_by); + } + let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; let groups = repo.get_snapshot_group(&self.ids, self.group_by, |sn| { config.snapshot_filter.matches(sn) @@ -80,40 +96,17 @@ impl SnapshotCmd { if self.long { for snap in snapshots { - snap.print_table(); - } - } else { - let snap_to_table = |(sn, count): (SnapshotFile, usize)| { - let tags = sn.tags.formatln(); - let paths = sn.paths.formatln(); - let time = sn.time.format("%Y-%m-%d %H:%M:%S"); - let (files, dirs, size) = sn.summary.as_ref().map_or_else( - || ("?".to_string(), "?".to_string(), "?".to_string()), - |s| { - ( - s.total_files_processed.to_string(), - s.total_dirs_processed.to_string(), - bytes_size_to_string(s.total_bytes_processed), - ) - }, - ); - let id = match count { - 0 => format!("{}", sn.id), - count => format!("{} (+{})", sn.id, count), + let mut table = table(); + + let add_entry = |title: &str, value: String| { + _ = table.add_row([bold_cell(title), Cell::new(value)]); }; - [ - id, - time.to_string(), - sn.hostname, - sn.label, - tags, - paths, - files, - dirs, - size, - ] - }; + fill_table(&snap, add_entry); + println!("{table}"); + println!(); + } + } else { let mut table = table_right_from( 6, [ @@ -121,14 +114,19 @@ impl SnapshotCmd { ], ); - let snapshots: Vec<_> = snapshots - .into_iter() - .group_by(|sn| if self.all { sn.id } else { sn.tree }) - .into_iter() - .map(|(_, mut g)| (g.next().unwrap(), g.count())) - .map(snap_to_table) - .collect(); - _ = table.add_rows(snapshots); + if self.all { + // Add all snapshots to output table + _ = table.add_rows(snapshots.into_iter().map(|sn| snap_to_table(&sn, 0))); + } else { + // Group snapshts by treeid and output into table + _ = table.add_rows( + snapshots + .into_iter() + .chunk_by(|sn| sn.tree) + .into_iter() + .map(|(_, mut g)| snap_to_table(&g.next().unwrap(), g.count())), + ); + } println!("{table}"); } println!("{count} snapshot(s)"); @@ -141,99 +139,115 @@ impl SnapshotCmd { } } -/// Trait to print a table -trait PrintTable { - /// Print a table - fn print_table(&self); +pub fn snap_to_table(sn: &SnapshotFile, count: usize) -> [String; 9] { + let tags = sn.tags.formatln(); + let paths = sn.paths.formatln(); + let time = sn.time.format("%Y-%m-%d %H:%M:%S"); + let (files, dirs, size) = sn.summary.as_ref().map_or_else( + || ("?".to_string(), "?".to_string(), "?".to_string()), + |s| { + ( + s.total_files_processed.to_string(), + s.total_dirs_processed.to_string(), + bytes_size_to_string(s.total_bytes_processed), + ) + }, + ); + let id = match count { + 0 => format!("{}", sn.id), + count => format!("{} (+{})", sn.id, count), + }; + [ + id, + time.to_string(), + sn.hostname.clone(), + sn.label.clone(), + tags, + paths, + files, + dirs, + size, + ] } -impl PrintTable for SnapshotFile { - fn print_table(&self) { - let mut table = table(); +pub fn fill_table(snap: &SnapshotFile, mut add_entry: impl FnMut(&str, String)) { + add_entry("Snapshot", snap.id.to_hex().to_string()); + // note that if original was not set, it is set to snap.id by the load process + if let Some(original) = snap.original { + if original != snap.id { + add_entry("Original ID", original.to_hex().to_string()); + } + } + add_entry("Time", snap.time.format("%Y-%m-%d %H:%M:%S").to_string()); + add_entry("Generated by", snap.program_version.clone()); + add_entry("Host", snap.hostname.clone()); + add_entry("Label", snap.label.clone()); + add_entry("Tags", snap.tags.formatln()); + let delete = match snap.delete { + DeleteOption::NotSet => "not set".to_string(), + DeleteOption::Never => "never".to_string(), + DeleteOption::After(t) => format!("after {}", t.format("%Y-%m-%d %H:%M:%S")), + }; + add_entry("Delete", delete); + add_entry("Paths", snap.paths.formatln()); + let parent = snap.parent.map_or_else( + || "no parent snapshot".to_string(), + |p| p.to_hex().to_string(), + ); + add_entry("Parent", parent); + if let Some(ref summary) = snap.summary { + add_entry("", String::new()); + add_entry("Command", summary.command.clone()); + + let source = format!( + "files: {} / dirs: {} / size: {}", + summary.total_files_processed, + summary.total_dirs_processed, + bytes_size_to_string(summary.total_bytes_processed) + ); + add_entry("Source", source); + add_entry("", String::new()); - let mut add_entry = |title: &str, value: String| { - _ = table.add_row([bold_cell(title), Cell::new(value)]); - }; + let files = format!( + "new: {:>10} / changed: {:>10} / unchanged: {:>10}", + summary.files_new, summary.files_changed, summary.files_unmodified, + ); + add_entry("Files", files); - add_entry("Snapshot", self.id.to_hex().to_string()); - // note that if original was not set, it is set to self.id by the load process - if self.original != Some(self.id) { - add_entry("Original ID", self.original.unwrap().to_hex().to_string()); - } - add_entry("Time", self.time.format("%Y-%m-%d %H:%M:%S").to_string()); - add_entry("Generated by", self.program_version.clone()); - add_entry("Host", self.hostname.clone()); - add_entry("Label", self.label.clone()); - add_entry("Tags", self.tags.formatln()); - let delete = match self.delete { - DeleteOption::NotSet => "not set".to_string(), - DeleteOption::Never => "never".to_string(), - DeleteOption::After(t) => format!("after {}", t.format("%Y-%m-%d %H:%M:%S")), - }; - add_entry("Delete", delete); - add_entry("Paths", self.paths.formatln()); - let parent = self.parent.map_or_else( - || "no parent snapshot".to_string(), - |p| p.to_hex().to_string(), + let trees = format!( + "new: {:>10} / changed: {:>10} / unchanged: {:>10}", + summary.dirs_new, summary.dirs_changed, summary.dirs_unmodified, ); - add_entry("Parent", parent); - if let Some(ref summary) = self.summary { - add_entry("", String::new()); - add_entry("Command", summary.command.clone()); - - let source = format!( - "files: {} / dirs: {} / size: {}", - summary.total_files_processed, - summary.total_dirs_processed, - bytes_size_to_string(summary.total_bytes_processed) - ); - add_entry("Source", source); - add_entry("", String::new()); - - let files = format!( - "new: {:>10} / changed: {:>10} / unchanged: {:>10}", - summary.files_new, summary.files_changed, summary.files_unmodified, - ); - add_entry("Files", files); - - let trees = format!( - "new: {:>10} / changed: {:>10} / unchanged: {:>10}", - summary.dirs_new, summary.dirs_changed, summary.dirs_unmodified, - ); - add_entry("Dirs", trees); - add_entry("", String::new()); - - let written = format!( - "data: {:>10} blobs / raw: {:>10} / packed: {:>10}\n\ + add_entry("Dirs", trees); + add_entry("", String::new()); + + let written = format!( + "data: {:>10} blobs / raw: {:>10} / packed: {:>10}\n\ tree: {:>10} blobs / raw: {:>10} / packed: {:>10}\n\ total: {:>10} blobs / raw: {:>10} / packed: {:>10}", - summary.data_blobs, - bytes_size_to_string(summary.data_added_files), - bytes_size_to_string(summary.data_added_files_packed), - summary.tree_blobs, - bytes_size_to_string(summary.data_added_trees), - bytes_size_to_string(summary.data_added_trees_packed), - summary.tree_blobs + summary.data_blobs, - bytes_size_to_string(summary.data_added), - bytes_size_to_string(summary.data_added_packed), - ); - add_entry("Added to repo", written); - - let duration = format!( - "backup start: {} / backup end: {} / backup duration: {}\n\ - total duration: {}", - summary.backup_start.format("%Y-%m-%d %H:%M:%S"), - summary.backup_end.format("%Y-%m-%d %H:%M:%S"), - format_duration(std::time::Duration::from_secs_f64(summary.backup_duration)), - format_duration(std::time::Duration::from_secs_f64(summary.total_duration)) - ); - add_entry("Duration", duration); - } - if let Some(ref description) = self.description { - add_entry("Description", description.clone()); - } + summary.data_blobs, + bytes_size_to_string(summary.data_added_files), + bytes_size_to_string(summary.data_added_files_packed), + summary.tree_blobs, + bytes_size_to_string(summary.data_added_trees), + bytes_size_to_string(summary.data_added_trees_packed), + summary.tree_blobs + summary.data_blobs, + bytes_size_to_string(summary.data_added), + bytes_size_to_string(summary.data_added_packed), + ); + add_entry("Added to repo", written); - println!("{table}"); - println!(); + let duration = format!( + "backup start: {} / backup end: {} / backup duration: {}\n\ + total duration: {}", + summary.backup_start.format("%Y-%m-%d %H:%M:%S"), + summary.backup_end.format("%Y-%m-%d %H:%M:%S"), + format_duration(std::time::Duration::from_secs_f64(summary.backup_duration)), + format_duration(std::time::Duration::from_secs_f64(summary.total_duration)) + ); + add_entry("Duration", duration); + } + if let Some(ref description) = snap.description { + add_entry("Description", description.clone()); } } diff --git a/src/commands/tag.rs b/src/commands/tag.rs index d7855b334..302c58123 100644 --- a/src/commands/tag.rs +++ b/src/commands/tag.rs @@ -1,9 +1,10 @@ //! `tag` subcommand -use crate::{commands::open_repository, status_err, Application, RUSTIC_APP}; +use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP}; use abscissa_core::{Command, Runnable, Shutdown}; +use anyhow::Result; use chrono::{Duration, Local}; use rustic_core::{repofile::DeleteOption, StringList}; @@ -61,7 +62,11 @@ pub(crate) struct TagCmd { impl Runnable for TagCmd { fn run(&self) { - if let Err(err) = self.inner_run() { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_open(|repo| self.inner_run(repo)) + { status_err!("{}", err); RUSTIC_APP.shutdown(Shutdown::Crash); }; @@ -69,9 +74,8 @@ impl Runnable for TagCmd { } impl TagCmd { - fn inner_run(&self) -> anyhow::Result<()> { + fn inner_run(&self, repo: CliOpenRepo) -> Result<()> { let config = RUSTIC_APP.config(); - let repo = open_repository(&config)?; let snapshots = if self.ids.is_empty() { repo.get_matching_snapshots(|sn| config.snapshot_filter.matches(sn))? diff --git a/src/commands/tui.rs b/src/commands/tui.rs new file mode 100644 index 000000000..c0d0d6113 --- /dev/null +++ b/src/commands/tui.rs @@ -0,0 +1,112 @@ +//! `tui` subcommand +mod ls; +mod progress; +mod restore; +mod snapshots; +mod tree; +mod widgets; + +use crossterm::event::{KeyEvent, KeyModifiers}; +use progress::TuiProgressBars; +use scopeguard::defer; +use snapshots::Snapshots; + +use std::io; +use std::sync::{Arc, RwLock}; + +use crate::{Application, RUSTIC_APP}; + +use anyhow::Result; +use crossterm::{ + event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind}, + execute, + terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, +}; +use ratatui::prelude::*; +use rustic_core::{IndexedFull, Progress, ProgressBars, SnapshotGroupCriterion}; + +struct App<'a, P, S> { + snapshots: Snapshots<'a, P, S>, +} + +pub fn run(group_by: SnapshotGroupCriterion) -> Result<()> { + let config = RUSTIC_APP.config(); + + // setup terminal + let terminal = init_terminal()?; + let terminal = Arc::new(RwLock::new(terminal)); + + // restore terminal (even when leaving through ?, early return, or panic) + defer! { + reset_terminal().unwrap(); + } + + let progress = TuiProgressBars { + terminal: terminal.clone(), + }; + let res = config + .repository + .run_indexed_with_progress(progress.clone(), |repo| { + let p = progress.progress_spinner("starting rustic in interactive mode..."); + p.finish(); + // create app and run it + let snapshots = Snapshots::new(&repo, config.snapshot_filter.clone(), group_by)?; + let app = App { snapshots }; + run_app(terminal, app) + }); + + if let Err(err) = res { + println!("{err:?}"); + } + + Ok(()) +} + +/// Initializes the terminal. +fn init_terminal() -> Result>> { + execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture)?; + enable_raw_mode()?; + + let backend = CrosstermBackend::new(io::stdout()); + + let mut terminal = Terminal::new(backend)?; + terminal.hide_cursor()?; + + Ok(terminal) +} + +/// Resets the terminal. +fn reset_terminal() -> Result<()> { + disable_raw_mode()?; + execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture)?; + Ok(()) +} + +fn run_app( + terminal: Arc>>, + mut app: App<'_, P, S>, +) -> Result<()> { + loop { + _ = terminal.write().unwrap().draw(|f| ui(f, &mut app))?; + let event = event::read()?; + use KeyCode::*; + + if let Event::Key(KeyEvent { + code: Char('c'), + modifiers: KeyModifiers::CONTROL, + kind: KeyEventKind::Press, + .. + }) = event + { + return Ok(()); + } + if app.snapshots.input(event)? { + return Ok(()); + } + } +} + +fn ui(f: &mut Frame<'_>, app: &mut App<'_, P, S>) { + let area = f.area(); + app.snapshots.draw(area, f); +} diff --git a/src/commands/tui/ls.rs b/src/commands/tui/ls.rs new file mode 100644 index 000000000..2956fa141 --- /dev/null +++ b/src/commands/tui/ls.rs @@ -0,0 +1,320 @@ +use std::path::{Path, PathBuf}; + +use anyhow::Result; +use crossterm::event::{Event, KeyCode, KeyEventKind}; +use ratatui::{prelude::*, widgets::*}; +use rustic_core::{ + repofile::{Node, SnapshotFile, Tree}, + vfs::OpenFile, + IndexedFull, ProgressBars, Repository, +}; +use style::palette::tailwind; + +use crate::commands::{ + ls::{NodeLs, Summary}, + tui::{ + restore::Restore, + widgets::{ + popup_prompt, popup_scrollable_text, popup_text, Draw, PopUpPrompt, PopUpText, + ProcessEvent, PromptResult, SelectTable, TextInputResult, WithBlock, + }, + }, +}; + +use super::widgets::PopUpInput; + +// the states this screen can be in +enum CurrentScreen<'a, P, S> { + Snapshot, + ShowHelp(PopUpText), + Restore(Restore<'a, P, S>), + PromptExit(PopUpPrompt), + ShowFile(PopUpInput), +} + +const INFO_TEXT: &str = + "(Esc) quit | (Enter) enter dir | (Backspace) return to parent | (v) view | (r) restore | (?) show all commands"; + +const HELP_TEXT: &str = r#" +General Commands: + + q,Esc : exit + Enter : enter dir + Backspace : return to parent dir + v : view file contents (text files only, up to 1MiB) + r : restore selected item + n : toggle numeric IDs + ? : show this help page + + "#; + +pub(crate) struct Snapshot<'a, P, S> { + current_screen: CurrentScreen<'a, P, S>, + numeric: bool, + table: WithBlock, + repo: &'a Repository, + snapshot: SnapshotFile, + path: PathBuf, + trees: Vec<(Tree, usize)>, // Stack of parent trees with position + tree: Tree, +} + +pub enum SnapshotResult { + Exit, + Return, + None, +} + +impl<'a, P: ProgressBars, S: IndexedFull> Snapshot<'a, P, S> { + pub fn new(repo: &'a Repository, snapshot: SnapshotFile) -> Result { + let header = ["Name", "Size", "Mode", "User", "Group", "Time"] + .into_iter() + .map(Text::from) + .collect(); + + let tree = repo.get_tree(&snapshot.tree)?; + let mut app = Self { + current_screen: CurrentScreen::Snapshot, + numeric: false, + table: WithBlock::new(SelectTable::new(header), Block::new()), + repo, + snapshot, + path: PathBuf::new(), + trees: Vec::new(), + tree, + }; + app.update_table(); + Ok(app) + } + + fn ls_row(&self, node: &Node) -> Vec> { + let (user, group) = if self.numeric { + ( + node.meta + .uid + .map_or_else(|| "?".to_string(), |id| id.to_string()), + node.meta + .gid + .map_or_else(|| "?".to_string(), |id| id.to_string()), + ) + } else { + ( + node.meta.user.clone().unwrap_or_else(|| "?".to_string()), + node.meta.group.clone().unwrap_or_else(|| "?".to_string()), + ) + }; + let name = node.name().to_string_lossy().to_string(); + let size = node.meta.size.to_string(); + let mtime = node + .meta + .mtime + .map(|t| format!("{}", t.format("%Y-%m-%d %H:%M:%S"))) + .unwrap_or_else(|| "?".to_string()); + [name, size, node.mode_str(), user, group, mtime] + .into_iter() + .map(Text::from) + .collect() + } + + pub fn selected_node(&self) -> Option<&Node> { + self.table.widget.selected().map(|i| &self.tree.nodes[i]) + } + + pub fn update_table(&mut self) { + let old_selection = if self.tree.nodes.is_empty() { + None + } else { + Some(self.table.widget.selected().unwrap_or_default()) + }; + let mut rows = Vec::new(); + let mut summary = Summary::default(); + for node in &self.tree.nodes { + summary.update(node); + let row = self.ls_row(node); + rows.push(row); + } + + self.table.widget.set_content(rows, 1); + + self.table.block = Block::new() + .borders(Borders::BOTTOM | Borders::TOP) + .title(format!("{}:{}", self.snapshot.id, self.path.display())) + .title_bottom(format!( + "total: {}, files: {}, dirs: {}, size: {} - {}", + self.tree.nodes.len(), + summary.files, + summary.dirs, + summary.size, + if self.numeric { + "numeric IDs" + } else { + " Id names" + } + )) + .title_alignment(Alignment::Center); + self.table.widget.select(old_selection); + } + + pub fn enter(&mut self) -> Result<()> { + if let Some(idx) = self.table.widget.selected() { + let node = &self.tree.nodes[idx]; + if node.is_dir() { + self.path.push(node.name()); + let tree = self.tree.clone(); + self.tree = self.repo.get_tree(&node.subtree.unwrap())?; + self.trees.push((tree, idx)); + } + } + self.table.widget.set_to(0); + self.update_table(); + Ok(()) + } + + pub fn goback(&mut self) -> bool { + _ = self.path.pop(); + if let Some((tree, idx)) = self.trees.pop() { + self.tree = tree; + self.table.widget.set_to(idx); + self.update_table(); + false + } else { + true + } + } + + pub fn toggle_numeric(&mut self) { + self.numeric = !self.numeric; + self.update_table(); + } + + pub fn input(&mut self, event: Event) -> Result { + use KeyCode::*; + match &mut self.current_screen { + CurrentScreen::Snapshot => match event { + Event::Key(key) if key.kind == KeyEventKind::Press => match key.code { + Enter | Right => self.enter()?, + Backspace | Left => { + if self.goback() { + return Ok(SnapshotResult::Return); + } + } + Esc | Char('q') => { + self.current_screen = CurrentScreen::PromptExit(popup_prompt( + "exit rustic", + "do you want to exit? (y/n)".into(), + )); + } + Char('?') => { + self.current_screen = + CurrentScreen::ShowHelp(popup_text("help", HELP_TEXT.into())); + } + Char('n') => self.toggle_numeric(), + Char('v') => { + // viewing is not supported on cold repositories + if self.repo.config().is_hot != Some(true) { + if let Some(node) = self.selected_node() { + if node.is_file() { + if let Ok(data) = OpenFile::from_node(self.repo, node).read_at( + self.repo, + 0, + node.meta.size.min(1_000_000).try_into().unwrap(), + ) { + // viewing is only supported for text files + if let Ok(content) = String::from_utf8(data.to_vec()) { + let lines = content.lines().count(); + let path = self.path.join(node.name()); + let path = path.display(); + self.current_screen = + CurrentScreen::ShowFile(popup_scrollable_text( + format!("{}:/{path}", self.snapshot.id), + &content, + (lines + 1).min(40).try_into().unwrap(), + )); + } + } + } + } + } + } + Char('r') => { + if let Some(node) = self.selected_node() { + let is_absolute = self + .snapshot + .paths + .iter() + .any(|p| Path::new(p).is_absolute()); + let path = self.path.join(node.name()); + let path = path.display(); + let default_targt = if is_absolute { + format!("/{path}") + } else { + format!("{path}") + }; + let restore = Restore::new( + self.repo, + node.clone(), + format!("{}:/{path}", self.snapshot.id), + &default_targt, + ); + self.current_screen = CurrentScreen::Restore(restore); + } + } + _ => self.table.input(event), + }, + _ => {} + }, + CurrentScreen::ShowFile(prompt) => match prompt.input(event) { + TextInputResult::Cancel | TextInputResult::Input(_) => { + self.current_screen = CurrentScreen::Snapshot; + } + TextInputResult::None => {} + }, + CurrentScreen::ShowHelp(_) => match event { + Event::Key(key) if key.kind == KeyEventKind::Press => { + if matches!(key.code, Char('q') | Esc | Enter | Char(' ') | Char('?')) { + self.current_screen = CurrentScreen::Snapshot; + } + } + _ => {} + }, + CurrentScreen::Restore(restore) => { + if restore.input(event)? { + self.current_screen = CurrentScreen::Snapshot; + } + } + CurrentScreen::PromptExit(prompt) => match prompt.input(event) { + PromptResult::Ok => return Ok(SnapshotResult::Exit), + PromptResult::Cancel => self.current_screen = CurrentScreen::Snapshot, + PromptResult::None => {} + }, + } + Ok(SnapshotResult::None) + } + + pub fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + let rects = Layout::vertical([Constraint::Min(0), Constraint::Length(1)]).split(area); + + if let CurrentScreen::Restore(restore) = &mut self.current_screen { + restore.draw(area, f); + } else { + // draw the table + self.table.draw(rects[0], f); + + // draw the footer + let buffer_bg = tailwind::SLATE.c950; + let row_fg = tailwind::SLATE.c200; + let info_footer = Paragraph::new(Line::from(INFO_TEXT)) + .style(Style::new().fg(row_fg).bg(buffer_bg)) + .centered(); + f.render_widget(info_footer, rects[1]); + } + + // draw popups + match &mut self.current_screen { + CurrentScreen::Snapshot | CurrentScreen::Restore(_) => {} + CurrentScreen::ShowHelp(popup) => popup.draw(area, f), + CurrentScreen::PromptExit(popup) => popup.draw(area, f), + CurrentScreen::ShowFile(popup) => popup.draw(area, f), + } + } +} diff --git a/src/commands/tui/progress.rs b/src/commands/tui/progress.rs new file mode 100644 index 000000000..3f5f70fa7 --- /dev/null +++ b/src/commands/tui/progress.rs @@ -0,0 +1,174 @@ +use std::io::Stdout; +use std::sync::{Arc, RwLock}; +use std::time::{Duration, SystemTime}; + +use bytesize::ByteSize; +use ratatui::{backend::CrosstermBackend, Terminal}; +use rustic_core::{Progress, ProgressBars}; + +use super::widgets::{popup_gauge, popup_text, Draw}; + +#[derive(Clone)] +pub struct TuiProgressBars { + pub terminal: Arc>>>, +} + +impl TuiProgressBars { + fn as_progress(&self, progress_type: TuiProgressType, prefix: String) -> TuiProgress { + TuiProgress { + terminal: self.terminal.clone(), + data: Arc::new(RwLock::new(CounterData::new(prefix))), + progress_type, + } + } +} + +impl ProgressBars for TuiProgressBars { + type P = TuiProgress; + fn progress_hidden(&self) -> Self::P { + self.as_progress(TuiProgressType::Hidden, String::new()) + } + fn progress_spinner(&self, prefix: impl Into>) -> Self::P { + let progress = self.as_progress(TuiProgressType::Spinner, String::from(prefix.into())); + progress.popup(); + progress + } + fn progress_counter(&self, prefix: impl Into>) -> Self::P { + let progress = self.as_progress(TuiProgressType::Counter, String::from(prefix.into())); + progress.popup(); + progress + } + fn progress_bytes(&self, prefix: impl Into>) -> Self::P { + let progress = self.as_progress(TuiProgressType::Bytes, String::from(prefix.into())); + progress.popup(); + progress + } +} + +struct CounterData { + prefix: String, + begin: SystemTime, + length: Option, + count: u64, +} + +impl CounterData { + fn new(prefix: String) -> Self { + Self { + prefix, + begin: SystemTime::now(), + length: None, + count: 0, + } + } +} + +#[derive(Clone)] +enum TuiProgressType { + Hidden, + Spinner, + Counter, + Bytes, +} + +#[derive(Clone)] +pub struct TuiProgress { + terminal: Arc>>>, + data: Arc>, + progress_type: TuiProgressType, +} + +fn fmt_duration(d: Duration) -> String { + let seconds = d.as_secs(); + let (minutes, seconds) = (seconds / 60, seconds % 60); + let (hours, minutes) = (minutes / 60, minutes % 60); + format!("[{hours:02}:{minutes:02}:{seconds:02}]") +} + +impl TuiProgress { + fn popup(&self) { + let data = self.data.read().unwrap(); + let elapsed = data.begin.elapsed().unwrap(); + let length = data.length; + let count = data.count; + let ratio = match length { + None | Some(0) => 0.0, + Some(l) => count as f64 / l as f64, + }; + let eta = match ratio { + r if r < 0.01 => " ETA: -".to_string(), + r if r > 0.999999 => String::new(), + r => { + format!( + " ETA: {}", + fmt_duration(Duration::from_secs(1) + elapsed.div_f64(r / (1.0 - r))) + ) + } + }; + let prefix = &data.prefix; + let message = match self.progress_type { + TuiProgressType::Spinner => { + format!("{} {prefix}", fmt_duration(elapsed)) + } + TuiProgressType::Counter => { + format!( + "{} {prefix} {}{}{eta}", + fmt_duration(elapsed), + count, + length.map_or(String::new(), |l| format!("/{l}")) + ) + } + TuiProgressType::Bytes => { + format!( + "{} {prefix} {}{}{eta}", + fmt_duration(elapsed), + ByteSize(count).to_string_as(true), + length.map_or(String::new(), |l| format!( + "/{}", + ByteSize(l).to_string_as(true) + )) + ) + } + TuiProgressType::Hidden => String::new(), + }; + drop(data); + + let mut terminal = self.terminal.write().unwrap(); + _ = terminal + .draw(|f| { + let area = f.area(); + match self.progress_type { + TuiProgressType::Hidden => {} + TuiProgressType::Spinner => { + let mut popup = popup_text("progress", message.into()); + popup.draw(area, f); + } + TuiProgressType::Counter | TuiProgressType::Bytes => { + let mut popup = popup_gauge("progress", message.into(), ratio); + popup.draw(area, f); + } + } + }) + .unwrap(); + } +} + +impl Progress for TuiProgress { + fn is_hidden(&self) -> bool { + matches!(self.progress_type, TuiProgressType::Hidden) + } + fn set_length(&self, len: u64) { + self.data.write().unwrap().length = Some(len); + self.popup(); + } + fn set_title(&self, title: &'static str) { + self.data.write().unwrap().prefix = String::from(title); + self.popup(); + } + + fn inc(&self, inc: u64) { + self.data.write().unwrap().count += inc; + self.popup(); + } + fn finish(&self) {} +} diff --git a/src/commands/tui/restore.rs b/src/commands/tui/restore.rs new file mode 100644 index 000000000..a2dbef439 --- /dev/null +++ b/src/commands/tui/restore.rs @@ -0,0 +1,160 @@ +use anyhow::Result; +use crossterm::event::{Event, KeyCode, KeyEventKind}; +use ratatui::prelude::*; +use rustic_core::{ + repofile::Node, IndexedFull, LocalDestination, LsOptions, ProgressBars, Repository, + RestoreOptions, RestorePlan, +}; + +use crate::{ + commands::tui::widgets::{ + popup_input, popup_prompt, Draw, PopUpInput, PopUpPrompt, PopUpText, ProcessEvent, + PromptResult, TextInputResult, + }, + helpers::bytes_size_to_string, +}; + +use super::widgets::popup_text; + +// the states this screen can be in +enum CurrentScreen { + GetDestination(PopUpInput), + PromptRestore(PopUpPrompt, Option), + RestoreDone(PopUpText), +} + +pub(crate) struct Restore<'a, P, S> { + current_screen: CurrentScreen, + repo: &'a Repository, + opts: RestoreOptions, + node: Node, + source: String, + dest: String, +} + +impl<'a, P: ProgressBars, S: IndexedFull> Restore<'a, P, S> { + pub fn new(repo: &'a Repository, node: Node, source: String, path: &str) -> Self { + let opts = RestoreOptions::default(); + let title = format!("restore {} to:", source); + let popup = popup_input(title, "enter restore destination", path, 1); + Self { + current_screen: CurrentScreen::GetDestination(popup), + node, + repo, + opts, + source, + dest: String::new(), + } + } + + pub fn compute_plan(&mut self, mut dest: String, dry_run: bool) -> Result { + if dest.is_empty() { + dest = ".".to_string(); + } + self.dest = dest; + let dest = LocalDestination::new(&self.dest, true, !self.node.is_dir())?; + + // for restore, always recurse into tree + let mut ls_opts = LsOptions::default(); + ls_opts.recursive = true; + + let ls = self.repo.ls(&self.node, &ls_opts)?; + + let plan = self.repo.prepare_restore(&self.opts, ls, &dest, dry_run)?; + + Ok(plan) + } + + // restore using the plan + // + // Note: This currently runs `prepare_restore` again and doesn't use `plan` + // TODO: Fix when restore is changed such that `prepare_restore` is always dry_run and all modification is done in `restore` + fn restore(&self, _plan: RestorePlan) -> Result<()> { + let dest = LocalDestination::new(&self.dest, true, !self.node.is_dir())?; + + // for restore, always recurse into tree + let mut ls_opts = LsOptions::default(); + ls_opts.recursive = true; + + let ls = self.repo.ls(&self.node, &ls_opts)?; + let plan = self + .repo + .prepare_restore(&self.opts, ls.clone(), &dest, false)?; + + // the actual restore + self.repo.restore(plan, &self.opts, ls, &dest)?; + Ok(()) + } + + pub fn input(&mut self, event: Event) -> Result { + use KeyCode::*; + match &mut self.current_screen { + CurrentScreen::GetDestination(prompt) => match prompt.input(event) { + TextInputResult::Cancel => return Ok(true), + TextInputResult::Input(input) => { + let plan = self.compute_plan(input, true)?; + let fs = plan.stats.files; + let ds = plan.stats.dirs; + let popup = popup_prompt( + "restore information", + Text::from(format!( + r#" +restoring from: {} +restoring to: {} + +Files: {} to restore, {} unchanged, {} verified, {} to modify, {} additional +Dirs: {} to restore, {} to modify, {} additional +Total restore size: {} + +Do you want to proceed (y/n)? + "#, + self.source, + self.dest, + fs.restore, + fs.unchanged, + fs.verified, + fs.modify, + fs.additional, + ds.restore, + ds.modify, + ds.additional, + bytes_size_to_string(plan.restore_size) + )), + ); + self.current_screen = CurrentScreen::PromptRestore(popup, Some(plan)); + } + TextInputResult::None => {} + }, + CurrentScreen::PromptRestore(prompt, plan) => match prompt.input(event) { + PromptResult::Ok => { + let plan = plan.take().unwrap(); + self.restore(plan)?; + self.current_screen = CurrentScreen::RestoreDone(popup_text( + "restore done", + format!("restored {} successfully to {}", self.source, self.dest).into(), + )); + } + PromptResult::Cancel => return Ok(true), + PromptResult::None => {} + }, + CurrentScreen::RestoreDone(_) => match event { + Event::Key(key) if key.kind == KeyEventKind::Press => { + if matches!(key.code, Char('q') | Esc | Enter | Char(' ')) { + return Ok(true); + } + } + _ => {} + }, + } + Ok(false) + } + + pub fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + // draw popups + match &mut self.current_screen { + CurrentScreen::GetDestination(popup) => popup.draw(area, f), + CurrentScreen::PromptRestore(popup, _) => popup.draw(area, f), + CurrentScreen::RestoreDone(popup) => popup.draw(area, f), + } + } +} diff --git a/src/commands/tui/snapshots.rs b/src/commands/tui/snapshots.rs new file mode 100644 index 000000000..bacc47a05 --- /dev/null +++ b/src/commands/tui/snapshots.rs @@ -0,0 +1,928 @@ +use std::{collections::BTreeSet, iter::once, mem, str::FromStr}; + +use anyhow::Result; +use chrono::Local; +use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers}; +use itertools::Itertools; +use ratatui::{prelude::*, widgets::*}; +use rustic_core::{ + repofile::{DeleteOption, SnapshotFile}, + IndexedFull, ProgressBars, Repository, SnapshotGroup, SnapshotGroupCriterion, StringList, +}; +use style::palette::tailwind; + +use crate::{ + commands::{ + snapshots::{fill_table, snap_to_table}, + tui::{ + ls::{Snapshot, SnapshotResult}, + tree::{Tree, TreeIterItem, TreeNode}, + widgets::{ + popup_input, popup_prompt, popup_table, popup_text, Draw, PopUpInput, PopUpPrompt, + PopUpTable, PopUpText, ProcessEvent, PromptResult, SelectTable, TextInputResult, + WithBlock, + }, + }, + }, + filtering::SnapshotFilter, +}; + +// the states this screen can be in +enum CurrentScreen<'a, P, S> { + Snapshots, + ShowHelp(PopUpText), + SnapshotDetails(PopUpTable), + EnterLabel(PopUpInput), + EnterDescription(PopUpInput), + EnterAddTags(PopUpInput), + EnterSetTags(PopUpInput), + EnterRemoveTags(PopUpInput), + EnterFilter(PopUpInput), + PromptWrite(PopUpPrompt), + PromptExit(PopUpPrompt), + Dir(Snapshot<'a, P, S>), +} + +// status of each snapshot +#[derive(Clone, Copy, Default)] +struct SnapStatus { + marked: bool, + modified: bool, + to_forget: bool, +} + +impl SnapStatus { + fn toggle_mark(&mut self) { + self.marked = !self.marked; + } +} + +#[derive(Debug)] +enum View { + Filter, + All, + Marked, + Modified, +} + +#[derive(PartialEq, Eq)] +enum SnapshotNode { + Group(SnapshotGroup), + Snap(usize), +} + +const INFO_TEXT: &str = + "(Esc) quit | (F5) reload snapshots | (Enter) show contents | (v) toggle view | (i) show snapshot | (?) show all commands"; + +const HELP_TEXT: &str = r#"General Commands: + q, Esc : exit + F5 : re-read all snapshots from repository + Enter : show snapshot contents + v : toggle snapshot view [Filtered -> All -> Marked -> Modified] + V : modify filter to use + Ctrl-v : reset filter + i : show detailed snapshot information for selected snapshot + w : write modified snapshots and delete snapshots to-forget + ? : show this help page + + Commands for marking snapshot(s): + + x : toggle marking for selected snapshot + X : toggle markings for all snapshots + Ctrl-x : clear all markings + + Commands applied to marked snapshot(s) (selected if none marked): + + f : toggle to-forget for snapshot(s) + Ctrl-f : clear to-forget for snapshot(s) + l : set label for snapshot(s) + Ctrl-l : remove label for snapshot(s) + d : set description for snapshot(s) + Ctrl-d : remove description for snapshot(s) + t : add tag(s) for snapshot(s) + Ctrl-t : remove all tags for snapshot(s) + s : set tag(s) for snapshot(s) + r : remove tag(s) for snapshot(s) + p : set delete protection for snapshot(s) + Ctrl-p : remove delete protection for snapshot(s) +"#; + +pub(crate) struct Snapshots<'a, P, S> { + current_screen: CurrentScreen<'a, P, S>, + current_view: View, + table: WithBlock, + repo: &'a Repository, + snaps_status: Vec, + snapshots: Vec, + original_snapshots: Vec, + filtered_snapshots: Vec, + tree: Tree, + filter: SnapshotFilter, + default_filter: SnapshotFilter, + group_by: SnapshotGroupCriterion, +} + +impl<'a, P: ProgressBars, S: IndexedFull> Snapshots<'a, P, S> { + pub fn new( + repo: &'a Repository, + filter: SnapshotFilter, + group_by: SnapshotGroupCriterion, + ) -> Result { + let header = [ + "", " ID", "Time", "Host", "Label", "Tags", "Paths", "Files", "Dirs", "Size", + ] + .into_iter() + .map(Text::from) + .collect(); + + let mut app = Self { + current_screen: CurrentScreen::Snapshots, + current_view: View::Filter, + table: WithBlock::new(SelectTable::new(header), Block::new()), + repo, + snaps_status: Vec::new(), + original_snapshots: Vec::new(), + snapshots: Vec::new(), + filtered_snapshots: Vec::new(), + tree: Tree::Leaf(0), + default_filter: filter.clone(), + filter, + group_by, + }; + app.reread()?; + Ok(app) + } + + fn selected_tree(&self) -> Option> { + self.table + .widget + .selected() + .and_then(|selected| self.tree.iter_open().nth(selected)) + } + + fn selected_tree_mut(&mut self) -> Option<&mut Tree> { + self.table + .widget + .selected() + .and_then(|selected| self.tree.nth_mut(selected)) + } + + fn snap_idx(&self) -> Vec { + self.selected_tree() + .iter() + .flat_map(|item| item.tree.iter().map(|item| item.tree)) + .filter_map(|tree| tree.leaf_data().copied()) + .collect() + } + + fn selected_snapshot(&self) -> Option<&SnapshotFile> { + self.selected_tree().map(|tree_info| match tree_info.tree { + Tree::Leaf(index) + | Tree::Node(TreeNode { + data: SnapshotNode::Snap(index), + .. + }) => Some(&self.snapshots[*index]), + _ => None, + })? + } + + pub fn has_mark(&self) -> bool { + self.snaps_status.iter().any(|s| s.marked) + } + + pub fn has_modified(&self) -> bool { + self.snaps_status.iter().any(|s| s.modified) + } + + pub fn toggle_view_mark(&mut self) { + match self.current_view { + View::Filter => self.current_view = View::All, + View::All => { + self.current_view = View::Marked; + if !self.has_mark() { + self.toggle_view_mark(); + } + } + View::Marked => { + self.current_view = View::Modified; + if !self.has_modified() { + self.toggle_view_mark(); + } + } + View::Modified => self.current_view = View::Filter, + } + } + + pub fn toggle_view(&mut self) { + self.toggle_view_mark(); + self.apply_view(); + } + + pub fn apply_view(&mut self) { + // select snapshots to show + self.filtered_snapshots = self + .snapshots + .iter() + .enumerate() + .zip(self.snaps_status.iter()) + .filter_map(|((i, sn), status)| { + match self.current_view { + View::All => true, + View::Filter => self.filter.matches(sn), + View::Marked => status.marked, + View::Modified => status.modified, + } + .then_some(i) + }) + .collect(); + self.create_tree(); + } + + pub fn create_tree(&mut self) { + // remember current snapshot index + let old_tree = self.selected_tree().map(|t| t.tree); + + let mut result = Vec::new(); + for (group, snaps) in &self + .filtered_snapshots + .iter() + .chunk_by(|i| SnapshotGroup::from_snapshot(&self.snapshots[**i], self.group_by)) + { + let mut same_id_group = Vec::new(); + for (_, s) in &snaps.into_iter().chunk_by(|i| self.snapshots[**i].tree) { + let leafs: Vec<_> = s.map(|i| Tree::leaf(*i)).collect(); + let first = leafs[0].leaf_data().unwrap(); // Cannot be None as leafs[0] is a leaf! + if leafs.len() == 1 { + same_id_group.push(Tree::leaf(*first)); + } else { + same_id_group.push(Tree::node(SnapshotNode::Snap(*first), false, leafs)); + } + } + result.push(Tree::node(SnapshotNode::Group(group), false, same_id_group)); + } + let tree = Tree::node(SnapshotNode::Snap(0), true, result); + + let len = tree.iter_open().count(); + let selected = if len == 0 { + None + } else { + Some( + tree.iter() + .position(|info| Some(info.tree) == old_tree) + .unwrap_or(len - 1), + ) + }; + + self.tree = tree; + self.update_table(); + self.table.widget.select(selected); + } + + fn table_row(&self, info: TreeIterItem<'_, SnapshotNode, usize>) -> Vec> { + let (has_mark, has_not_mark, has_modified, has_to_forget) = info + .tree + .iter() + .filter_map(|item| item.leaf_data().copied()) + .fold( + (false, false, false, false), + |(mut a, mut b, mut c, mut d), i| { + if self.snaps_status[i].marked { + a = true; + } else { + b = true; + } + + if self.snaps_status[i].modified { + c = true; + } + + if self.snaps_status[i].to_forget { + d = true; + } + + (a, b, c, d) + }, + ); + + let mark = match (has_mark, has_not_mark) { + (false, _) => " ", + (true, true) => "*", + (true, false) => "X", + }; + let modified = if has_modified { "*" } else { " " }; + let del = if has_to_forget { "🗑" } else { "" }; + let mut collapse = " ".repeat(info.depth); + collapse.push_str(match info.tree { + Tree::Leaf(_) => "", + Tree::Node(TreeNode { open: false, .. }) => "\u{25b6} ", // Arrow to right + Tree::Node(TreeNode { open: true, .. }) => "\u{25bc} ", // Arrow down + }); + + match info.tree { + Tree::Leaf(index) + | Tree::Node(TreeNode { + data: SnapshotNode::Snap(index), + .. + }) => { + let snap = &self.snapshots[*index]; + let symbols = match ( + snap.delete == DeleteOption::NotSet, + snap.description.is_none(), + ) { + (true, true) => "", + (true, false) => "🗎", + (false, true) => "🛡", + (false, false) => "🛡 🗎", + }; + let count = info.tree.child_count(); + once(&mark.to_string()) + .chain(snap_to_table(snap, count).iter()) + .cloned() + .enumerate() + .map(|(i, mut content)| { + if i == 1 { + // ID gets modified and protected marks + content = format!("{collapse}{modified}{del}{content}{symbols}"); + } + Text::from(content) + }) + .collect() + } + Tree::Node(TreeNode { + data: SnapshotNode::Group(group), + .. + }) => { + let host = group + .hostname + .as_ref() + .map(String::from) + .unwrap_or_default(); + let label = group.label.as_ref().map(String::from).unwrap_or_default(); + + let paths = group + .paths + .as_ref() + .map_or_else(String::default, |p| p.formatln()); + let tags = group + .tags + .as_ref() + .map_or_else(String::default, |t| t.formatln()); + [ + mark.to_string(), + format!("{collapse}{modified}{del}group"), + String::default(), + host, + label, + tags, + paths, + String::default(), + String::default(), + String::default(), + ] + .into_iter() + .map(Text::from) + .collect() + } + } + } + + pub fn update_table(&mut self) { + let max_tags = self + .filtered_snapshots + .iter() + .map(|&i| self.snapshots[i].tags.iter().count()) + .max() + .unwrap_or(1); + let max_paths = self + .filtered_snapshots + .iter() + .map(|&i| self.snapshots[i].paths.iter().count()) + .max() + .unwrap_or(1); + let height = max_tags.max(max_paths).max(1) + 1; + + let rows = self + .tree + .iter_open() + .map(|tree| self.table_row(tree)) + .collect(); + + self.table.widget.set_content(rows, height); + self.table.block = Block::new() + .borders(Borders::BOTTOM) + .title_bottom(format!( + "{:?} view: {}, total: {}, marked: {}, modified: {}, to forget: {}", + self.current_view, + self.filtered_snapshots.len(), + self.snapshots.len(), + self.count_marked_snaps(), + self.count_modified_snaps(), + self.count_forget_snaps() + )) + .title_alignment(Alignment::Center); + } + + pub fn toggle_mark(&mut self) { + for snap_idx in self.snap_idx() { + self.snaps_status[snap_idx].toggle_mark(); + } + self.update_table(); + } + + pub fn toggle_mark_all(&mut self) { + for snap_idx in &self.filtered_snapshots { + self.snaps_status[*snap_idx].toggle_mark(); + } + self.update_table(); + } + + pub fn clear_marks(&mut self) { + for status in self.snaps_status.iter_mut() { + status.marked = false; + } + self.update_table(); + } + + pub fn reset_filter(&mut self) { + self.filter = self.default_filter.clone(); + self.apply_view(); + } + + pub fn collapse(&mut self) { + if let Some(tree) = self.selected_tree_mut() { + tree.close(); + self.update_table(); + } + } + + pub fn extendable(&self) -> bool { + matches!(self.selected_tree(), Some(tree_info) if tree_info.tree.openable()) + } + + pub fn extend(&mut self) { + if let Some(tree) = self.selected_tree_mut() { + tree.open(); + self.update_table(); + } + } + + pub fn snapshot_details(&self) -> PopUpTable { + let mut rows = Vec::new(); + if let Some(snap) = self.selected_snapshot() { + fill_table(snap, |title, value| { + rows.push(vec![Text::from(title.to_string()), Text::from(value)]); + }); + } + popup_table("snapshot details", rows) + } + + pub fn dir(&self) -> Result>> { + self.selected_snapshot().map_or(Ok(None), |snap| { + Some(Snapshot::new(self.repo, snap.clone())).transpose() + }) + } + + pub fn count_marked_snaps(&self) -> usize { + self.snaps_status.iter().filter(|s| s.marked).count() + } + + pub fn count_modified_snaps(&self) -> usize { + self.snaps_status.iter().filter(|s| s.modified).count() + } + + pub fn count_forget_snaps(&self) -> usize { + self.snaps_status.iter().filter(|s| s.to_forget).count() + } + + // process marked snapshots (or the current one if none is marked) + // the process function must return true if it modified the snapshot, else false + pub fn process_marked_snaps(&mut self, mut process: impl FnMut(&mut SnapshotFile) -> bool) { + let has_mark = self.has_mark(); + + if !has_mark { + self.toggle_mark(); + } + + for ((snap, status), original_snap) in self + .snapshots + .iter_mut() + .zip(self.snaps_status.iter_mut()) + .zip(self.original_snapshots.iter()) + { + if status.marked && process(snap) { + // Note that snap impls Eq, but only by comparing the time! + status.modified = + serde_json::to_string(snap).ok() != serde_json::to_string(original_snap).ok(); + } + } + + if !has_mark { + self.toggle_mark(); + } + self.update_table(); + } + + pub fn get_snap_entity(&mut self, f: impl Fn(&SnapshotFile) -> String) -> String { + let has_mark = self.has_mark(); + + if !has_mark { + self.toggle_mark(); + } + + let entity = self + .snapshots + .iter() + .zip(self.snaps_status.iter()) + .filter_map(|(snap, status)| status.marked.then_some(f(snap))) + .reduce(|entity, e| if entity == e { e } else { String::new() }) + .unwrap_or_default(); + + if !has_mark { + self.toggle_mark(); + } + entity + } + + pub fn get_label(&mut self) -> String { + self.get_snap_entity(|snap| snap.label.clone()) + } + + pub fn get_tags(&mut self) -> String { + self.get_snap_entity(|snap| snap.tags.formatln()) + } + + pub fn get_description(&mut self) -> String { + self.get_snap_entity(|snap| snap.description.clone().unwrap_or_default()) + } + + pub fn get_filter(&self) -> Result { + Ok(toml::to_string_pretty(&self.filter)?) + } + + pub fn set_filter(&mut self, filter: String) { + if let Ok(filter) = toml::from_str::(&filter) { + self.filter = filter; + self.apply_view(); + } + } + + pub fn set_label(&mut self, label: String) { + self.process_marked_snaps(|snap| { + if snap.label == label { + return false; + } + snap.label.clone_from(&label); + true + }); + } + + pub fn clear_label(&mut self) { + self.set_label(String::new()); + } + + pub fn set_description(&mut self, desc: String) { + let desc = if desc.is_empty() { None } else { Some(desc) }; + self.process_marked_snaps(|snap| { + if snap.description == desc { + return false; + } + snap.description.clone_from(&desc); + true + }); + } + + pub fn clear_description(&mut self) { + self.set_description(String::new()); + } + + pub fn add_tags(&mut self, tags: String) { + let tags = vec![StringList::from_str(&tags).unwrap()]; + self.process_marked_snaps(|snap| snap.add_tags(tags.clone())); + } + + pub fn set_tags(&mut self, tags: String) { + let tags = vec![StringList::from_str(&tags).unwrap()]; + self.process_marked_snaps(|snap| snap.set_tags(tags.clone())); + } + + pub fn remove_tags(&mut self, tags: String) { + let tags = vec![StringList::from_str(&tags).unwrap()]; + self.process_marked_snaps(|snap| snap.remove_tags(&tags)); + } + + pub fn clear_tags(&mut self) { + let no_tags = vec![StringList::default()]; + self.process_marked_snaps(|snap| snap.set_tags(no_tags.clone())); + } + + pub fn set_delete_protection_to(&mut self, delete: DeleteOption) { + self.process_marked_snaps(|snap| { + if snap.delete == delete { + return false; + } + snap.delete = delete; + true + }); + } + + pub fn toggle_to_forget(&mut self) { + let has_mark = self.has_mark(); + + if !has_mark { + self.toggle_mark(); + } + + let now = Local::now(); + for (snap, status) in self.snapshots.iter_mut().zip(self.snaps_status.iter_mut()) { + if status.marked { + if status.to_forget { + status.to_forget = false; + } else if !snap.must_keep(now) { + status.to_forget = true; + } + } + } + + if !has_mark { + self.toggle_mark(); + } + self.update_table(); + } + + pub fn clear_to_forget(&mut self) { + for status in self.snaps_status.iter_mut() { + status.to_forget = false; + } + self.update_table(); + } + + pub fn apply_input(&mut self, input: String) { + match self.current_screen { + CurrentScreen::EnterLabel(_) => self.set_label(input), + CurrentScreen::EnterDescription(_) => self.set_description(input), + CurrentScreen::EnterAddTags(_) => self.add_tags(input), + CurrentScreen::EnterSetTags(_) => self.set_tags(input), + CurrentScreen::EnterRemoveTags(_) => self.remove_tags(input), + CurrentScreen::EnterFilter(_) => self.set_filter(input), + _ => {} + } + } + + pub fn set_delete_protection(&mut self) { + self.set_delete_protection_to(DeleteOption::Never); + } + + pub fn clear_delete_protection(&mut self) { + self.set_delete_protection_to(DeleteOption::NotSet); + } + + pub fn write(&mut self) -> Result<()> { + if !self.has_modified() && self.count_forget_snaps() == 0 { + return Ok(()); + }; + + let save_snaps: Vec<_> = self + .snapshots + .iter() + .zip(self.snaps_status.iter()) + .filter_map(|(snap, status)| (status.modified && !status.to_forget).then_some(snap)) + .cloned() + .collect(); + let old_snap_ids = save_snaps.iter().map(|sn| sn.id); + let snap_ids_to_forget = self + .snapshots + .iter() + .zip(self.snaps_status.iter()) + .filter_map(|(snap, status)| status.to_forget.then_some(snap.id)); + let delete_ids: Vec<_> = old_snap_ids.chain(snap_ids_to_forget).collect(); + self.repo.save_snapshots(save_snaps)?; + self.repo.delete_snapshots(&delete_ids)?; + // remove snapshots-to-reread + let ids: BTreeSet<_> = delete_ids.into_iter().collect(); + self.snapshots.retain(|snap| !ids.contains(&snap.id)); + // re-read snapshots + self.reread() + } + + // re-read all snapshots + pub fn reread(&mut self) -> Result<()> { + let snapshots = mem::take(&mut self.snapshots); + self.snapshots = self.repo.update_all_snapshots(snapshots)?; + self.snapshots + .sort_unstable_by(|sn1, sn2| sn1.cmp_group(self.group_by, sn2).then(sn1.cmp(sn2))); + self.snaps_status = vec![SnapStatus::default(); self.snapshots.len()]; + self.original_snapshots.clone_from(&self.snapshots); + self.table.widget.select(None); + self.apply_view(); + Ok(()) + } + + pub fn input(&mut self, event: Event) -> Result { + use KeyCode::*; + match &mut self.current_screen { + CurrentScreen::Snapshots => { + match event { + Event::Key(key) if key.kind == KeyEventKind::Press => { + if key.modifiers == KeyModifiers::CONTROL { + match key.code { + Char('f') => self.clear_to_forget(), + Char('x') => self.clear_marks(), + Char('l') => self.clear_label(), + Char('d') => self.clear_description(), + Char('t') => self.clear_tags(), + Char('p') => self.clear_delete_protection(), + Char('v') => self.reset_filter(), + _ => {} + } + } else { + match key.code { + Esc | Char('q') => { + self.current_screen = CurrentScreen::PromptExit(popup_prompt( + "exit rustic", + "do you want to exit? (y/n)".into(), + )); + } + Char('f') => self.toggle_to_forget(), + F(5) => self.reread()?, + Enter => { + if let Some(dir) = self.dir()? { + self.current_screen = CurrentScreen::Dir(dir); + } + } + Right => { + if self.extendable() { + self.extend(); + } else if let Some(dir) = self.dir()? { + self.current_screen = CurrentScreen::Dir(dir); + } + } + Char('+') => { + if self.extendable() { + self.extend(); + } + } + Left | Char('-') => self.collapse(), + Char('?') => { + self.current_screen = CurrentScreen::ShowHelp(popup_text( + "help", + HELP_TEXT.into(), + )); + } + Char('x') => { + self.toggle_mark(); + self.table.widget.next(); + } + Char('X') => self.toggle_mark_all(), + Char('v') => self.toggle_view(), + Char('V') => { + self.current_screen = CurrentScreen::EnterFilter(popup_input( + "set filter (Ctrl-s to confirm)", + "enter filter in TOML format", + &self.get_filter()?, + 15, + )); + } + Char('i') => { + self.current_screen = + CurrentScreen::SnapshotDetails(self.snapshot_details()); + } + Char('l') => { + self.current_screen = CurrentScreen::EnterLabel(popup_input( + "set label", + "enter label", + &self.get_label(), + 1, + )); + } + Char('d') => { + self.current_screen = + CurrentScreen::EnterDescription(popup_input( + "set description (Ctrl-s to confirm)", + "enter description", + &self.get_description(), + 5, + )); + } + Char('t') => { + self.current_screen = CurrentScreen::EnterAddTags(popup_input( + "add tags", + "enter tags", + "", + 1, + )); + } + Char('s') => { + self.current_screen = CurrentScreen::EnterSetTags(popup_input( + "set tags", + "enter tags", + &self.get_tags(), + 1, + )); + } + Char('r') => { + self.current_screen = CurrentScreen::EnterRemoveTags( + popup_input("remove tags", "enter tags", "", 1), + ); + } + // TODO: Allow to enter delete protection option + Char('p') => self.set_delete_protection(), + Char('w') => { + let msg = format!( + "Do you want to write {} modified and remove {} snapshots? (y/n)", + self.count_modified_snaps(), + self.count_forget_snaps() + ); + self.current_screen = CurrentScreen::PromptWrite(popup_prompt( + "write snapshots", + msg.into(), + )); + } + _ => self.table.input(event), + } + } + } + _ => {} + } + } + CurrentScreen::SnapshotDetails(_) | CurrentScreen::ShowHelp(_) => match event { + Event::Key(key) if key.kind == KeyEventKind::Press => { + if matches!( + key.code, + Char('q') | Esc | Enter | Char(' ') | Char('i') | Char('?') + ) { + self.current_screen = CurrentScreen::Snapshots; + } + } + _ => {} + }, + CurrentScreen::EnterLabel(prompt) + | CurrentScreen::EnterDescription(prompt) + | CurrentScreen::EnterAddTags(prompt) + | CurrentScreen::EnterSetTags(prompt) + | CurrentScreen::EnterRemoveTags(prompt) + | CurrentScreen::EnterFilter(prompt) => match prompt.input(event) { + TextInputResult::Cancel => self.current_screen = CurrentScreen::Snapshots, + TextInputResult::Input(input) => { + self.apply_input(input); + self.current_screen = CurrentScreen::Snapshots; + } + TextInputResult::None => {} + }, + CurrentScreen::PromptWrite(prompt) => match prompt.input(event) { + PromptResult::Ok => { + self.write()?; + self.current_screen = CurrentScreen::Snapshots; + } + PromptResult::Cancel => self.current_screen = CurrentScreen::Snapshots, + PromptResult::None => {} + }, + CurrentScreen::PromptExit(prompt) => match prompt.input(event) { + PromptResult::Ok => return Ok(true), + PromptResult::Cancel => self.current_screen = CurrentScreen::Snapshots, + PromptResult::None => {} + }, + CurrentScreen::Dir(dir) => match dir.input(event)? { + SnapshotResult::Exit => return Ok(true), + SnapshotResult::Return => self.current_screen = CurrentScreen::Snapshots, + SnapshotResult::None => {} + }, + } + Ok(false) + } + + pub fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + if let CurrentScreen::Dir(dir) = &mut self.current_screen { + dir.draw(area, f); + return; + } + + let rects = Layout::vertical([Constraint::Min(0), Constraint::Length(1)]).split(area); + + // draw the table + self.table.draw(rects[0], f); + + // draw the footer + let buffer_bg = tailwind::SLATE.c950; + let row_fg = tailwind::SLATE.c200; + let info_footer = Paragraph::new(Line::from(INFO_TEXT)) + .style(Style::new().fg(row_fg).bg(buffer_bg)) + .centered(); + f.render_widget(info_footer, rects[1]); + + // draw popups + match &mut self.current_screen { + CurrentScreen::SnapshotDetails(popup) => popup.draw(area, f), + CurrentScreen::ShowHelp(popup) => popup.draw(area, f), + CurrentScreen::EnterLabel(popup) + | CurrentScreen::EnterDescription(popup) + | CurrentScreen::EnterAddTags(popup) + | CurrentScreen::EnterSetTags(popup) + | CurrentScreen::EnterRemoveTags(popup) + | CurrentScreen::EnterFilter(popup) => popup.draw(area, f), + CurrentScreen::PromptWrite(popup) | CurrentScreen::PromptExit(popup) => { + popup.draw(area, f); + } + _ => {} + } + } +} diff --git a/src/commands/tui/tree.rs b/src/commands/tui/tree.rs new file mode 100644 index 000000000..9df215966 --- /dev/null +++ b/src/commands/tui/tree.rs @@ -0,0 +1,144 @@ +#[derive(PartialEq, Eq)] +pub struct TreeNode { + pub data: Data, + pub open: bool, + pub children: Vec>, +} + +#[derive(PartialEq, Eq)] +pub enum Tree { + Node(TreeNode), + Leaf(LeafData), +} + +impl Tree { + pub fn leaf(data: LeafData) -> Self { + Self::Leaf(data) + } + pub fn node(data: Data, open: bool, children: Vec) -> Self { + Self::Node(TreeNode { + data, + open, + children, + }) + } + + pub fn child_count(&self) -> usize { + match self { + Self::Leaf(_) => 0, + Self::Node(TreeNode { children, .. }) => { + children.len() + children.iter().map(Self::child_count).sum::() + } + } + } + + pub fn leaf_data(&self) -> Option<&LeafData> { + match self { + Self::Node(_) => None, + Self::Leaf(data) => Some(data), + } + } + + pub fn openable(&self) -> bool { + matches!(self, Self::Node(node) if !node.open) + } + + pub fn open(&mut self) { + if let Self::Node(node) = self { + node.open = true; + } + } + pub fn close(&mut self) { + if let Self::Node(node) = self { + node.open = false; + } + } + + pub fn iter(&self) -> impl Iterator> { + TreeIter { + tree: Some(self), + iter_stack: Vec::new(), + only_open: false, + } + } + + // iter open tree descending only into open nodes. + // Note: This iterator skips the root node! + pub fn iter_open(&self) -> impl Iterator> { + TreeIter { + tree: Some(self), + iter_stack: Vec::new(), + only_open: true, + } + .skip(1) + } + + pub fn nth_mut(&mut self, n: usize) -> Option<&mut Self> { + let mut count = 0; + let mut tree = Some(self); + let mut iter_stack = Vec::new(); + loop { + if count == n + 1 { + return tree; + } + let item = tree?; + if let Self::Node(node) = item { + if node.open { + iter_stack.push(node.children.iter_mut()); + } + } + tree = next_from_iter_stack(&mut iter_stack); + count += 1; + } + } +} + +pub struct TreeIterItem<'a, Data, LeadData> { + pub depth: usize, + pub tree: &'a Tree, +} + +impl<'a, Data, LeafData> TreeIterItem<'a, Data, LeafData> { + pub fn leaf_data(&self) -> Option<&LeafData> { + self.tree.leaf_data() + } +} + +pub struct TreeIter<'a, Data, LeafData> { + tree: Option<&'a Tree>, + iter_stack: Vec>>, + only_open: bool, +} + +impl<'a, Data, LeafData> Iterator for TreeIter<'a, Data, LeafData> { + type Item = TreeIterItem<'a, Data, LeafData>; + fn next(&mut self) -> Option { + let item = self.tree?; + let depth = self.iter_stack.len(); + if let Tree::Node(node) = item { + if !self.only_open || node.open { + self.iter_stack.push(node.children.iter()); + } + } + + self.tree = next_from_iter_stack(&mut self.iter_stack); + Some(TreeIterItem { depth, tree: item }) + } +} + +// helper function to get next item from iteration stack when iterating over a Tree +fn next_from_iter_stack(stack: &mut Vec>) -> Option { + loop { + match stack.pop() { + None => { + break None; + } + Some(mut iter) => { + if let Some(next) = iter.next() { + stack.push(iter); + break Some(next); + } + } + } + } +} diff --git a/src/commands/tui/widgets.rs b/src/commands/tui/widgets.rs new file mode 100644 index 000000000..e9fde214c --- /dev/null +++ b/src/commands/tui/widgets.rs @@ -0,0 +1,102 @@ +mod popup; +mod prompt; +mod select_table; +mod sized_gauge; +mod sized_paragraph; +mod sized_table; +mod text_input; +mod with_block; + +pub use popup::*; +pub use prompt::*; +use ratatui::widgets::block::Title; +pub use select_table::*; +pub use sized_gauge::*; +pub use sized_paragraph::*; +pub use sized_table::*; +pub use text_input::*; +pub use with_block::*; + +use crossterm::event::Event; +use crossterm::event::{KeyCode, KeyEvent, KeyEventKind}; +use ratatui::prelude::*; +use ratatui::widgets::*; + +pub trait ProcessEvent { + type Result; + fn input(&mut self, event: Event) -> Self::Result; +} + +pub trait SizedWidget { + fn height(&self) -> Option { + None + } + fn width(&self) -> Option { + None + } +} + +pub trait Draw { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>); +} + +// the widgets we are using and convenience builders +pub type PopUpInput = PopUp>; +pub fn popup_input( + title: impl Into>, + text: &str, + initial: &str, + lines: u16, +) -> PopUpInput { + PopUp(WithBlock::new( + TextInput::new(Some(text), initial, lines, true), + Block::bordered().title(title), + )) +} + +pub fn popup_scrollable_text( + title: impl Into>, + text: &str, + lines: u16, +) -> PopUpInput { + PopUp(WithBlock::new( + TextInput::new(None, text, lines, false), + Block::bordered().title(title), + )) +} + +pub type PopUpText = PopUp>; +pub fn popup_text(title: impl Into>, text: Text<'static>) -> PopUpText { + PopUp(WithBlock::new( + SizedParagraph::new(text), + Block::bordered().title(title), + )) +} + +pub type PopUpTable = PopUp>; +pub fn popup_table( + title: impl Into>, + content: Vec>>, +) -> PopUpTable { + PopUp(WithBlock::new( + SizedTable::new(content), + Block::bordered().title(title), + )) +} + +pub type PopUpPrompt = Prompt; +pub fn popup_prompt(title: &'static str, text: Text<'static>) -> PopUpPrompt { + Prompt(popup_text(title, text)) +} + +pub type PopUpGauge = PopUp>; +pub fn popup_gauge( + title: impl Into>, + text: Span<'static>, + ratio: f64, +) -> PopUpGauge { + PopUp(WithBlock::new( + SizedGauge::new(text, ratio), + Block::bordered().title(title), + )) +} diff --git a/src/commands/tui/widgets/popup.rs b/src/commands/tui/widgets/popup.rs new file mode 100644 index 000000000..d861bd5b4 --- /dev/null +++ b/src/commands/tui/widgets/popup.rs @@ -0,0 +1,38 @@ +use super::*; + +// Make a popup from a SizedWidget +pub struct PopUp(pub T); + +impl ProcessEvent for PopUp { + type Result = T::Result; + fn input(&mut self, event: Event) -> Self::Result { + self.0.input(event) + } +} + +impl Draw for PopUp { + fn draw(&mut self, mut area: Rect, f: &mut Frame<'_>) { + // center vertically + if let Some(h) = self.0.height() { + let layout = Layout::vertical([ + Constraint::Min(1), + Constraint::Length(h), + Constraint::Min(1), + ]); + area = layout.split(area)[1]; + } + + // center horizontally + if let Some(w) = self.0.width() { + let layout = Layout::horizontal([ + Constraint::Min(1), + Constraint::Length(w), + Constraint::Min(1), + ]); + area = layout.split(area)[1]; + } + + f.render_widget(Clear, area); + self.0.draw(area, f); + } +} diff --git a/src/commands/tui/widgets/prompt.rs b/src/commands/tui/widgets/prompt.rs new file mode 100644 index 000000000..7b177846b --- /dev/null +++ b/src/commands/tui/widgets/prompt.rs @@ -0,0 +1,39 @@ +use super::*; + +pub struct Prompt(pub T); + +pub enum PromptResult { + Ok, + Cancel, + None, +} + +impl SizedWidget for Prompt { + fn height(&self) -> Option { + self.0.height() + } + fn width(&self) -> Option { + self.0.width() + } +} + +impl Draw for Prompt { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + self.0.draw(area, f); + } +} + +impl ProcessEvent for Prompt { + type Result = PromptResult; + fn input(&mut self, event: Event) -> PromptResult { + use KeyCode::*; + match event { + Event::Key(key) if key.kind == KeyEventKind::Press => match key.code { + Char('q') | Char('n') | Char('c') | Esc => PromptResult::Cancel, + Enter | Char('y') | Char('j') | Char(' ') => PromptResult::Ok, + _ => PromptResult::None, + }, + _ => PromptResult::None, + } + } +} diff --git a/src/commands/tui/widgets/select_table.rs b/src/commands/tui/widgets/select_table.rs new file mode 100644 index 000000000..081577292 --- /dev/null +++ b/src/commands/tui/widgets/select_table.rs @@ -0,0 +1,196 @@ +use super::*; +use std::iter::once; +use style::palette::tailwind; + +struct TableColors { + buffer_bg: Color, + header_bg: Color, + header_fg: Color, + row_fg: Color, + selected_style_fg: Color, + normal_row_color: Color, + alt_row_color: Color, +} + +impl TableColors { + fn new(color: &tailwind::Palette) -> Self { + Self { + buffer_bg: tailwind::SLATE.c950, + header_bg: color.c900, + header_fg: tailwind::SLATE.c200, + row_fg: tailwind::SLATE.c200, + selected_style_fg: color.c400, + normal_row_color: tailwind::SLATE.c950, + alt_row_color: tailwind::SLATE.c900, + } + } +} + +pub struct SelectTable { + header: Vec>, + table: Table<'static>, + state: TableState, + scroll_state: ScrollbarState, + rows: usize, + rows_display: usize, + row_height: usize, +} + +impl SelectTable { + pub fn new(header: Vec>) -> Self { + let table = Table::default(); + + Self { + header, + table, + state: TableState::default(), + scroll_state: ScrollbarState::new(0), + rows: 0, + rows_display: 0, + row_height: 0, + } + } + + pub fn set_content(&mut self, content: Vec>>, row_height: usize) { + let colors = TableColors::new(&tailwind::BLUE); + let selected_style = Style::default() + .add_modifier(Modifier::REVERSED) + .fg(colors.selected_style_fg); + + let header_style = Style::default().fg(colors.header_fg).bg(colors.header_bg); + + self.row_height = row_height; + let widths = once(&self.header) + .chain(content.iter()) + .map(|row| row.iter().map(Text::width).collect()) + .reduce(|widths: Vec, row| { + row.iter() + .zip(widths.iter()) + .map(|(r, w)| r.max(w)) + .cloned() + .collect() + }) + .unwrap_or_default(); + + self.rows = content.len(); + self.scroll_state = ScrollbarState::new(self.rows * self.row_height); + + let content = content.into_iter().enumerate().map(|(i, row)| { + let color = match i % 2 { + 0 => colors.normal_row_color, + _ => colors.alt_row_color, + }; + Row::new(row) + .style(Style::new().fg(colors.row_fg).bg(color)) + .height(self.row_height.try_into().unwrap()) + }); + + self.table = Table::default() + .header(Row::new(self.header.clone()).style(header_style)) + .row_highlight_style(selected_style) + .bg(colors.buffer_bg) + .widths(widths.iter().map(|w| { + (*w).try_into() + .ok() + .map_or(Constraint::Min(0), Constraint::Length) + })) + .flex(layout::Flex::SpaceBetween) + .rows(content); + } + + pub fn selected(&self) -> Option { + self.state.selected() + } + + pub fn select(&mut self, index: Option) { + self.state.select(index); + } + + pub fn set_to(&mut self, i: usize) { + self.state.select(Some(i)); + self.scroll_state = self.scroll_state.position(i * self.row_height); + } + + pub fn go_forward(&mut self, step: usize) { + if let Some(selected_old) = self.state.selected() { + let selected = (selected_old + step).min(self.rows - 1); + self.set_to(selected); + } + } + + pub fn go_back(&mut self, step: usize) { + if let Some(selected_old) = self.state.selected() { + let selected = selected_old.saturating_sub(step); + self.set_to(selected); + } + } + + pub fn next(&mut self) { + self.go_forward(1); + } + + pub fn page_down(&mut self) { + self.go_forward(self.rows_display); + } + + pub fn previous(&mut self) { + self.go_back(1); + } + + pub fn page_up(&mut self) { + self.go_back(self.rows_display); + } + + pub fn home(&mut self) { + if self.state.selected().is_some() { + self.set_to(0); + } + } + + pub fn end(&mut self) { + if self.state.selected().is_some() { + self.set_to(self.rows - 1); + } + } + + pub fn set_rows(&mut self, rows: usize) { + self.rows_display = rows / self.row_height; + } +} + +impl ProcessEvent for SelectTable { + type Result = (); + fn input(&mut self, event: Event) { + use KeyCode::*; + match event { + Event::Key(key) if key.kind == KeyEventKind::Press => match key.code { + Down => self.next(), + Up => self.previous(), + PageDown => self.page_down(), + PageUp => self.page_up(), + Home => self.home(), + End => self.end(), + _ => {} + }, + _ => {} + } + } +} + +impl SizedWidget for SelectTable {} + +impl Draw for SelectTable { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + self.set_rows(area.height.into()); + let chunks = Layout::horizontal([Constraint::Min(0), Constraint::Length(1)]).split(area); + f.render_stateful_widget(&self.table, chunks[0], &mut self.state); + f.render_stateful_widget( + Scrollbar::default() + .orientation(ScrollbarOrientation::VerticalRight) + .begin_symbol(None) + .end_symbol(None), + chunks[1], + &mut self.scroll_state, + ); + } +} diff --git a/src/commands/tui/widgets/sized_gauge.rs b/src/commands/tui/widgets/sized_gauge.rs new file mode 100644 index 000000000..e84738690 --- /dev/null +++ b/src/commands/tui/widgets/sized_gauge.rs @@ -0,0 +1,33 @@ +use super::*; + +pub struct SizedGauge { + p: Gauge<'static>, + width: Option, +} + +impl SizedGauge { + pub fn new(text: Span<'static>, ratio: f64) -> Self { + let width = text.width().try_into().ok(); + let p = Gauge::default() + .gauge_style(Style::default().fg(Color::Blue)) + .use_unicode(true) + .label(text) + .ratio(ratio); + Self { p, width } + } +} + +impl SizedWidget for SizedGauge { + fn width(&self) -> Option { + self.width.map(|w| w + 10) + } + fn height(&self) -> Option { + Some(1) + } +} + +impl Draw for SizedGauge { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + f.render_widget(&self.p, area); + } +} diff --git a/src/commands/tui/widgets/sized_paragraph.rs b/src/commands/tui/widgets/sized_paragraph.rs new file mode 100644 index 000000000..391abd26d --- /dev/null +++ b/src/commands/tui/widgets/sized_paragraph.rs @@ -0,0 +1,31 @@ +use super::*; + +pub struct SizedParagraph { + p: Paragraph<'static>, + height: Option, + width: Option, +} + +impl SizedParagraph { + pub fn new(text: Text<'static>) -> Self { + let height = text.height().try_into().ok(); + let width = text.width().try_into().ok(); + let p = Paragraph::new(text); + Self { p, height, width } + } +} + +impl SizedWidget for SizedParagraph { + fn width(&self) -> Option { + self.width + } + fn height(&self) -> Option { + self.height + } +} + +impl Draw for SizedParagraph { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + f.render_widget(&self.p, area); + } +} diff --git a/src/commands/tui/widgets/sized_table.rs b/src/commands/tui/widgets/sized_table.rs new file mode 100644 index 000000000..506c0f48e --- /dev/null +++ b/src/commands/tui/widgets/sized_table.rs @@ -0,0 +1,63 @@ +use super::*; + +pub struct SizedTable { + table: Table<'static>, + height: usize, + width: usize, +} + +impl SizedTable { + pub fn new(content: Vec>>) -> Self { + let height = content + .iter() + .map(|row| row.iter().map(Text::height).max().unwrap_or_default()) + .sum::(); + + let widths = content + .iter() + .map(|row| row.iter().map(Text::width).collect()) + .reduce(|widths: Vec, row| { + row.iter() + .zip(widths.iter()) + .map(|(r, w)| r.max(w)) + .cloned() + .collect() + }) + .unwrap_or_default(); + + let width = widths + .iter() + .cloned() + .reduce(|width, w| width + w + 1) // +1 because of space between entries + .unwrap_or_default(); + + let rows = content.into_iter().map(Row::new); + let table = Table::default() + .widths(widths.iter().map(|w| { + (*w).try_into() + .ok() + .map_or(Constraint::Min(0), Constraint::Length) + })) + .rows(rows); + Self { + table, + height, + width, + } + } +} + +impl SizedWidget for SizedTable { + fn height(&self) -> Option { + self.height.try_into().ok() + } + fn width(&self) -> Option { + self.width.try_into().ok() + } +} + +impl Draw for SizedTable { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + f.render_widget(&self.table, area); + } +} diff --git a/src/commands/tui/widgets/text_input.rs b/src/commands/tui/widgets/text_input.rs new file mode 100644 index 000000000..9295d760e --- /dev/null +++ b/src/commands/tui/widgets/text_input.rs @@ -0,0 +1,88 @@ +use super::*; + +use crossterm::event::KeyModifiers; +use tui_textarea::{CursorMove, TextArea}; + +pub struct TextInput { + textarea: TextArea<'static>, + lines: u16, + changeable: bool, +} + +pub enum TextInputResult { + Cancel, + Input(String), + None, +} + +impl TextInput { + pub fn new(text: Option<&str>, initial: &str, lines: u16, changeable: bool) -> Self { + let mut textarea = TextArea::default(); + textarea.set_style(Style::default()); + if let Some(text) = text { + textarea.set_placeholder_text(text); + } + _ = textarea.insert_str(initial); + if !changeable { + textarea.move_cursor(CursorMove::Top); + } + Self { + textarea, + lines, + changeable, + } + } +} + +impl SizedWidget for TextInput { + fn height(&self) -> Option { + Some(self.lines) + } +} + +impl Draw for TextInput { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + f.render_widget(&self.textarea, area); + } +} + +impl ProcessEvent for TextInput { + type Result = TextInputResult; + fn input(&mut self, event: Event) -> TextInputResult { + if let Event::Key(key) = event { + let KeyEvent { + code, modifiers, .. + } = key; + use KeyCode::*; + if self.changeable { + match (code, modifiers) { + (Esc, _) => return TextInputResult::Cancel, + (Enter, _) if self.lines == 1 => { + return TextInputResult::Input(self.textarea.lines().join("\n")); + } + (Char('s'), KeyModifiers::CONTROL) => { + return TextInputResult::Input(self.textarea.lines().join("\n")); + } + _ => { + _ = self.textarea.input(key); + } + } + } else { + match (code, modifiers) { + (Esc | Enter | Char('q') | Char('x'), _) => return TextInputResult::Cancel, + (Home, _) => { + self.textarea.move_cursor(CursorMove::Top); + } + (End, _) => { + self.textarea.move_cursor(CursorMove::Bottom); + } + (PageDown | PageUp | Up | Down, _) => { + _ = self.textarea.input(key); + } + _ => {} + } + } + } + TextInputResult::None + } +} diff --git a/src/commands/tui/widgets/with_block.rs b/src/commands/tui/widgets/with_block.rs new file mode 100644 index 000000000..7a8b4b126 --- /dev/null +++ b/src/commands/tui/widgets/with_block.rs @@ -0,0 +1,57 @@ +use super::*; +use layout::Size; + +pub struct WithBlock { + pub block: Block<'static>, + pub widget: T, +} + +impl WithBlock { + pub fn new(widget: T, block: Block<'static>) -> Self { + Self { block, widget } + } + + // Note: this could be a method of self.block, but is unfortunately not present + // So we compute ourselves using self.block.inner() on an artificial Rect. + fn size_diff(&self) -> Size { + let rect = Rect { + x: 0, + y: 0, + width: u16::MAX, + height: u16::MAX, + }; + let inner = self.block.inner(rect); + Size { + width: rect.as_size().width - inner.as_size().width, + height: rect.as_size().height - inner.as_size().height, + } + } +} + +impl ProcessEvent for WithBlock { + type Result = T::Result; + fn input(&mut self, event: Event) -> Self::Result { + self.widget.input(event) + } +} + +impl SizedWidget for WithBlock { + fn height(&self) -> Option { + self.widget + .height() + .map(|h| h.saturating_add(self.size_diff().height)) + } + + fn width(&self) -> Option { + self.widget + .width() + .map(|w| w.saturating_add(self.size_diff().width)) + } +} + +impl Draw for WithBlock { + fn draw(&mut self, area: Rect, f: &mut Frame<'_>) { + f.render_widget(self.block.clone(), area); + self.widget.draw(self.block.inner(area), f); + } +} diff --git a/src/commands/webdav.rs b/src/commands/webdav.rs new file mode 100644 index 000000000..5dfdc4ccd --- /dev/null +++ b/src/commands/webdav.rs @@ -0,0 +1,143 @@ +//! `webdav` subcommand + +// ignore markdown clippy lints as we use doc-comments to generate clap help texts +#![allow(clippy::doc_markdown)] + +use std::net::ToSocketAddrs; + +use crate::{repository::CliIndexedRepo, status_err, Application, RusticConfig, RUSTIC_APP}; +use abscissa_core::{config::Override, Command, FrameworkError, Runnable, Shutdown}; +use anyhow::{anyhow, Result}; +use conflate::Merge; +use dav_server::{warp::dav_handler, DavHandler}; +use serde::{Deserialize, Serialize}; + +use rustic_core::vfs::{FilePolicy, IdenticalSnapshot, Latest, Vfs}; + +#[derive(Clone, Command, Default, Debug, clap::Parser, Serialize, Deserialize, Merge)] +#[serde(default, rename_all = "kebab-case", deny_unknown_fields)] +pub struct WebDavCmd { + /// Address to bind the webdav server to. [default: "localhost:8000"] + #[clap(long, value_name = "ADDRESS")] + #[merge(strategy=conflate::option::overwrite_none)] + address: Option, + + /// The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + path_template: Option, + + /// The time template to use to display times in the path template. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. [default: "%Y-%m-%d_%H-%M-%S"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + time_template: Option, + + /// Use symlinks. This may not be supported by all WebDAV clients + #[clap(long)] + #[merge(strategy=conflate::bool::overwrite_false)] + symlinks: bool, + + /// How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"] + #[clap(long)] + #[merge(strategy=conflate::option::overwrite_none)] + file_access: Option, + + /// Specify directly which snapshot/path to serve + #[clap(value_name = "SNAPSHOT[:PATH]")] + #[merge(strategy=conflate::option::overwrite_none)] + snapshot_path: Option, +} + +impl Override for WebDavCmd { + // Process the given command line options, overriding settings from + // a configuration file using explicit flags taken from command-line + // arguments. + fn override_config(&self, mut config: RusticConfig) -> Result { + let mut self_config = self.clone(); + // merge "webdav" section from config file, if given + self_config.merge(config.webdav); + config.webdav = self_config; + Ok(config) + } +} + +impl Runnable for WebDavCmd { + fn run(&self) { + if let Err(err) = RUSTIC_APP + .config() + .repository + .run_indexed(|repo| self.inner_run(repo)) + { + status_err!("{}", err); + RUSTIC_APP.shutdown(Shutdown::Crash); + }; + } +} + +impl WebDavCmd { + /// be careful about self VS RUSTIC_APP.config() usage + /// only the RUSTIC_APP.config() involves the TOML and ENV merged configurations + /// see https://github.com/rustic-rs/rustic/issues/1242 + fn inner_run(&self, repo: CliIndexedRepo) -> Result<()> { + let config = RUSTIC_APP.config(); + + let path_template = config + .webdav + .path_template + .clone() + .unwrap_or_else(|| "[{hostname}]/[{label}]/{time}".to_string()); + let time_template = config + .webdav + .time_template + .clone() + .unwrap_or_else(|| "%Y-%m-%d_%H-%M-%S".to_string()); + + let sn_filter = |sn: &_| config.snapshot_filter.matches(sn); + + let vfs = if let Some(snap) = &config.webdav.snapshot_path { + let node = repo.node_from_snapshot_path(snap, sn_filter)?; + Vfs::from_dir_node(&node) + } else { + let snapshots = repo.get_matching_snapshots(sn_filter)?; + let (latest, identical) = if config.webdav.symlinks { + (Latest::AsLink, IdenticalSnapshot::AsLink) + } else { + (Latest::AsDir, IdenticalSnapshot::AsDir) + }; + Vfs::from_snapshots(snapshots, &path_template, &time_template, latest, identical)? + }; + + let addr = config + .webdav + .address + .clone() + .unwrap_or_else(|| "localhost:8000".to_string()) + .to_socket_addrs()? + .next() + .ok_or_else(|| anyhow!("no address given"))?; + + let file_access = config.webdav.file_access.as_ref().map_or_else( + || { + if repo.config().is_hot == Some(true) { + Ok(FilePolicy::Forbidden) + } else { + Ok(FilePolicy::Read) + } + }, + |s| s.parse(), + )?; + + let dav_server = DavHandler::builder() + .filesystem(vfs.into_webdav_fs(repo, file_access)) + .build_handler(); + + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()? + .block_on(async { + warp::serve(dav_handler(dav_server)).run(addr).await; + }); + + Ok(()) + } +} diff --git a/src/config.rs b/src/config.rs index 254669924..f0145098c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,27 +4,33 @@ //! application's configuration file and/or command-line options //! for specifying it. +pub(crate) mod hooks; pub(crate) mod progress_options; +use std::fmt::Debug; use std::{collections::HashMap, path::PathBuf}; +use abscissa_core::{config::Config, path::AbsPathBuf, FrameworkError}; +use anyhow::Result; +use clap::{Parser, ValueHint}; +use conflate::Merge; use directories::ProjectDirs; - -use merge::Merge; - -use abscissa_core::config::Config; -use abscissa_core::path::AbsPathBuf; -use abscissa_core::FrameworkError; -use clap::Parser; use itertools::Itertools; use log::Level; -use rustic_core::RepositoryOptions; use serde::{Deserialize, Serialize}; +#[cfg(not(all(feature = "mount", feature = "webdav")))] +use toml::Value; + +#[cfg(feature = "mount")] +use crate::commands::mount::MountCmd; +#[cfg(feature = "webdav")] +use crate::commands::webdav::WebDavCmd; use crate::{ - commands::{backup::BackupCmd, copy::Targets, forget::ForgetOptions}, - config::progress_options::ProgressOptions, + commands::{backup::BackupCmd, copy::CopyCmd, forget::ForgetOptions}, + config::{hooks::Hooks, progress_options::ProgressOptions}, filtering::SnapshotFilter, + repository::AllRepositoryOptions, }; /// Rustic Configuration @@ -33,7 +39,7 @@ use crate::{ /// /// # Example // TODO: add example -#[derive(Clone, Default, Debug, Parser, Deserialize, Merge)] +#[derive(Clone, Default, Debug, Parser, Deserialize, Serialize, Merge)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct RusticConfig { /// Global options @@ -42,7 +48,7 @@ pub struct RusticConfig { /// Repository options #[clap(flatten, next_help_heading = "Repository options")] - pub repository: RepositoryOptions, + pub repository: AllRepositoryOptions, /// Snapshot filter options #[clap(flatten, next_help_heading = "Snapshot filter options")] @@ -54,11 +60,27 @@ pub struct RusticConfig { /// Copy options #[clap(skip)] - pub copy: Targets, + pub copy: CopyCmd, /// Forget options #[clap(skip)] pub forget: ForgetOptions, + + /// mount options + #[clap(skip)] + #[cfg(feature = "mount")] + pub mount: MountCmd, + #[cfg(not(feature = "mount"))] + #[merge(skip)] + pub mount: Option, + + /// webdav options + #[clap(skip)] + #[cfg(feature = "webdav")] + pub webdav: WebDavCmd, + #[cfg(not(feature = "webdav"))] + #[merge(skip)] + pub webdav: Option, } impl RusticConfig { @@ -83,7 +105,7 @@ impl RusticConfig { merge_logs.push((Level::Info, format!("using config {}", path.display()))); let mut config = Self::load_toml_file(AbsPathBuf::canonicalize(path)?)?; // if "use_profile" is defined in config file, merge the referenced profiles first - for profile in &config.global.use_profile.clone() { + for profile in &config.global.use_profiles.clone() { config.merge_profile(profile, merge_logs, Level::Warn)?; } self.merge(config); @@ -111,21 +133,27 @@ pub struct GlobalOptions { /// [default: "rustic"] #[clap( short = 'P', - long, + long = "use-profile", global = true, value_name = "PROFILE", env = "RUSTIC_USE_PROFILE" )] - #[merge(strategy = merge::vec::append)] - pub use_profile: Vec, + #[merge(strategy=conflate::vec::append)] + pub use_profiles: Vec, /// Only show what would be done without modifying anything. Does not affect read-only commands. #[clap(long, short = 'n', global = true, env = "RUSTIC_DRY_RUN")] - #[merge(strategy = merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] pub dry_run: bool, + /// Check if index matches pack files and read pack headers if neccessary + #[clap(long, global = true, env = "RUSTIC_CHECK_INDEX")] + #[merge(strategy=conflate::bool::overwrite_false)] + pub check_index: bool, + /// Use this log level [default: info] #[clap(long, global = true, env = "RUSTIC_LOG_LEVEL")] + #[merge(strategy=conflate::option::overwrite_none)] pub log_level: Option, /// Write log messages to the given file instead of printing them. @@ -133,7 +161,8 @@ pub struct GlobalOptions { /// # Note /// /// Warnings and errors are still additionally printed unless they are ignored by `--log-level` - #[clap(long, global = true, env = "RUSTIC_LOG_FILE", value_name = "LOGFILE")] + #[clap(long, global = true, env = "RUSTIC_LOG_FILE", value_name = "LOGFILE", value_hint = ValueHint::FilePath)] + #[merge(strategy=conflate::option::overwrite_none)] pub log_file: Option, /// Settings to customize progress bars @@ -141,18 +170,16 @@ pub struct GlobalOptions { #[serde(flatten)] pub progress_options: ProgressOptions, + /// Hooks + #[clap(skip)] + pub hooks: Hooks, + /// List of environment variables to set (only in config file) #[clap(skip)] - #[merge(strategy = extend)] + #[merge(strategy = conflate::hashmap::ignore)] pub env: HashMap, } -/// Extend the contents of a [`HashMap`] with the contents of another -/// [`HashMap`] with the same key and value types. -fn extend(left: &mut HashMap, right: HashMap) { - left.extend(right); -} - /// Get the paths to the config file /// /// # Arguments diff --git a/src/config/hooks.rs b/src/config/hooks.rs new file mode 100644 index 000000000..a3df66921 --- /dev/null +++ b/src/config/hooks.rs @@ -0,0 +1,107 @@ +//! rustic hooks configuration +//! +//! Hooks are commands that are executed before and after every rustic operation. +//! They can be used to run custom scripts or commands before and after a backup, +//! copy, forget, prune or other operation. +//! +//! Depending on the hook type, the command is being executed at a different point +//! in the lifecycle of the program. The following hooks are available: +//! +//! - global hooks +//! - repository hooks +//! - backup hooks +//! - specific source-related hooks + +use anyhow::Result; +use conflate::Merge; +use serde::{Deserialize, Serialize}; + +use rustic_core::CommandInput; + +#[derive(Debug, Default, Clone, Serialize, Deserialize, Merge)] +#[serde(default, rename_all = "kebab-case", deny_unknown_fields)] +pub struct Hooks { + /// Call this command before every rustic operation + #[merge(strategy = conflate::vec::append)] + pub run_before: Vec, + + /// Call this command after every successful rustic operation + #[merge(strategy = conflate::vec::append)] + pub run_after: Vec, + + /// Call this command after every failed rustic operation + #[merge(strategy = conflate::vec::append)] + pub run_failed: Vec, + + /// Call this command after every rustic operation + #[merge(strategy = conflate::vec::append)] + pub run_finally: Vec, + + #[serde(skip)] + #[merge(skip)] + pub context: String, +} + +impl Hooks { + pub fn with_context(&self, context: &str) -> Self { + let mut hooks = self.clone(); + hooks.context = context.to_string(); + hooks + } + + fn run_all(cmds: &[CommandInput], context: &str, what: &str) -> Result<()> { + for cmd in cmds { + cmd.run(context, what)?; + } + + Ok(()) + } + + pub fn run_before(&self) -> Result<()> { + Self::run_all(&self.run_before, &self.context, "run-before") + } + + pub fn run_after(&self) -> Result<()> { + Self::run_all(&self.run_after, &self.context, "run-after") + } + + pub fn run_failed(&self) -> Result<()> { + Self::run_all(&self.run_failed, &self.context, "run-failed") + } + + pub fn run_finally(&self) -> Result<()> { + Self::run_all(&self.run_finally, &self.context, "run-finally") + } + + /// Run the given closure using the specified hooks. + /// + /// Note: after a failure no error handling is done for the hooks `run_failed` + /// and `run_finally` which must run after. However, they already log a warning + /// or error depending on the `on_failure` setting. + pub fn use_with(&self, f: impl FnOnce() -> Result) -> Result { + match self.run_before() { + Ok(_) => match f() { + Ok(result) => match self.run_after() { + Ok(_) => { + self.run_finally()?; + Ok(result) + } + Err(err_after) => { + _ = self.run_finally(); + Err(err_after) + } + }, + Err(err_f) => { + _ = self.run_failed(); + _ = self.run_finally(); + Err(err_f) + } + }, + Err(err_before) => { + _ = self.run_failed(); + _ = self.run_finally(); + Err(err_before) + } + } + } +} diff --git a/src/config/progress_options.rs b/src/config/progress_options.rs index 2f4fcd4a6..fcb201e99 100644 --- a/src/config/progress_options.rs +++ b/src/config/progress_options.rs @@ -5,7 +5,7 @@ use std::{borrow::Cow, fmt::Write, time::Duration}; use indicatif::{HumanDuration, ProgressBar, ProgressState, ProgressStyle}; use clap::Parser; -use merge::Merge; +use conflate::Merge; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; @@ -19,7 +19,7 @@ use rustic_core::{Progress, ProgressBars}; pub struct ProgressOptions { /// Don't show any progress bar #[clap(long, global = true, env = "RUSTIC_NO_PROGRESS")] - #[merge(strategy=merge::bool::overwrite_false)] + #[merge(strategy=conflate::bool::overwrite_false)] pub no_progress: bool, /// Interval to update progress bars @@ -31,6 +31,7 @@ pub struct ProgressOptions { conflicts_with = "no_progress" )] #[serde_as(as = "Option")] + #[merge(strategy=conflate::option::overwrite_none)] pub progress_interval: Option, } @@ -131,11 +132,13 @@ impl Progress for RusticProgress { ProgressType::Bytes => { self.0.set_style( ProgressStyle::default_bar() - .with_key("my_eta", |s: &ProgressState, w: &mut dyn Write| - match (s.pos(), s.len()){ - (pos,Some(len)) if pos != 0 => write!(w,"{:#}", HumanDuration(Duration::from_secs(s.elapsed().as_secs() * (len-pos)/pos))), + .with_key("my_eta", |s: &ProgressState, w: &mut dyn Write| { + let _ = match (s.pos(), s.len()){ + // Extra checks to prevent panics from dividing by zero or subtract overflow + (pos,Some(len)) if pos != 0 && len > pos => write!(w,"{:#}", HumanDuration(Duration::from_secs(s.elapsed().as_secs() * (len-pos)/pos))), (_, _) => write!(w,"-"), - }.unwrap()) + }; + }) .template("[{elapsed_precise}] {prefix:30} {bar:40.cyan/blue} {bytes:>10}/{total_bytes:10} {bytes_per_sec:12} (ETA {my_eta})") .unwrap() ); diff --git a/src/filtering.rs b/src/filtering.rs index fefb7ae1c..93327c0ed 100644 --- a/src/filtering.rs +++ b/src/filtering.rs @@ -1,11 +1,20 @@ use crate::error::RhaiErrorKinds; +use bytesize::ByteSize; +use derive_more::derive::Display; use log::warn; use rustic_core::{repofile::SnapshotFile, StringList}; -use std::{error::Error, str::FromStr}; +use std::{ + error::Error, + fmt::{Debug, Display}, + str::FromStr, +}; +use cached::proc_macro::cached; +use chrono::{DateTime, Local, NaiveTime}; +use conflate::Merge; use rhai::{serde::to_dynamic, Dynamic, Engine, FnPtr, AST}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; /// A function to filter snapshots @@ -24,6 +33,17 @@ impl FromStr for SnapshotFn { } } +#[cached(key = "String", convert = r#"{ s.to_string() }"#, size = 1)] +fn string_to_fn(s: &str) -> Option { + match SnapshotFn::from_str(s) { + Ok(filter_fn) => Some(filter_fn), + Err(err) => { + warn!("Error evaluating filter-fn {s}: {err}",); + None + } + } +} + impl SnapshotFn { /// Call the function with a [`SnapshotFile`] /// @@ -43,35 +63,72 @@ impl SnapshotFn { } #[serde_as] -#[derive(Clone, Default, Debug, Deserialize, merge::Merge, clap::Parser)] +#[derive(Clone, Default, Debug, Serialize, Deserialize, Merge, clap::Parser)] #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] pub struct SnapshotFilter { /// Hostname to filter (can be specified multiple times) - #[clap(long, global = true, value_name = "HOSTNAME")] - #[merge(strategy=merge::vec::overwrite_empty)] - filter_host: Vec, + #[clap(long = "filter-host", global = true, value_name = "HOSTNAME")] + #[merge(strategy=conflate::vec::overwrite_empty)] + filter_hosts: Vec, /// Label to filter (can be specified multiple times) - #[clap(long, global = true, value_name = "LABEL")] - #[merge(strategy=merge::vec::overwrite_empty)] - filter_label: Vec, + #[clap(long = "filter-label", global = true, value_name = "LABEL")] + #[merge(strategy=conflate::vec::overwrite_empty)] + filter_labels: Vec, /// Path list to filter (can be specified multiple times) #[clap(long, global = true, value_name = "PATH[,PATH,..]")] #[serde_as(as = "Vec")] - #[merge(strategy=merge::vec::overwrite_empty)] + #[merge(strategy=conflate::vec::overwrite_empty)] filter_paths: Vec, + /// Path list to filter exactly (no superset) as given (can be specified multiple times) + #[clap(long, global = true, value_name = "PATH[,PATH,..]")] + #[serde_as(as = "Vec")] + #[merge(strategy=conflate::vec::overwrite_empty)] + filter_paths_exact: Vec, + /// Tag list to filter (can be specified multiple times) #[clap(long, global = true, value_name = "TAG[,TAG,..]")] #[serde_as(as = "Vec")] - #[merge(strategy=merge::vec::overwrite_empty)] + #[merge(strategy=conflate::vec::overwrite_empty)] filter_tags: Vec, + /// Tag list to filter exactly (no superset) as given (can be specified multiple times) + #[clap(long, global = true, value_name = "TAG[,TAG,..]")] + #[serde_as(as = "Vec")] + #[merge(strategy=conflate::vec::overwrite_empty)] + filter_tags_exact: Vec, + + /// Only use snapshots which are taken after the given given date/time + #[serde_as(as = "Option")] + #[clap(long, global = true, value_name = "DATE(TIME)")] + #[merge(strategy=conflate::option::overwrite_none)] + filter_after: Option, + + /// Only use snapshots which are taken before the given given date/time + #[serde_as(as = "Option")] + #[clap(long, global = true, value_name = "DATE(TIME)")] + #[merge(strategy=conflate::option::overwrite_none)] + filter_before: Option, + + /// Only use snapshots with total size in given range + #[serde_as(as = "Option")] + #[clap(long, global = true, value_name = "SIZE")] + #[merge(strategy=conflate::option::overwrite_none)] + filter_size: Option, + + /// Only use snapshots with size added to the repo in given range + #[serde_as(as = "Option")] + #[clap(long, global = true, value_name = "SIZE")] + #[merge(strategy=conflate::option::overwrite_none)] + filter_size_added: Option, + /// Function to filter snapshots #[clap(long, global = true, value_name = "FUNC")] #[serde_as(as = "Option")] - filter_fn: Option, + #[merge(strategy=conflate::option::overwrite_none)] + filter_fn: Option, } impl SnapshotFilter { @@ -87,24 +144,153 @@ impl SnapshotFilter { #[must_use] pub fn matches(&self, snapshot: &SnapshotFile) -> bool { if let Some(filter_fn) = &self.filter_fn { - match filter_fn.call::(snapshot) { - Ok(result) => { - if !result { - return false; + if let Some(func) = string_to_fn(filter_fn) { + match func.call::(snapshot) { + Ok(result) => { + if !result { + return false; + } + } + Err(err) => { + warn!( + "Error evaluating filter-fn for snapshot {}: {err}", + snapshot.id + ); } - } - Err(err) => { - warn!( - "Error evaluating filter-fn for snapshot {}: {err}", - snapshot.id - ); } } } + // For the `Option`s we check if the option is set and the condition is not matched. In this case we can early return false. + if matches!(&self.filter_after, Some(after) if !after.matches(snapshot.time)) + || matches!(&self.filter_before, Some(before) if !before.matches(snapshot.time)) + || matches!((&self.filter_size,&snapshot.summary), (Some(size),Some(summary)) if !size.matches(summary.total_bytes_processed)) + || matches!((&self.filter_size_added,&snapshot.summary), (Some(size),Some(summary)) if !size.matches(summary.data_added)) + { + return false; + } + + // For the the `Vec`s we have two possibilities: + // - There exists a suitable matches method on the snapshot item + // (this automatically handles empty filter correctly): snapshot.paths.matches(&self.filter_paths) && snapshot.tags.matches(&self.filter_tags) - && (self.filter_host.is_empty() || self.filter_host.contains(&snapshot.hostname)) - && (self.filter_label.is_empty() || self.filter_label.contains(&snapshot.label)) + // - manually check if the snapshot item is contained in the `Vec` + // but only if the `Vec` is not empty. + // If it is empty, no condition is given. + && (self.filter_paths_exact.is_empty() + || self.filter_paths_exact.contains(&snapshot.paths)) + && (self.filter_tags_exact.is_empty() + || self.filter_tags_exact.contains(&snapshot.tags)) + && (self.filter_hosts.is_empty() || self.filter_hosts.contains(&snapshot.hostname)) + && (self.filter_labels.is_empty() || self.filter_labels.contains(&snapshot.label)) + } +} + +#[derive(Debug, Clone, Display)] +struct AfterDate(DateTime); + +impl AfterDate { + fn matches(&self, datetime: DateTime) -> bool { + self.0 < datetime + } +} + +impl FromStr for AfterDate { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + let before_midnight = NaiveTime::from_hms_nano_opt(23, 59, 59, 999_999_999).unwrap(); + let datetime = dateparser::parse_with(s, &Local, before_midnight)?; + Ok(Self(datetime.into())) + } +} + +#[derive(Debug, Clone, Display)] +struct BeforeDate(DateTime); + +impl BeforeDate { + fn matches(&self, datetime: DateTime) -> bool { + datetime < self.0 + } +} + +impl FromStr for BeforeDate { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result { + let midnight = NaiveTime::from_hms_opt(0, 0, 0).unwrap(); + let datetime = dateparser::parse_with(s, &Local, midnight)?; + Ok(Self(datetime.into())) + } +} + +#[derive(Debug, Clone)] +struct SizeRange { + from: Option, + to: Option, +} + +impl SizeRange { + fn matches(&self, size: u64) -> bool { + // The matches-expression is only true if the `Option` is `Some` and the size is smaller than from. + // Hence, !matches is true either if `self.from` is `None` or if the size >= the values + !matches!(self.from, Some(from) if size < from.0) + // same logic here, but smaller and greater swapped. + && !matches!(self.to, Some(to) if size > to.0) + } +} + +fn parse_size(s: &str) -> Result, String> { + let s = s.trim(); + if s.is_empty() { + return Ok(None); + } + Ok(Some(s.parse()?)) +} + +impl FromStr for SizeRange { + type Err = String; + fn from_str(s: &str) -> Result { + let (from, to) = match s.split_once("..") { + Some((s1, s2)) => (parse_size(s1)?, parse_size(s2)?), + None => (parse_size(s)?, None), + }; + Ok(Self { from, to }) + } +} + +impl Display for SizeRange { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(from) = self.from { + f.write_str(&from.to_string_as(true))?; + } + f.write_str("..")?; + if let Some(to) = self.to { + f.write_str(&to.to_string_as(true))?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use rstest::rstest; + + #[rstest] + #[case("..", None, None)] + #[case("10", Some(10), None)] + #[case("..10k", None, Some(10_000))] + #[case("1MB..", Some(1_000_000), None)] + #[case("1 MB .. 1 GiB", Some(1_000_000), Some(1_073_741_824))] + #[case("10 .. 20 ", Some(10), Some(20))] + #[case(" 2G ", Some(2_000_000_000), None)] + fn size_range_from_str( + #[case] input: SizeRange, + #[case] from: Option, + #[case] to: Option, + ) { + assert_eq!(input.from.map(|v| v.0), from); + assert_eq!(input.to.map(|v| v.0), to); } } diff --git a/src/lib.rs b/src/lib.rs index b594b3159..399bd4c3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,10 +34,8 @@ Application based on the [Abscissa] framework. patterns_in_fns_without_body, trivial_numeric_casts, unused_results, - trivial_casts, unused_extern_crates, unused_import_braces, - unused_qualifications, unconditional_recursion, unused, unused_allocation, @@ -64,6 +62,7 @@ pub(crate) mod config; pub(crate) mod error; pub(crate) mod filtering; pub(crate) mod helpers; +pub(crate) mod repository; // rustic_cli Public API diff --git a/src/repository.rs b/src/repository.rs new file mode 100644 index 000000000..7f045078e --- /dev/null +++ b/src/repository.rs @@ -0,0 +1,167 @@ +//! Rustic Config +//! +//! See instructions in `commands.rs` to specify the path to your +//! application's configuration file and/or command-line options +//! for specifying it. + +use std::fmt::Debug; +use std::ops::Deref; + +use abscissa_core::Application; +use anyhow::{anyhow, bail, Result}; +use clap::Parser; +use conflate::Merge; +use dialoguer::Password; +use rustic_backend::BackendOptions; +use rustic_core::{ + FullIndex, IndexedStatus, OpenStatus, ProgressBars, Repository, RepositoryOptions, +}; +use serde::{Deserialize, Serialize}; + +use crate::{ + config::{hooks::Hooks, progress_options::ProgressOptions}, + RUSTIC_APP, +}; + +pub(super) mod constants { + pub(super) const MAX_PASSWORD_RETRIES: usize = 5; +} + +#[derive(Clone, Default, Debug, Parser, Serialize, Deserialize, Merge)] +#[serde(default, rename_all = "kebab-case")] +pub struct AllRepositoryOptions { + /// Backend options + #[clap(flatten)] + #[serde(flatten)] + pub be: BackendOptions, + + /// Repository options + #[clap(flatten)] + #[serde(flatten)] + pub repo: RepositoryOptions, + + /// Hooks + #[clap(skip)] + pub hooks: Hooks, +} + +pub type CliRepo = RusticRepo; +pub type CliOpenRepo = Repository; +pub type RusticIndexedRepo

= Repository>; +pub type CliIndexedRepo = RusticIndexedRepo; + +impl AllRepositoryOptions { + fn repository

(&self, po: P) -> Result> { + let backends = self.be.to_backends()?; + let repo = Repository::new_with_progress(&self.repo, &backends, po)?; + Ok(RusticRepo(repo)) + } + + pub fn run(&self, f: impl FnOnce(CliRepo) -> Result) -> Result { + let hooks = self.hooks.with_context("repository"); + let po = RUSTIC_APP.config().global.progress_options; + hooks.use_with(|| f(self.repository(po)?)) + } + + pub fn run_open(&self, f: impl FnOnce(CliOpenRepo) -> Result) -> Result { + let hooks = self.hooks.with_context("repository"); + let po = RUSTIC_APP.config().global.progress_options; + hooks.use_with(|| f(self.repository(po)?.open()?)) + } + + pub fn run_open_or_init_with( + &self, + do_init: bool, + init: impl FnOnce(CliRepo) -> Result, + f: impl FnOnce(CliOpenRepo) -> Result, + ) -> Result { + let hooks = self.hooks.with_context("repository"); + let po = RUSTIC_APP.config().global.progress_options; + hooks.use_with(|| { + f(self + .repository(po)? + .open_or_init_repository_with(do_init, init)?) + }) + } + + pub fn run_indexed_with_progress( + &self, + po: P, + f: impl FnOnce(RusticIndexedRepo

) -> Result, + ) -> Result { + let hooks = self.hooks.with_context("repository"); + hooks.use_with(|| f(self.repository(po)?.indexed()?)) + } + + pub fn run_indexed(&self, f: impl FnOnce(CliIndexedRepo) -> Result) -> Result { + let po = RUSTIC_APP.config().global.progress_options; + self.run_indexed_with_progress(po, f) + } +} + +#[derive(Debug)] +pub struct RusticRepo

(pub Repository); + +impl

Deref for RusticRepo

{ + type Target = Repository; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl RusticRepo

{ + pub fn open(self) -> Result> { + match self.0.password()? { + // if password is given, directly return the result of find_key_in_backend and don't retry + Some(pass) => { + return Ok(self.0.open_with_password(&pass)?); + } + None => { + for _ in 0..constants::MAX_PASSWORD_RETRIES { + let pass = Password::new() + .with_prompt("enter repository password") + .allow_empty_password(true) + .interact()?; + match self.0.clone().open_with_password(&pass) { + Ok(repo) => return Ok(repo), + Err(err) if err.is_incorrect_password() => continue, + Err(err) => return Err(err.into()), + } + } + } + } + Err(anyhow!("incorrect password")) + } + + fn open_or_init_repository_with( + self, + do_init: bool, + init: impl FnOnce(Self) -> Result>, + ) -> Result> { + let dry_run = RUSTIC_APP.config().global.check_index; + // Initialize repository if --init is set and it is not yet initialized + let repo = if do_init && self.0.config_id()?.is_none() { + if dry_run { + bail!( + "cannot initialize repository {} in dry-run mode!", + self.0.name + ); + } + init(self)? + } else { + self.open()? + }; + Ok(repo) + } + + fn indexed(self) -> Result>> { + let open = self.open()?; + let check_index = RUSTIC_APP.config().global.check_index; + let repo = if check_index { + open.to_indexed_checked() + } else { + open.to_indexed() + }?; + Ok(repo) + } +} diff --git a/tests/backup_restore.rs b/tests/backup_restore.rs index 4199bea6a..0beaf5b66 100644 --- a/tests/backup_restore.rs +++ b/tests/backup_restore.rs @@ -7,134 +7,94 @@ //! You can run them with 'nextest': //! `cargo nextest run -E 'test(backup)'`. -use abscissa_core::testing::prelude::*; - -use aho_corasick::PatternID; use dircmp::Comparison; -use pretty_assertions::assert_eq; -use rustic_testing::{get_matches, TestResult}; -use std::io::Read; use tempfile::{tempdir, TempDir}; -pub fn rustic_runner(temp_dir: &TempDir) -> CmdRunner { +use assert_cmd::Command; +use predicates::prelude::{predicate, PredicateBooleanExt}; + +use rustic_testing::TestResult; + +pub fn rustic_runner(temp_dir: &TempDir) -> TestResult { let password = "test"; let repo_dir = temp_dir.path().join("repo"); - let mut runner = CmdRunner::new(env!("CARGO_BIN_EXE_rustic")); + + let mut runner = Command::new(env!("CARGO_BIN_EXE_rustic")); + runner .arg("-r") .arg(repo_dir) .arg("--password") .arg(password) - .arg("--no-progress") - .capture_stdout() - .capture_stderr(); - runner + .arg("--no-progress"); + + Ok(runner) } fn setup() -> TestResult { let temp_dir = tempdir()?; - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.args(["init"]).run(); - - let mut stdout = String::new(); - let mut stderr = String::new(); - cmd.stdout().read_to_string(&mut stdout)?; - cmd.stderr().read_to_string(&mut stderr)?; + rustic_runner(&temp_dir)? + .args(["init"]) + .assert() + .success() + .stderr(predicate::str::contains("successfully created.")) + .stderr(predicate::str::contains("successfully added.")); - let patterns = &["successfully added.", "successfully created."]; - let matches = get_matches(patterns, stderr)?; - - assert_eq!( - matches, - vec![(PatternID::must(0), 19), (PatternID::must(1), 21),] - ); - - cmd.wait()?.expect_success(); Ok(temp_dir) } #[test] fn test_backup_and_check_passes() -> TestResult<()> { let temp_dir = setup()?; - let backup = "crates/"; + let backup = "src/"; { // Run `backup` for the first time - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("backup").arg(backup).run(); - - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["successfully saved."]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches, vec![(PatternID::must(0), 19)]); - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("backup") + .arg(backup) + .assert() + .success() + .stdout(predicate::str::contains("successfully saved.")); } { // Run `snapshots` - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("snapshots").run(); - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["total: 1 snapshot(s)"]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches, vec![(PatternID::must(0), 20)]); - - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("snapshots") + .assert() + .success() + .stdout(predicate::str::contains("total: 1 snapshot(s)")); } { // Run `backup` a second time - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("backup").arg(backup).run(); - - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["Added to the repo: 0 B", "successfully saved."]; - let matches = get_matches(patterns, output)?; - - assert_eq!( - matches, - vec![(PatternID::must(0), 22), (PatternID::must(1), 19)] - ); - - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("backup") + .arg(backup) + .assert() + .success() + .stdout(predicate::str::contains("Added to the repo: 0 B")) + .stdout(predicate::str::contains("successfully saved.")); } { // Run `snapshots` a second time - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("snapshots").run(); - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["total: 2 snapshot(s)"]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches, vec![(PatternID::must(0), 20)]); - - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("snapshots") + .assert() + .success() + .stdout(predicate::str::contains("total: 2 snapshot(s)")); } { // Run `check --read-data` - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.args(["check", "--read-data"]).run(); - let mut output = String::new(); - cmd.stderr().read_to_string(&mut output)?; - - let patterns = &["WARN", "ERROR"]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches.len(), 0); - - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .args(["check", "--read-data"]) + .assert() + .success() + .stderr(predicate::str::contains("WARN").not()) + .stderr(predicate::str::contains("ERROR").not()); } Ok(()) @@ -144,44 +104,34 @@ fn test_backup_and_check_passes() -> TestResult<()> { fn test_backup_and_restore_passes() -> TestResult<()> { let temp_dir = setup()?; let restore_dir = temp_dir.path().join("restore"); - let backup = "crates"; + let backup = "src/"; // actual repository root to backup - let current_dir = std::env::current_dir()?; - let backup_files = current_dir.join(backup); + let backup_files = std::env::current_dir()?.join(backup); { // Run `backup` for the first time - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("backup").arg(&backup_files).run(); - - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["successfully saved."]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches, vec![(PatternID::must(0), 19)]); - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("backup") + .arg(&backup_files) + .assert() + .success() + .stdout(predicate::str::contains("successfully saved.")); } { // Run `restore` - let mut runner = rustic_runner(&temp_dir); - let mut cmd = runner.arg("restore").arg("latest").arg(&restore_dir).run(); - - let mut output = String::new(); - cmd.stdout().read_to_string(&mut output)?; - - let patterns = &["restore done"]; - let matches = get_matches(patterns, output)?; - - assert_eq!(matches, vec![(PatternID::must(0), 12)]); - cmd.wait()?.expect_success(); + rustic_runner(&temp_dir)? + .arg("restore") + .arg("latest") + .arg(&restore_dir) + .assert() + .success() + .stdout(predicate::str::contains("restore done")); } - let comparison = Comparison::default(); - let compare_result = comparison.compare(&backup_files, &restore_dir.join(&backup_files))?; - dbg!(&compare_result); + // Compare the backup and the restored directory + let compare_result = + Comparison::default().compare(&backup_files, &restore_dir.join(&backup_files))?; // no differences assert!(compare_result.is_empty()); diff --git a/tests/completions-fixtures/bash.txt b/tests/completions-fixtures/bash.txt index 259c2d86f..27016865e 100644 --- a/tests/completions-fixtures/bash.txt +++ b/tests/completions-fixtures/bash.txt @@ -36,6 +36,9 @@ _rustic() { rustic,dump) cmd="rustic__dump" ;; + rustic,find) + cmd="rustic__find" + ;; rustic,forget) cmd="rustic__forget" ;; @@ -81,6 +84,9 @@ _rustic() { rustic,tag) cmd="rustic__tag" ;; + rustic,webdav) + cmd="rustic__webdav" + ;; rustic__cat,config) cmd="rustic__cat__config" ;; @@ -147,6 +153,9 @@ _rustic() { rustic__help,dump) cmd="rustic__help__dump" ;; + rustic__help,find) + cmd="rustic__help__find" + ;; rustic__help,forget) cmd="rustic__help__forget" ;; @@ -192,6 +201,9 @@ _rustic() { rustic__help,tag) cmd="rustic__help__tag" ;; + rustic__help,webdav) + cmd="rustic__help__webdav" + ;; rustic__help__cat,config) cmd="rustic__help__cat__config" ;; @@ -256,7 +268,7 @@ _rustic() { case "${cmd}" in rustic) - opts="-P -n -r -p -h -V --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help --version backup cat config completions check copy diff dump forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag help" + opts="-P -n -r -p -h -V --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help --version backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -275,7 +287,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -283,11 +306,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -299,11 +335,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -311,7 +369,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -350,18 +411,32 @@ _rustic() { return 0 ;; rustic__backup) - opts="-g -f -x -P -n -r -p -h --stdin-filename --as-path --with-atime --ignore-devid --json --init --group-by --parent --force --ignore-ctime --ignore-inode --glob --iglob --glob-file --iglob-file --git-ignore --no-require-git --exclude-if-present --one-file-system --exclude-larger-than --label --tag --description --description-from --time --delete-never --delete-after --host --command --hostname --username --with-created --set-compression --set-version --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [SOURCE]..." + opts="-g -f -x -P -n -r -p -h --stdin-filename --as-path --with-atime --ignore-devid --no-scan --json --quiet --init --group-by --parent --skip-identical-parent --force --ignore-ctime --ignore-inode --glob --iglob --glob-file --iglob-file --git-ignore --no-require-git --custom-ignorefile --exclude-if-present --one-file-system --exclude-larger-than --label --tag --description --description-from --time --delete-never --delete-after --host --command --hostname --username --with-created --set-compression --set-version --set-append-only --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --set-extra-verify --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [SOURCE]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in --stdin-filename) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --as-path) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --group-by) @@ -392,6 +467,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --custom-ignorefile) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --exclude-if-present) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -413,7 +492,18 @@ _rustic() { return 0 ;; --description-from) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --time) @@ -448,6 +538,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-append-only) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --set-treepack-size) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -480,6 +574,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-extra-verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --use-profile) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -493,7 +591,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -501,11 +610,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -517,11 +639,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -529,7 +673,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -568,7 +715,7 @@ _rustic() { return 0 ;; rustic__cat) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help tree-blob data-blob config index snapshot tree help" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help tree-blob data-blob config index snapshot tree help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -587,7 +734,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -595,11 +753,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -611,11 +782,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -623,7 +816,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -662,7 +858,7 @@ _rustic() { return 0 ;; rustic__cat__config) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -681,7 +877,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -689,11 +896,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -705,11 +925,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -717,7 +959,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -756,7 +1001,7 @@ _rustic() { return 0 ;; rustic__cat__data__blob) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -775,7 +1020,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -783,11 +1039,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -799,11 +1068,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -811,7 +1102,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -962,7 +1256,7 @@ _rustic() { return 0 ;; rustic__cat__index) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -981,7 +1275,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -989,11 +1294,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1005,11 +1323,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1017,7 +1357,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1056,7 +1399,7 @@ _rustic() { return 0 ;; rustic__cat__snapshot) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1075,7 +1418,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1083,11 +1437,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1099,11 +1466,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1111,7 +1500,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1150,7 +1542,7 @@ _rustic() { return 0 ;; rustic__cat__tree) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1169,7 +1561,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1177,11 +1580,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1193,11 +1609,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1205,7 +1643,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1244,7 +1685,7 @@ _rustic() { return 0 ;; rustic__cat__tree__blob) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1263,7 +1704,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1271,11 +1723,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1287,11 +1752,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1299,7 +1786,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1338,7 +1828,7 @@ _rustic() { return 0 ;; rustic__check) - opts="-P -n -r -p -h --trust-cache --read-data --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --trust-cache --read-data --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1357,7 +1847,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1365,11 +1866,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1381,11 +1895,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1393,7 +1929,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1432,7 +1971,7 @@ _rustic() { return 0 ;; rustic__completions) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help bash fish zsh powershell" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help bash fish zsh powershell" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1451,7 +1990,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1459,11 +2009,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1475,11 +2038,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1487,7 +2072,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1526,7 +2114,7 @@ _rustic() { return 0 ;; rustic__config) - opts="-P -n -r -p -h --set-compression --set-version --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --set-compression --set-version --set-append-only --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --set-extra-verify --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1540,6 +2128,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-append-only) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --set-treepack-size) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -1572,6 +2164,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-extra-verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --use-profile) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -1585,7 +2181,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1593,11 +2200,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1609,11 +2229,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1621,7 +2263,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1660,7 +2305,7 @@ _rustic() { return 0 ;; rustic__copy) - opts="-P -n -r -p -h --init --hostname --username --with-created --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." + opts="-P -n -r -p -h --init --hostname --username --with-created --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1687,7 +2332,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1695,11 +2351,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1711,11 +2380,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1723,7 +2414,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1762,7 +2456,7 @@ _rustic() { return 0 ;; rustic__diff) - opts="-x -P -n -r -p -h --metadata --no-content --glob --iglob --glob-file --iglob-file --git-ignore --no-require-git --exclude-if-present --one-file-system --exclude-larger-than --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-x -P -n -r -p -h --metadata --no-content --glob --iglob --glob-file --iglob-file --git-ignore --no-require-git --custom-ignorefile --exclude-if-present --one-file-system --exclude-larger-than --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1784,6 +2478,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --custom-ignorefile) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --exclude-if-present) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -1805,7 +2503,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1813,11 +2522,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1829,11 +2551,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1841,7 +2585,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1880,7 +2627,7 @@ _rustic() { return 0 ;; rustic__dump) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1899,7 +2646,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -1907,11 +2665,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -1923,11 +2694,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -1935,7 +2728,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -1973,162 +2769,325 @@ _rustic() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; - rustic__forget) - opts="-g -l -H -d -w -m -y -P -n -r -p -h --json --group-by --prune --filter-host --filter-label --filter-paths --filter-tags --filter-fn --keep-tags --keep-id --keep-last --keep-hourly --keep-daily --keep-weekly --keep-monthly --keep-quarter-yearly --keep-half-yearly --keep-yearly --keep-within --keep-within-hourly --keep-within-daily --keep-within-weekly --keep-within-monthly --keep-within-quarter-yearly --keep-within-half-yearly --keep-within-yearly --max-repack --max-unused --keep-pack --keep-delete --instant-delete --fast-repack --repack-uncompressed --repack-all --repack-cacheable-only --no-resize --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --help [ID]..." + rustic__find) + opts="-g -P -n -r -p -h --glob --iglob --path --group-by --all --show-misses --numeric-uid-gid --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in - --group-by) + --glob) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -g) + --iglob) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --filter-host) + --path) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --filter-label) + --group-by) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --filter-paths) + -g) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --filter-tags) + --use-profile) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --filter-fn) + -P) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-tags) + --log-level) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-id) + --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; - --keep-last) + --progress-interval) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -l) - COMPREPLY=($(compgen -f "${cur}")) + --repository) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; - --keep-hourly) - COMPREPLY=($(compgen -f "${cur}")) + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; - -H) - COMPREPLY=($(compgen -f "${cur}")) + -r) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; - --keep-daily) + --repo-hot) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -d) + --password) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-weekly) + --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; - -w) + -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; - --keep-monthly) + --password-command) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -m) - COMPREPLY=($(compgen -f "${cur}")) + --cache-dir) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; - --keep-quarter-yearly) + --warm-up-command) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-half-yearly) + --warm-up-wait) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-yearly) + --filter-host) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -y) + --filter-label) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within) + --filter-paths) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-hourly) + --filter-tags) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-daily) + --filter-fn) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-weekly) + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + rustic__forget) + opts="-g -l -H -d -w -m -y -P -n -r -p -h --json --quiet --group-by --prune --filter-host --filter-label --filter-paths --filter-tags --filter-fn --keep-tags --keep-id --keep-last --keep-hourly --keep-daily --keep-weekly --keep-monthly --keep-quarter-yearly --keep-half-yearly --keep-yearly --keep-within --keep-within-hourly --keep-within-daily --keep-within-weekly --keep-within-monthly --keep-within-quarter-yearly --keep-within-half-yearly --keep-within-yearly --keep-none --max-repack --max-unused --keep-pack --keep-delete --instant-delete --early-delete-index --fast-repack --repack-uncompressed --repack-all --repack-cacheable-only --no-resize --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --help [ID]..." + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --group-by) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-monthly) + -g) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-quarter-yearly) + --filter-host) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-half-yearly) + --filter-label) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-within-yearly) + --filter-paths) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --max-repack) + --filter-tags) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --max-unused) + --filter-fn) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-pack) + --keep-tags) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --keep-delete) + --keep-id) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --repack-cacheable-only) - COMPREPLY=($(compgen -W "true false" -- "${cur}")) + --keep-last) + COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --use-profile) + -l) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - -P) + --keep-hourly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -H) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-daily) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -d) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-weekly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -w) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-monthly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -m) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-quarter-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-half-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -y) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-hourly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-daily) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-weekly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-monthly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-quarter-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-half-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-within-yearly) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --max-repack) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --max-unused) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-pack) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --keep-delete) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --repack-cacheable-only) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; + --use-profile) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -P) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; @@ -2137,7 +3096,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -2145,11 +3115,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -2161,11 +3144,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -2173,7 +3178,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -2192,7 +3200,7 @@ _rustic() { return 0 ;; rustic__help) - opts="backup cat config completions check copy diff dump forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag help" + opts="backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2401,6 +3409,20 @@ _rustic() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + rustic__help__find) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; rustic__help__forget) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then @@ -2653,8 +3675,22 @@ _rustic() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + rustic__help__webdav) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; rustic__init) - opts="-P -n -r -p -h --hostname --username --with-created --set-compression --set-version --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --hostname --username --with-created --set-compression --set-version --set-append-only --set-treepack-size --set-treepack-size-limit --set-treepack-growfactor --set-datapack-size --set-datapack-growfactor --set-datapack-size-limit --set-min-packsize-tolerate-percent --set-max-packsize-tolerate-percent --set-extra-verify --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2676,6 +3712,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-append-only) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --set-treepack-size) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -2708,6 +3748,10 @@ _rustic() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --set-extra-verify) + COMPREPLY=($(compgen -W "true false" -- "${cur}")) + return 0 + ;; --use-profile) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -2721,7 +3765,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -2729,11 +3784,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -2745,11 +3813,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -2757,7 +3847,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -2796,7 +3889,7 @@ _rustic() { return 0 ;; rustic__key) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help add help" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help add help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -2815,7 +3908,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -2823,11 +3927,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -2839,11 +3956,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -2851,7 +3990,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -2890,16 +4032,24 @@ _rustic() { return 0 ;; rustic__key__add) - opts="-P -n -r -p -h --new-password-file --hostname --username --with-created --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --new-password --new-password-file --new-password-command --hostname --username --with-created --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in + --new-password) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --new-password-file) COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --new-password-command) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --hostname) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -2921,7 +4071,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -2929,11 +4090,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -2945,11 +4119,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -2957,7 +4153,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3038,7 +4237,7 @@ _rustic() { return 0 ;; rustic__list) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help blobs index packs snapshots keys" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help blobs index packs snapshots keys" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3057,7 +4256,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3065,11 +4275,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3081,11 +4304,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3093,7 +4338,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3132,7 +4380,7 @@ _rustic() { return 0 ;; rustic__ls) - opts="-s -l -P -n -r -p -h --summary --long --glob --iglob --glob-file --iglob-file --recursive --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " + opts="-s -l -P -n -r -p -h --summary --long --numeric-uid-gid --glob --iglob --glob-file --iglob-file --recursive --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3167,7 +4415,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3175,11 +4434,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3191,11 +4463,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3203,7 +4497,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3242,7 +4539,7 @@ _rustic() { return 0 ;; rustic__merge) - opts="-P -n -r -p -h --json --delete --label --tag --description --description-from --time --delete-never --delete-after --host --command --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." + opts="-P -n -r -p -h --json --delete --label --tag --description --description-from --time --delete-never --delete-after --host --command --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3261,7 +4558,18 @@ _rustic() { return 0 ;; --description-from) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --time) @@ -3293,7 +4601,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3301,11 +4620,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3317,11 +4649,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3329,7 +4683,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3368,7 +4725,7 @@ _rustic() { return 0 ;; rustic__prune) - opts="-P -n -r -p -h --max-repack --max-unused --keep-pack --keep-delete --instant-delete --fast-repack --repack-uncompressed --repack-all --repack-cacheable-only --no-resize --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --max-repack --max-unused --keep-pack --keep-delete --instant-delete --early-delete-index --fast-repack --repack-uncompressed --repack-all --repack-cacheable-only --no-resize --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3407,7 +4764,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3415,11 +4783,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3431,11 +4812,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3443,7 +4846,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3482,7 +4888,7 @@ _rustic() { return 0 ;; rustic__repair) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help index snapshots help" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help index snapshots help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3501,7 +4907,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3509,11 +4926,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3525,11 +4955,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3537,7 +4989,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3632,7 +5087,7 @@ _rustic() { return 0 ;; rustic__repair__index) - opts="-P -n -r -p -h --read-all --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --read-all --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3651,7 +5106,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3659,11 +5125,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3675,11 +5154,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3687,7 +5188,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3726,7 +5230,7 @@ _rustic() { return 0 ;; rustic__repair__snapshots) - opts="-P -n -r -p -h --delete --suffix --tag --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." + opts="-P -n -r -p -h --delete --suffix --tag --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3753,7 +5257,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3761,11 +5276,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3777,11 +5305,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3789,7 +5339,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3828,7 +5381,7 @@ _rustic() { return 0 ;; rustic__repoinfo) - opts="-P -n -r -p -h --only-files --only-index --json --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --only-files --only-index --json --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3847,7 +5400,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3855,11 +5419,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -3871,11 +5448,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -3883,7 +5482,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -3922,7 +5524,7 @@ _rustic() { return 0 ;; rustic__restore) - opts="-P -n -r -p -h --delete --numeric-id --no-ownership --verify-existing --glob --iglob --glob-file --iglob-file --recursive --filter-host --filter-label --filter-paths --filter-tags --filter-fn --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --help " + opts="-P -n -r -p -h --delete --numeric-id --no-ownership --verify-existing --glob --iglob --glob-file --iglob-file --recursive --filter-host --filter-label --filter-paths --filter-tags --filter-fn --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --help " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3977,7 +5579,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -3985,11 +5598,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -4001,11 +5627,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -4013,7 +5661,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -4032,7 +5683,7 @@ _rustic() { return 0 ;; rustic__self__update) - opts="-P -n -r -p -h --force --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --force --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4051,7 +5702,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -4059,11 +5721,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -4075,11 +5750,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -4087,7 +5784,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -4126,7 +5826,7 @@ _rustic() { return 0 ;; rustic__show__config) - opts="-P -n -r -p -h --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" + opts="-P -n -r -p -h --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4145,7 +5845,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -4153,11 +5864,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -4169,11 +5893,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -4181,7 +5927,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -4220,7 +5969,7 @@ _rustic() { return 0 ;; rustic__snapshots) - opts="-g -P -n -r -p -h --group-by --long --json --all --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." + opts="-g -i -P -n -r -p -h --group-by --long --json --all --interactive --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4247,7 +5996,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -4255,11 +6015,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -4271,11 +6044,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -4283,7 +6078,10 @@ _rustic() { return 0 ;; --cache-dir) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -4322,7 +6120,7 @@ _rustic() { return 0 ;; rustic__tag) - opts="-P -n -r -p -h --add --remove --set --remove-delete --set-delete-never --set-delete-after --use-profile --dry-run --log-level --log-file --no-progress --progress-interval --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." + opts="-P -n -r -p -h --add --remove --set --remove-delete --set-delete-never --set-delete-after --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [ID]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -4357,7 +6155,18 @@ _rustic() { return 0 ;; --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --progress-interval) @@ -4365,11 +6174,24 @@ _rustic() { return 0 ;; --repository) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; -r) - COMPREPLY=($(compgen -f "${cur}")) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --repo-hot) @@ -4381,11 +6203,33 @@ _rustic() { return 0 ;; --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi return 0 ;; --password-command) @@ -4393,7 +6237,169 @@ _rustic() { return 0 ;; --cache-dir) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --warm-up-command) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --warm-up-wait) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --filter-host) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --filter-label) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --filter-paths) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --filter-tags) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --filter-fn) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + rustic__webdav) + opts="-P -n -r -p -h --address --path-template --time-template --symlinks --file-access --use-profile --dry-run --check-index --log-level --log-file --no-progress --progress-interval --repo --repository --repo-hot --password --password-file --password-command --no-cache --cache-dir --warm-up --warm-up-command --warm-up-wait --filter-host --filter-label --filter-paths --filter-tags --filter-fn --help [SNAPSHOT[:PATH]]" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --address) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --path-template) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --time-template) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --file-access) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --use-profile) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -P) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --log-level) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --log-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --progress-interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --repository) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + -r) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi + return 0 + ;; + --repo-hot) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --password) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --password-file) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + -p) + local oldifs + if [ -n "${IFS+x}" ]; then + oldifs="$IFS" + fi + IFS=$'\n' + COMPREPLY=($(compgen -f "${cur}")) + if [ -n "${oldifs+x}" ]; then + IFS="$oldifs" + fi + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o filenames + fi + return 0 + ;; + --password-command) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --cache-dir) + COMPREPLY=() + if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then + compopt -o plusdirs + fi return 0 ;; --warm-up-command) @@ -4434,4 +6440,8 @@ _rustic() { esac } -complete -F _rustic -o nosort -o bashdefault -o default rustic +if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then + complete -F _rustic -o nosort -o bashdefault -o default rustic +else + complete -F _rustic -o bashdefault -o default rustic +fi diff --git a/tests/completions-fixtures/fish.txt b/tests/completions-fixtures/fish.txt index 5037f3d5d..1e9bde25a 100644 --- a/tests/completions-fixtures/fish.txt +++ b/tests/completions-fixtures/fish.txt @@ -1,956 +1,1095 @@ -complete -c rustic -n "__fish_use_subcommand" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_use_subcommand" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_use_subcommand" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_use_subcommand" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_use_subcommand" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_use_subcommand" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_use_subcommand" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_use_subcommand" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_use_subcommand" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_use_subcommand" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_use_subcommand" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_use_subcommand" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_use_subcommand" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_use_subcommand" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_use_subcommand" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_use_subcommand" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_use_subcommand" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_use_subcommand" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_use_subcommand" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_use_subcommand" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_use_subcommand" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_use_subcommand" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_use_subcommand" -s V -l version -d 'Print version' -complete -c rustic -n "__fish_use_subcommand" -f -a "backup" -d 'Backup to the repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "cat" -d 'Show raw data of repository files and blobs' -complete -c rustic -n "__fish_use_subcommand" -f -a "config" -d 'Change the repository configuration' -complete -c rustic -n "__fish_use_subcommand" -f -a "completions" -d 'Generate shell completions' -complete -c rustic -n "__fish_use_subcommand" -f -a "check" -d 'Check the repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "copy" -d 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!' -complete -c rustic -n "__fish_use_subcommand" -f -a "diff" -d 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' -complete -c rustic -n "__fish_use_subcommand" -f -a "dump" -d 'dump the contents of a file in a snapshot to stdout' -complete -c rustic -n "__fish_use_subcommand" -f -a "forget" -d 'Remove snapshots from the repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "init" -d 'Initialize a new repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "key" -d 'Manage keys' -complete -c rustic -n "__fish_use_subcommand" -f -a "list" -d 'List repository files' -complete -c rustic -n "__fish_use_subcommand" -f -a "ls" -d 'List file contents of a snapshot' -complete -c rustic -n "__fish_use_subcommand" -f -a "merge" -d 'Merge snapshots' -complete -c rustic -n "__fish_use_subcommand" -f -a "snapshots" -d 'Show a detailed overview of the snapshots within the repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "show-config" -d 'Show the configuration which has been read from the config file(s)' -complete -c rustic -n "__fish_use_subcommand" -f -a "self-update" -d 'Update to the latest rustic release' -complete -c rustic -n "__fish_use_subcommand" -f -a "prune" -d 'Remove unused data or repack repository pack files' -complete -c rustic -n "__fish_use_subcommand" -f -a "restore" -d 'Restore a snapshot/path' -complete -c rustic -n "__fish_use_subcommand" -f -a "repair" -d 'Repair a snapshot/path' -complete -c rustic -n "__fish_use_subcommand" -f -a "repoinfo" -d 'Show general information about the repository' -complete -c rustic -n "__fish_use_subcommand" -f -a "tag" -d 'Change tags of snapshots' -complete -c rustic -n "__fish_use_subcommand" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l stdin-filename -d 'Set filename to be used when backing up from stdin' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l as-path -d 'Manually set backup path in snapshot' -r -F -complete -c rustic -n "__fish_seen_subcommand_from backup" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l parent -d 'Snapshot to use as parent' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l exclude-if-present -d 'Exclude contents of directories containing this filename (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l exclude-larger-than -d 'Maximum size of files to be backed up. Larger files will be excluded' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l label -d 'Label snapshot with given label' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l tag -d 'Tags to add to snapshot (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l description -d 'Add description to snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l description-from -d 'Add description to snapshot from file' -r -F -complete -c rustic -n "__fish_seen_subcommand_from backup" -l time -d 'Set the backup time manually' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l host -d 'Set the host name manually' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l command -d 'Set the backup command manually' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l hostname -d 'Set \'hostname\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l username -d 'Set \'username\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from backup" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from backup" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from backup" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from backup" -l with-atime -d 'Save access time for files and directories' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l ignore-devid -d 'Don\'t save device ID for files and directories' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l json -d 'Output generated snapshot in json format' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l init -d 'Initialize repository, if it doesn\'t exist yet' -complete -c rustic -n "__fish_seen_subcommand_from backup" -s f -l force -d 'Use no parent, read all files' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l ignore-ctime -d 'Ignore ctime changes when checking for modified files' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l ignore-inode -d 'Ignore inode number changes when checking for modified files' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l git-ignore -d 'Ignore files based on .gitignore files' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l no-require-git -d 'Do not require a git repository to apply git-ignore rule' -complete -c rustic -n "__fish_seen_subcommand_from backup" -s x -l one-file-system -d 'Exclude other file systems, don\'t cross filesystem boundaries and subvolumes' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l delete-never -d 'Mark snapshot as uneraseable' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l with-created -d 'Add \'created\' date in public key information' -complete -c rustic -n "__fish_seen_subcommand_from backup" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from backup" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from backup" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "tree-blob" -d 'Display a tree blob' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "data-blob" -d 'Display a data blob' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "config" -d 'Display the config file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "index" -d 'Display an index file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "snapshot" -d 'Display a snapshot file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "tree" -d 'Display a tree within a snapshot' -complete -c rustic -n "__fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree-blob" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from data-blob" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from index" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from snapshot" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from tree" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "tree-blob" -d 'Display a tree blob' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "data-blob" -d 'Display a data blob' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "config" -d 'Display the config file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "index" -d 'Display an index file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "snapshot" -d 'Display a snapshot file' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "tree" -d 'Display a tree within a snapshot' -complete -c rustic -n "__fish_seen_subcommand_from cat; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from config" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from config" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from config" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from completions" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from completions" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from completions" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from completions" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from completions" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from completions" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from completions" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from completions" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from completions" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from check" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from check" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from check" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from check" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from check" -l trust-cache -d 'Don\'t verify the data saved in the cache' -complete -c rustic -n "__fish_seen_subcommand_from check" -l read-data -d 'Read all data blobs' -complete -c rustic -n "__fish_seen_subcommand_from check" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from check" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from check" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from check" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from check" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from copy" -l hostname -d 'Set \'hostname\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l username -d 'Set \'username\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from copy" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from copy" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from copy" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from copy" -l init -d 'Initialize non-existing target repositories' -complete -c rustic -n "__fish_seen_subcommand_from copy" -l with-created -d 'Add \'created\' date in public key information' -complete -c rustic -n "__fish_seen_subcommand_from copy" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from copy" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from copy" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from copy" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from copy" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l exclude-if-present -d 'Exclude contents of directories containing this filename (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l exclude-larger-than -d 'Maximum size of files to be backed up. Larger files will be excluded' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from diff" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from diff" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from diff" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from diff" -l metadata -d 'show differences in metadata' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l no-content -d 'don\'t check for different file contents' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l git-ignore -d 'Ignore files based on .gitignore files' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l no-require-git -d 'Do not require a git repository to apply git-ignore rule' -complete -c rustic -n "__fish_seen_subcommand_from diff" -s x -l one-file-system -d 'Exclude other file systems, don\'t cross filesystem boundaries and subvolumes' -complete -c rustic -n "__fish_seen_subcommand_from diff" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from diff" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from diff" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from dump" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from dump" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from dump" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from dump" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from dump" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from dump" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from dump" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from dump" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from dump" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from forget" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-tags -d 'Keep snapshots with this taglist (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-id -d 'Keep snapshots ids that start with ID (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s l -l keep-last -d 'Keep the last N snapshots (N == -1: keep all snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s H -l keep-hourly -d 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s d -l keep-daily -d 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s w -l keep-weekly -d 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s m -l keep-monthly -d 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-quarter-yearly -d 'Keep the last N quarter-yearly snapshots (N == -1: keep all quarter-yearly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-half-yearly -d 'Keep the last N half-yearly snapshots (N == -1: keep all half-yearly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s y -l keep-yearly -d 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within -d 'Keep snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-hourly -d 'Keep hourly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-daily -d 'Keep daily snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-weekly -d 'Keep weekly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-monthly -d 'Keep monthly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-quarter-yearly -d 'Keep quarter-yearly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-half-yearly -d 'Keep half-yearly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-within-yearly -d 'Keep yearly snapshots newer than DURATION relative to latest snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l max-repack -d 'Define maximum data to repack in % of reposize or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l max-unused -d 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-pack -d 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won\'t be repacked or marked for deletion within this prune run' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l keep-delete -d 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won\'t be deleted within this prune run' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l repack-cacheable-only -d 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]' -r -f -a "{true '',false ''}" -complete -c rustic -n "__fish_seen_subcommand_from forget" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from forget" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from forget" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from forget" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from forget" -l json -d 'Show infos in json format' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l prune -d 'Also prune the repository' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l instant-delete -d 'Delete files immediately instead of marking them. This also removes all files already marked for deletion' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l fast-repack -d 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l repack-uncompressed -d 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l repack-all -d 'Repack all packs. Implies --max-unused=0' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l no-resize -d 'Do not repack packs which only needs to be resized' -complete -c rustic -n "__fish_seen_subcommand_from forget" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from forget" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from forget" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from init" -l hostname -d 'Set \'hostname\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l username -d 'Set \'username\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from init" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from init" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from init" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from init" -l with-created -d 'Add \'created\' date in public key information' -complete -c rustic -n "__fish_seen_subcommand_from init" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from init" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from init" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from init" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from init" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -f -a "add" -d 'Add a new key to the repository' -complete -c rustic -n "__fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l new-password-file -d 'File from which to read the new password' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l hostname -d 'Set \'hostname\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l username -d 'Set \'username\' in public key information' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l with-created -d 'Add \'created\' date in public key information' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from add" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -f -a "add" -d 'Add a new key to the repository' -complete -c rustic -n "__fish_seen_subcommand_from key; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from add; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from list" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from list" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from list" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from list" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from list" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from list" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from list" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from list" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from list" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from ls" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from ls" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from ls" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from ls" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from ls" -s s -l summary -d 'show summary' -complete -c rustic -n "__fish_seen_subcommand_from ls" -s l -l long -d 'show long listing' -complete -c rustic -n "__fish_seen_subcommand_from ls" -l recursive -d 'recursively list the dir' -complete -c rustic -n "__fish_seen_subcommand_from ls" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from ls" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from ls" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from ls" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from ls" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l label -d 'Label snapshot with given label' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l tag -d 'Tags to add to snapshot (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l description -d 'Add description to snapshot' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l description-from -d 'Add description to snapshot from file' -r -F -complete -c rustic -n "__fish_seen_subcommand_from merge" -l time -d 'Set the backup time manually' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l host -d 'Set the host name manually' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l command -d 'Set the backup command manually' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from merge" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from merge" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from merge" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from merge" -l json -d 'Output generated snapshot in json format' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l delete -d 'Remove input snapshots after merging' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l delete-never -d 'Mark snapshot as uneraseable' -complete -c rustic -n "__fish_seen_subcommand_from merge" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from merge" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from merge" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l long -d 'Show detailed information about snapshots' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l json -d 'Show snapshots in json format' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l all -d 'Show all snapshots instead of summarizing identical follow-up snapshots' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from snapshots" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from show-config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from show-config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from show-config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from show-config" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l force -d 'Do not ask before processing the self-update' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from self-update" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l max-repack -d 'Define maximum data to repack in % of reposize or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l max-unused -d 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l keep-pack -d 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won\'t be repacked or marked for deletion within this prune run' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l keep-delete -d 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won\'t be deleted within this prune run' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l repack-cacheable-only -d 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]' -r -f -a "{true '',false ''}" -complete -c rustic -n "__fish_seen_subcommand_from prune" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from prune" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from prune" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from prune" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from prune" -l instant-delete -d 'Delete files immediately instead of marking them. This also removes all files already marked for deletion' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l fast-repack -d 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l repack-uncompressed -d 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l repack-all -d 'Repack all packs. Implies --max-unused=0' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l no-resize -d 'Do not repack packs which only needs to be resized' -complete -c rustic -n "__fish_seen_subcommand_from prune" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from prune" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from prune" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from restore" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from restore" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from restore" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from restore" -l delete -d 'Remove all files/dirs in destination which are not contained in snapshot' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l numeric-id -d 'Use numeric ids instead of user/group when restoring uid/gui' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l no-ownership -d 'Don\'t restore ownership (user/group)' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l verify-existing -d 'Always read and verify existing files (don\'t trust correct modification time and file size)' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l recursive -d 'recursively list the dir' -complete -c rustic -n "__fish_seen_subcommand_from restore" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from restore" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from restore" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "index" -d 'Repair the repository index' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "snapshots" -d 'Repair snapshots' -complete -c rustic -n "__fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l read-all -d 'Read all data packs, i.e. completely re-create the index' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from index" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l suffix -d 'Append this suffix to repaired directory or file name' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l tag -d 'Tag list to set on repaired snapshots (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l delete -d 'Also remove defect snapshots' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from snapshots" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "index" -d 'Repair the repository index' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "snapshots" -d 'Repair snapshots' -complete -c rustic -n "__fish_seen_subcommand_from repair; and __fish_seen_subcommand_from help; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l only-files -d 'Only scan repository files (doesn\'t need repository password)' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l only-index -d 'Only scan index' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l json -d 'Show infos in json format' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from repoinfo" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from tag" -l add -d 'Tags to add (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l remove -d 'Tags to remove (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l set -d 'Tag list to set (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l set-delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l log-level -d 'Use this log level [default: info]' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F -complete -c rustic -n "__fish_seen_subcommand_from tag" -l progress-interval -d 'Interval to update progress bars' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -s r -l repository -d 'Repository to use' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l repo-hot -d 'Repository to use as hot storage' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l password -d 'Password of the repository' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -s p -l password-file -d 'File to read the password from' -r -F -complete -c rustic -n "__fish_seen_subcommand_from tag" -l password-command -d 'Command to read the password from. Password is read from stdout' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -F -complete -c rustic -n "__fish_seen_subcommand_from tag" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l filter-label -d 'Label to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l filter-fn -d 'Function to filter snapshots' -r -complete -c rustic -n "__fish_seen_subcommand_from tag" -l remove-delete -d 'Remove any delete mark' -complete -c rustic -n "__fish_seen_subcommand_from tag" -l set-delete-never -d 'Mark snapshot as uneraseable' -complete -c rustic -n "__fish_seen_subcommand_from tag" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' -complete -c rustic -n "__fish_seen_subcommand_from tag" -l no-progress -d 'Don\'t show any progress bar' -complete -c rustic -n "__fish_seen_subcommand_from tag" -l no-cache -d 'Don\'t use a cache' -complete -c rustic -n "__fish_seen_subcommand_from tag" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' -complete -c rustic -n "__fish_seen_subcommand_from tag" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "backup" -d 'Backup to the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "cat" -d 'Show raw data of repository files and blobs' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "config" -d 'Change the repository configuration' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "completions" -d 'Generate shell completions' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "check" -d 'Check the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "copy" -d 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "diff" -d 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "dump" -d 'dump the contents of a file in a snapshot to stdout' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "forget" -d 'Remove snapshots from the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "init" -d 'Initialize a new repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "key" -d 'Manage keys' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "list" -d 'List repository files' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "ls" -d 'List file contents of a snapshot' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "merge" -d 'Merge snapshots' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "snapshots" -d 'Show a detailed overview of the snapshots within the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "show-config" -d 'Show the configuration which has been read from the config file(s)' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "self-update" -d 'Update to the latest rustic release' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "prune" -d 'Remove unused data or repack repository pack files' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "restore" -d 'Restore a snapshot/path' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "repair" -d 'Repair a snapshot/path' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "repoinfo" -d 'Show general information about the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "tag" -d 'Change tags of snapshots' -complete -c rustic -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from backup; and not __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from completions; and not __fish_seen_subcommand_from check; and not __fish_seen_subcommand_from copy; and not __fish_seen_subcommand_from diff; and not __fish_seen_subcommand_from dump; and not __fish_seen_subcommand_from forget; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from ls; and not __fish_seen_subcommand_from merge; and not __fish_seen_subcommand_from snapshots; and not __fish_seen_subcommand_from show-config; and not __fish_seen_subcommand_from self-update; and not __fish_seen_subcommand_from prune; and not __fish_seen_subcommand_from restore; and not __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from repoinfo; and not __fish_seen_subcommand_from tag; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "tree-blob" -d 'Display a tree blob' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "data-blob" -d 'Display a data blob' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "config" -d 'Display the config file' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "index" -d 'Display an index file' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "snapshot" -d 'Display a snapshot file' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from cat; and not __fish_seen_subcommand_from tree-blob; and not __fish_seen_subcommand_from data-blob; and not __fish_seen_subcommand_from config; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshot; and not __fish_seen_subcommand_from tree" -f -a "tree" -d 'Display a tree within a snapshot' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from key; and not __fish_seen_subcommand_from add" -f -a "add" -d 'Add a new key to the repository' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots" -f -a "index" -d 'Repair the repository index' -complete -c rustic -n "__fish_seen_subcommand_from help; and __fish_seen_subcommand_from repair; and not __fish_seen_subcommand_from index; and not __fish_seen_subcommand_from snapshots" -f -a "snapshots" -d 'Repair snapshots' +# Print an optspec for argparse to handle cmd's options that are independent of any subcommand. +function __fish_rustic_global_optspecs + string join \n P/use-profile= n/dry-run check-index log-level= log-file= no-progress progress-interval= r/repository= repo-hot= password= p/password-file= password-command= no-cache cache-dir= warm-up warm-up-command= warm-up-wait= filter-host= filter-label= filter-paths= filter-tags= filter-fn= h/help V/version +end + +function __fish_rustic_needs_command + # Figure out if the current invocation already has a command. + set -l cmd (commandline -opc) + set -e cmd[1] + argparse -s (__fish_rustic_global_optspecs) -- $cmd 2>/dev/null + or return + if set -q argv[1] + # Also print the command, so this can be used to figure out what it is. + echo $argv[1] + return 1 + end + return 0 +end + +function __fish_rustic_using_subcommand + set -l cmd (__fish_rustic_needs_command) + test -z "$cmd" + and return 1 + contains -- $cmd[1] $argv +end + +complete -c rustic -n "__fish_rustic_needs_command" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_needs_command" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_needs_command" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_needs_command" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_needs_command" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_needs_command" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_needs_command" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_needs_command" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_needs_command" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_needs_command" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_needs_command" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_needs_command" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_needs_command" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_needs_command" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_needs_command" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_needs_command" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_needs_command" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_needs_command" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_needs_command" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_needs_command" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_needs_command" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_needs_command" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_needs_command" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_needs_command" -s V -l version -d 'Print version' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "backup" -d 'Backup to the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "cat" -d 'Show raw data of repository files and blobs' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "config" -d 'Change the repository configuration' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "completions" -d 'Generate shell completions' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "check" -d 'Check the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "copy" -d 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "diff" -d 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "dump" -d 'dump the contents of a file in a snapshot to stdout' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "find" -d 'Find in given snapshots' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "forget" -d 'Remove snapshots from the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "init" -d 'Initialize a new repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "key" -d 'Manage keys' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "list" -d 'List repository files' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "ls" -d 'List file contents of a snapshot' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "merge" -d 'Merge snapshots' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "snapshots" -d 'Show a detailed overview of the snapshots within the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "show-config" -d 'Show the configuration which has been read from the config file(s)' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "self-update" -d 'Update to the latest rustic release' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "prune" -d 'Remove unused data or repack repository pack files' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "restore" -d 'Restore a snapshot/path' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "repair" -d 'Repair a snapshot/path' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "repoinfo" -d 'Show general information about the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "tag" -d 'Change tags of snapshots' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "webdav" -d 'Start a webdav server which allows to access the repository' +complete -c rustic -n "__fish_rustic_needs_command" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l stdin-filename -d 'Set filename to be used when backing up from stdin' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l as-path -d 'Manually set backup path in snapshot' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l parent -d 'Snapshot to use as parent' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l custom-ignorefile -d 'Treat the provided filename like a .gitignore file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l exclude-if-present -d 'Exclude contents of directories containing this filename (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l exclude-larger-than -d 'Maximum size of files to be backed up. Larger files will be excluded' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l label -d 'Label snapshot with given label' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l tag -d 'Tags to add to snapshot (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l description -d 'Add description to snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l description-from -d 'Add description to snapshot from file' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l time -d 'Set the backup time manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l host -d 'Set the host name manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l command -d 'Set the backup command manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l hostname -d 'Set \'hostname\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l username -d 'Set \'username\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-append-only -d 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won\'t work any longer' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l set-extra-verify -d 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l with-atime -d 'Save access time for files and directories' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l ignore-devid -d 'Don\'t save device ID for files and directories' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l no-scan -d 'Don\'t scan the backup source for its size - this disables ETA estimation for backup' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l json -d 'Output generated snapshot in json format' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l quiet -d 'Don\'t show any output' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l init -d 'Initialize repository, if it doesn\'t exist yet' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l skip-identical-parent -d 'Skip writing of snapshot if nothing changed w.r.t. the parent snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s f -l force -d 'Use no parent, read all files' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l ignore-ctime -d 'Ignore ctime changes when checking for modified files' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l ignore-inode -d 'Ignore inode number changes when checking for modified files' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l git-ignore -d 'Ignore files based on .gitignore files' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l no-require-git -d 'Do not require a git repository to apply git-ignore rule' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s x -l one-file-system -d 'Exclude other file systems, don\'t cross filesystem boundaries and subvolumes' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l delete-never -d 'Mark snapshot as uneraseable' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l with-created -d 'Add \'created\' date in public key information' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand backup" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "tree-blob" -d 'Display a tree blob' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "data-blob" -d 'Display a data blob' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "config" -d 'Display the config file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "index" -d 'Display an index file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "snapshot" -d 'Display a snapshot file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "tree" -d 'Display a tree within a snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and not __fish_seen_subcommand_from tree-blob data-blob config index snapshot tree help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree-blob" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from data-blob" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from config" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from index" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from snapshot" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from tree" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "tree-blob" -d 'Display a tree blob' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "data-blob" -d 'Display a data blob' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "config" -d 'Display the config file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "index" -d 'Display an index file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "snapshot" -d 'Display a snapshot file' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "tree" -d 'Display a tree within a snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand cat; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-append-only -d 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won\'t work any longer' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l set-extra-verify -d 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand config" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand config" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand config" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand config" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand config" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand config" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand completions" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand completions" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand check" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand check" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand check" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand check" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand check" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand check" -l trust-cache -d 'Don\'t verify the data saved in the cache' +complete -c rustic -n "__fish_rustic_using_subcommand check" -l read-data -d 'Read all data blobs' +complete -c rustic -n "__fish_rustic_using_subcommand check" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand check" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand check" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand check" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand check" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand check" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l hostname -d 'Set \'hostname\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l username -d 'Set \'username\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l init -d 'Initialize non-existing target repositories' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l with-created -d 'Add \'created\' date in public key information' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand copy" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l custom-ignorefile -d 'Treat the provided filename like a .gitignore file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l exclude-if-present -d 'Exclude contents of directories containing this filename (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l exclude-larger-than -d 'Maximum size of files to be backed up. Larger files will be excluded' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l metadata -d 'show differences in metadata' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l no-content -d 'don\'t check for different file contents' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l git-ignore -d 'Ignore files based on .gitignore files' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l no-require-git -d 'Do not require a git repository to apply git-ignore rule' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s x -l one-file-system -d 'Exclude other file systems, don\'t cross filesystem boundaries and subvolumes' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand diff" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand dump" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand dump" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l glob -d 'pattern to find (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l iglob -d 'pattern to find case-insensitive (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l path -d 'exact path to find' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand find" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand find" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand find" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand find" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand find" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand find" -l all -d 'Show all snapshots instead of summarizing snapshots with identical search results' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l show-misses -d 'Also show snapshots which don\'t contain a search result' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l numeric-uid-gid -d 'Show uid/gid instead of user/group' +complete -c rustic -n "__fish_rustic_using_subcommand find" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand find" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand find" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-tags -d 'Keep snapshots with this taglist (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-id -d 'Keep snapshots ids that start with ID (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s l -l keep-last -d 'Keep the last N snapshots (N == -1: keep all snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s H -l keep-hourly -d 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s d -l keep-daily -d 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s w -l keep-weekly -d 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s m -l keep-monthly -d 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-quarter-yearly -d 'Keep the last N quarter-yearly snapshots (N == -1: keep all quarter-yearly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-half-yearly -d 'Keep the last N half-yearly snapshots (N == -1: keep all half-yearly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s y -l keep-yearly -d 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within -d 'Keep snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-hourly -d 'Keep hourly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-daily -d 'Keep daily snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-weekly -d 'Keep weekly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-monthly -d 'Keep monthly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-quarter-yearly -d 'Keep quarter-yearly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-half-yearly -d 'Keep half-yearly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-within-yearly -d 'Keep yearly snapshots newer than DURATION relative to latest snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l max-repack -d 'Define maximum data to repack in % of reposize or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l max-unused -d 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-pack -d 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won\'t be repacked or marked for deletion within this prune run' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-delete -d 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won\'t be deleted within this prune run' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l repack-cacheable-only -d 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l json -d 'Show infos in json format' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l quiet -d 'Don\'t show any output' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l prune -d 'Also prune the repository' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l keep-none -d 'Allow to keep no snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l instant-delete -d 'Delete files immediately instead of marking them. This also removes all files already marked for deletion' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l early-delete-index -d 'Delete index files early. This allows to run prune if there is few or no space left' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l fast-repack -d 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l repack-uncompressed -d 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l repack-all -d 'Repack all packs. Implies --max-unused=0' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l no-resize -d 'Do not repack packs which only needs to be resized' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand forget" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand init" -l hostname -d 'Set \'hostname\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l username -d 'Set \'username\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-compression -d 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-version -d 'Set repository version. Allowed versions: 1,2' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-append-only -d 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won\'t work any longer' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-treepack-size -d 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-treepack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-treepack-growfactor -d 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-datapack-size -d 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-datapack-growfactor -d 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-datapack-size-limit -d 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-min-packsize-tolerate-percent -d 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-max-packsize-tolerate-percent -d 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l set-extra-verify -d 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand init" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand init" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand init" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand init" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand init" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand init" -l with-created -d 'Add \'created\' date in public key information' +complete -c rustic -n "__fish_rustic_using_subcommand init" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand init" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand init" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand init" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand init" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand init" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -f -a "add" -d 'Add a new key to the repository' +complete -c rustic -n "__fish_rustic_using_subcommand key; and not __fish_seen_subcommand_from add help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l new-password -d 'New password' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l new-password-file -d 'File from which to read the new password' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l new-password-command -d 'Command to get the new password from' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l hostname -d 'Set \'hostname\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l username -d 'Set \'username\' in public key information' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l with-created -d 'Add \'created\' date in public key information' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from add" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from help" -f -a "add" -d 'Add a new key to the repository' +complete -c rustic -n "__fish_rustic_using_subcommand key; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand list" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand list" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand list" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand list" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand list" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand list" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand list" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand list" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand list" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand list" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand list" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s s -l summary -d 'show summary' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s l -l long -d 'show long listing' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l numeric-uid-gid -d 'show uid/gid instead of user/group' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l recursive -d 'recursively list the dir' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand ls" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l label -d 'Label snapshot with given label' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l tag -d 'Tags to add to snapshot (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l description -d 'Add description to snapshot' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l description-from -d 'Add description to snapshot from file' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l time -d 'Set the backup time manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l host -d 'Set the host name manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l command -d 'Set the backup command manually' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l json -d 'Output generated snapshot in json format' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l delete -d 'Remove input snapshots after merging' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l delete-never -d 'Mark snapshot as uneraseable' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand merge" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s g -l group-by -d 'Group snapshots by any combination of host,label,paths,tags' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l long -d 'Show detailed information about snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l json -d 'Show snapshots in json format' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l all -d 'Show all snapshots instead of summarizing identical follow-up snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s i -l interactive -d 'Run in interactive UI mode' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand snapshots" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand show-config" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l force -d 'Do not ask before processing the self-update' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand self-update" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l max-repack -d 'Define maximum data to repack in % of reposize or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l max-unused -d 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. \'5b\', \'2 kB\', \'3M\', \'4TiB\') or \'unlimited\'' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l keep-pack -d 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won\'t be repacked or marked for deletion within this prune run' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l keep-delete -d 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won\'t be deleted within this prune run' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l repack-cacheable-only -d 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]' -r -f -a "{true\t'',false\t''}" +complete -c rustic -n "__fish_rustic_using_subcommand prune" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l instant-delete -d 'Delete files immediately instead of marking them. This also removes all files already marked for deletion' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l early-delete-index -d 'Delete index files early. This allows to run prune if there is few or no space left' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l fast-repack -d 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l repack-uncompressed -d 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l repack-all -d 'Repack all packs. Implies --max-unused=0' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l no-resize -d 'Do not repack packs which only needs to be resized' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand prune" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l glob -d 'Glob pattern to exclude/include (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l iglob -d 'Same as --glob pattern but ignores the casing of filenames' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l glob-file -d 'Read glob patterns to exclude/include from this file (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l iglob-file -d 'Same as --glob-file ignores the casing of filenames in patterns' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l delete -d 'Remove all files/dirs in destination which are not contained in snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l numeric-id -d 'Use numeric ids instead of user/group when restoring uid/gui' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l no-ownership -d 'Don\'t restore ownership (user/group)' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l verify-existing -d 'Always read and verify existing files (don\'t trust correct modification time and file size)' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l recursive -d 'recursively list the dir' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand restore" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -f -a "index" -d 'Repair the repository index' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -f -a "snapshots" -d 'Repair snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and not __fish_seen_subcommand_from index snapshots help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l read-all -d 'Read all data packs, i.e. completely re-create the index' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from index" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l suffix -d 'Append this suffix to repaired directory or file name' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l tag -d 'Tag list to set on repaired snapshots (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l delete -d 'Also remove defect snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from snapshots" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from help" -f -a "index" -d 'Repair the repository index' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from help" -f -a "snapshots" -d 'Repair snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand repair; and __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l only-files -d 'Only scan repository files (doesn\'t need repository password)' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l only-index -d 'Only scan index' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l json -d 'Show infos in json format' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand repoinfo" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l add -d 'Tags to add (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l remove -d 'Tags to remove (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l set -d 'Tag list to set (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l set-delete-after -d 'Mark snapshot to be deleted after given duration (e.g. 10d)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l remove-delete -d 'Remove any delete mark' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l set-delete-never -d 'Mark snapshot as uneraseable' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand tag" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l address -d 'Address to bind the webdav server to. [default: "localhost:8000"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l path-template -d 'The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l time-template -d 'The time template to use to display times in the path template. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. [default: "%Y-%m-%d_%H-%M-%S"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l file-access -d 'How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -s P -l use-profile -d 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l log-level -d 'Use this log level [default: info]' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l log-file -d 'Write log messages to the given file instead of printing them' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l progress-interval -d 'Interval to update progress bars' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -s r -l repository -l repo -d 'Repository to use' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l repo-hot -d 'Repository to use as hot storage' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l password -d 'Password of the repository' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -s p -l password-file -d 'File to read the password from' -r -F +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l password-command -d 'Command to read the password from. Password is read from stdout' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l cache-dir -d 'Use this dir as cache dir instead of the standard cache dir' -r -f -a "(__fish_complete_directories)" +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l warm-up-command -d 'Warm up needed data pack files by running the command with %id replaced by pack id' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l warm-up-wait -d 'Duration (e.g. 10m) to wait after warm up' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l filter-host -d 'Hostname to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l filter-label -d 'Label to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l filter-paths -d 'Path list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l filter-tags -d 'Tag list to filter (can be specified multiple times)' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l filter-fn -d 'Function to filter snapshots' -r +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l symlinks -d 'Use symlinks. This may not be supported by all WebDAV clients' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -s n -l dry-run -d 'Only show what would be done without modifying anything. Does not affect read-only commands' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l check-index -d 'Check if index matches pack files and read pack headers if neccessary' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l no-progress -d 'Don\'t show any progress bar' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l no-cache -d 'Don\'t use a cache' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -l warm-up -d 'Warm up needed data pack files by only requesting them without processing' +complete -c rustic -n "__fish_rustic_using_subcommand webdav" -s h -l help -d 'Print help (see more with \'--help\')' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "backup" -d 'Backup to the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "cat" -d 'Show raw data of repository files and blobs' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "config" -d 'Change the repository configuration' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "completions" -d 'Generate shell completions' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "check" -d 'Check the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "copy" -d 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "diff" -d 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "dump" -d 'dump the contents of a file in a snapshot to stdout' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "find" -d 'Find in given snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "forget" -d 'Remove snapshots from the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "init" -d 'Initialize a new repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "key" -d 'Manage keys' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "list" -d 'List repository files' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "ls" -d 'List file contents of a snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "merge" -d 'Merge snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "snapshots" -d 'Show a detailed overview of the snapshots within the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "show-config" -d 'Show the configuration which has been read from the config file(s)' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "self-update" -d 'Update to the latest rustic release' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "prune" -d 'Remove unused data or repack repository pack files' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "restore" -d 'Restore a snapshot/path' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "repair" -d 'Repair a snapshot/path' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "repoinfo" -d 'Show general information about the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "tag" -d 'Change tags of snapshots' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "webdav" -d 'Start a webdav server which allows to access the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and not __fish_seen_subcommand_from backup cat config completions check copy diff dump find forget init key list ls merge snapshots show-config self-update prune restore repair repoinfo tag webdav help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "tree-blob" -d 'Display a tree blob' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "data-blob" -d 'Display a data blob' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "config" -d 'Display the config file' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "index" -d 'Display an index file' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "snapshot" -d 'Display a snapshot file' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from cat" -f -a "tree" -d 'Display a tree within a snapshot' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from key" -f -a "add" -d 'Add a new key to the repository' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from repair" -f -a "index" -d 'Repair the repository index' +complete -c rustic -n "__fish_rustic_using_subcommand help; and __fish_seen_subcommand_from repair" -f -a "snapshots" -d 'Repair snapshots' diff --git a/tests/completions-fixtures/powershell.txt b/tests/completions-fixtures/powershell.txt index 8852c39b6..44aaa6896 100644 --- a/tests/completions-fixtures/powershell.txt +++ b/tests/completions-fixtures/powershell.txt @@ -21,35 +21,37 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { $completions = @(switch ($command) { 'rustic' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') - [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-V', '-V ', [CompletionResultType]::ParameterName, 'Print version') + [CompletionResult]::new('--version', '--version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('backup', 'backup', [CompletionResultType]::ParameterValue, 'Backup to the repository') [CompletionResult]::new('cat', 'cat', [CompletionResultType]::ParameterValue, 'Show raw data of repository files and blobs') [CompletionResult]::new('config', 'config', [CompletionResultType]::ParameterValue, 'Change the repository configuration') @@ -58,6 +60,7 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { [CompletionResult]::new('copy', 'copy', [CompletionResultType]::ParameterValue, 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!') [CompletionResult]::new('diff', 'diff', [CompletionResultType]::ParameterValue, 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path') [CompletionResult]::new('dump', 'dump', [CompletionResultType]::ParameterValue, 'dump the contents of a file in a snapshot to stdout') + [CompletionResult]::new('find', 'find', [CompletionResultType]::ParameterValue, 'Find in given snapshots') [CompletionResult]::new('forget', 'forget', [CompletionResultType]::ParameterValue, 'Remove snapshots from the repository') [CompletionResult]::new('init', 'init', [CompletionResultType]::ParameterValue, 'Initialize a new repository') [CompletionResult]::new('key', 'key', [CompletionResultType]::ParameterValue, 'Manage keys') @@ -72,112 +75,123 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { [CompletionResult]::new('repair', 'repair', [CompletionResultType]::ParameterValue, 'Repair a snapshot/path') [CompletionResult]::new('repoinfo', 'repoinfo', [CompletionResultType]::ParameterValue, 'Show general information about the repository') [CompletionResult]::new('tag', 'tag', [CompletionResultType]::ParameterValue, 'Change tags of snapshots') + [CompletionResult]::new('webdav', 'webdav', [CompletionResultType]::ParameterValue, 'Start a webdav server which allows to access the repository') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } 'rustic;backup' { - [CompletionResult]::new('--stdin-filename', 'stdin-filename', [CompletionResultType]::ParameterName, 'Set filename to be used when backing up from stdin') - [CompletionResult]::new('--as-path', 'as-path', [CompletionResultType]::ParameterName, 'Manually set backup path in snapshot') - [CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)') - [CompletionResult]::new('--group-by', 'group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)') - [CompletionResult]::new('--parent', 'parent', [CompletionResultType]::ParameterName, 'Snapshot to use as parent') - [CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') - [CompletionResult]::new('--iglob', 'iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') - [CompletionResult]::new('--glob-file', 'glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') - [CompletionResult]::new('--iglob-file', 'iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') - [CompletionResult]::new('--exclude-if-present', 'exclude-if-present', [CompletionResultType]::ParameterName, 'Exclude contents of directories containing this filename (can be specified multiple times)') - [CompletionResult]::new('--exclude-larger-than', 'exclude-larger-than', [CompletionResultType]::ParameterName, 'Maximum size of files to be backed up. Larger files will be excluded') - [CompletionResult]::new('--label', 'label', [CompletionResultType]::ParameterName, 'Label snapshot with given label') - [CompletionResult]::new('--tag', 'tag', [CompletionResultType]::ParameterName, 'Tags to add to snapshot (can be specified multiple times)') - [CompletionResult]::new('--description', 'description', [CompletionResultType]::ParameterName, 'Add description to snapshot') - [CompletionResult]::new('--description-from', 'description-from', [CompletionResultType]::ParameterName, 'Add description to snapshot from file') - [CompletionResult]::new('--time', 'time', [CompletionResultType]::ParameterName, 'Set the backup time manually') - [CompletionResult]::new('--delete-after', 'delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') - [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'Set the host name manually') - [CompletionResult]::new('--command', 'command', [CompletionResultType]::ParameterName, 'Set the backup command manually') - [CompletionResult]::new('--hostname', 'hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') - [CompletionResult]::new('--username', 'username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') - [CompletionResult]::new('--set-compression', 'set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') - [CompletionResult]::new('--set-version', 'set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') - [CompletionResult]::new('--set-treepack-size', 'set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') - [CompletionResult]::new('--set-treepack-size-limit', 'set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-treepack-growfactor', 'set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size', 'set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') - [CompletionResult]::new('--set-datapack-growfactor', 'set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size-limit', 'set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-min-packsize-tolerate-percent', 'set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') - [CompletionResult]::new('--set-max-packsize-tolerate-percent', 'set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--with-atime', 'with-atime', [CompletionResultType]::ParameterName, 'Save access time for files and directories') - [CompletionResult]::new('--ignore-devid', 'ignore-devid', [CompletionResultType]::ParameterName, 'Don''t save device ID for files and directories') - [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Output generated snapshot in json format') - [CompletionResult]::new('--init', 'init', [CompletionResultType]::ParameterName, 'Initialize repository, if it doesn''t exist yet') - [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Use no parent, read all files') - [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Use no parent, read all files') - [CompletionResult]::new('--ignore-ctime', 'ignore-ctime', [CompletionResultType]::ParameterName, 'Ignore ctime changes when checking for modified files') - [CompletionResult]::new('--ignore-inode', 'ignore-inode', [CompletionResultType]::ParameterName, 'Ignore inode number changes when checking for modified files') - [CompletionResult]::new('--git-ignore', 'git-ignore', [CompletionResultType]::ParameterName, 'Ignore files based on .gitignore files') - [CompletionResult]::new('--no-require-git', 'no-require-git', [CompletionResultType]::ParameterName, 'Do not require a git repository to apply git-ignore rule') - [CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') - [CompletionResult]::new('--one-file-system', 'one-file-system', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') - [CompletionResult]::new('--delete-never', 'delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') - [CompletionResult]::new('--with-created', 'with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--stdin-filename', '--stdin-filename', [CompletionResultType]::ParameterName, 'Set filename to be used when backing up from stdin') + [CompletionResult]::new('--as-path', '--as-path', [CompletionResultType]::ParameterName, 'Manually set backup path in snapshot') + [CompletionResult]::new('-g', '-g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)') + [CompletionResult]::new('--group-by', '--group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default: host,label,paths)') + [CompletionResult]::new('--parent', '--parent', [CompletionResultType]::ParameterName, 'Snapshot to use as parent') + [CompletionResult]::new('--glob', '--glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') + [CompletionResult]::new('--iglob', '--iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') + [CompletionResult]::new('--glob-file', '--glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') + [CompletionResult]::new('--iglob-file', '--iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') + [CompletionResult]::new('--custom-ignorefile', '--custom-ignorefile', [CompletionResultType]::ParameterName, 'Treat the provided filename like a .gitignore file (can be specified multiple times)') + [CompletionResult]::new('--exclude-if-present', '--exclude-if-present', [CompletionResultType]::ParameterName, 'Exclude contents of directories containing this filename (can be specified multiple times)') + [CompletionResult]::new('--exclude-larger-than', '--exclude-larger-than', [CompletionResultType]::ParameterName, 'Maximum size of files to be backed up. Larger files will be excluded') + [CompletionResult]::new('--label', '--label', [CompletionResultType]::ParameterName, 'Label snapshot with given label') + [CompletionResult]::new('--tag', '--tag', [CompletionResultType]::ParameterName, 'Tags to add to snapshot (can be specified multiple times)') + [CompletionResult]::new('--description', '--description', [CompletionResultType]::ParameterName, 'Add description to snapshot') + [CompletionResult]::new('--description-from', '--description-from', [CompletionResultType]::ParameterName, 'Add description to snapshot from file') + [CompletionResult]::new('--time', '--time', [CompletionResultType]::ParameterName, 'Set the backup time manually') + [CompletionResult]::new('--delete-after', '--delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') + [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'Set the host name manually') + [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Set the backup command manually') + [CompletionResult]::new('--hostname', '--hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') + [CompletionResult]::new('--username', '--username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') + [CompletionResult]::new('--set-compression', '--set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') + [CompletionResult]::new('--set-version', '--set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') + [CompletionResult]::new('--set-append-only', '--set-append-only', [CompletionResultType]::ParameterName, 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won''t work any longer') + [CompletionResult]::new('--set-treepack-size', '--set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') + [CompletionResult]::new('--set-treepack-size-limit', '--set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-treepack-growfactor', '--set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size', '--set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') + [CompletionResult]::new('--set-datapack-growfactor', '--set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size-limit', '--set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-min-packsize-tolerate-percent', '--set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') + [CompletionResult]::new('--set-max-packsize-tolerate-percent', '--set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') + [CompletionResult]::new('--set-extra-verify', '--set-extra-verify', [CompletionResultType]::ParameterName, 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--with-atime', '--with-atime', [CompletionResultType]::ParameterName, 'Save access time for files and directories') + [CompletionResult]::new('--ignore-devid', '--ignore-devid', [CompletionResultType]::ParameterName, 'Don''t save device ID for files and directories') + [CompletionResult]::new('--no-scan', '--no-scan', [CompletionResultType]::ParameterName, 'Don''t scan the backup source for its size - this disables ETA estimation for backup') + [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'Output generated snapshot in json format') + [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Don''t show any output') + [CompletionResult]::new('--init', '--init', [CompletionResultType]::ParameterName, 'Initialize repository, if it doesn''t exist yet') + [CompletionResult]::new('--skip-identical-parent', '--skip-identical-parent', [CompletionResultType]::ParameterName, 'Skip writing of snapshot if nothing changed w.r.t. the parent snapshot') + [CompletionResult]::new('-f', '-f', [CompletionResultType]::ParameterName, 'Use no parent, read all files') + [CompletionResult]::new('--force', '--force', [CompletionResultType]::ParameterName, 'Use no parent, read all files') + [CompletionResult]::new('--ignore-ctime', '--ignore-ctime', [CompletionResultType]::ParameterName, 'Ignore ctime changes when checking for modified files') + [CompletionResult]::new('--ignore-inode', '--ignore-inode', [CompletionResultType]::ParameterName, 'Ignore inode number changes when checking for modified files') + [CompletionResult]::new('--git-ignore', '--git-ignore', [CompletionResultType]::ParameterName, 'Ignore files based on .gitignore files') + [CompletionResult]::new('--no-require-git', '--no-require-git', [CompletionResultType]::ParameterName, 'Do not require a git repository to apply git-ignore rule') + [CompletionResult]::new('-x', '-x', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') + [CompletionResult]::new('--one-file-system', '--one-file-system', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') + [CompletionResult]::new('--delete-never', '--delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') + [CompletionResult]::new('--with-created', '--with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('tree-blob', 'tree-blob', [CompletionResultType]::ParameterValue, 'Display a tree blob') [CompletionResult]::new('data-blob', 'data-blob', [CompletionResultType]::ParameterValue, 'Display a data blob') [CompletionResult]::new('config', 'config', [CompletionResultType]::ParameterValue, 'Display the config file') @@ -188,183 +202,195 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { break } 'rustic;cat;tree-blob' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;data-blob' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;config' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;index' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;snapshot' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;tree' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;cat;help' { @@ -399,388 +425,458 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { break } 'rustic;config' { - [CompletionResult]::new('--set-compression', 'set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') - [CompletionResult]::new('--set-version', 'set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') - [CompletionResult]::new('--set-treepack-size', 'set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') - [CompletionResult]::new('--set-treepack-size-limit', 'set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-treepack-growfactor', 'set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size', 'set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') - [CompletionResult]::new('--set-datapack-growfactor', 'set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size-limit', 'set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-min-packsize-tolerate-percent', 'set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') - [CompletionResult]::new('--set-max-packsize-tolerate-percent', 'set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--set-compression', '--set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') + [CompletionResult]::new('--set-version', '--set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') + [CompletionResult]::new('--set-append-only', '--set-append-only', [CompletionResultType]::ParameterName, 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won''t work any longer') + [CompletionResult]::new('--set-treepack-size', '--set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') + [CompletionResult]::new('--set-treepack-size-limit', '--set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-treepack-growfactor', '--set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size', '--set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') + [CompletionResult]::new('--set-datapack-growfactor', '--set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size-limit', '--set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-min-packsize-tolerate-percent', '--set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') + [CompletionResult]::new('--set-max-packsize-tolerate-percent', '--set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') + [CompletionResult]::new('--set-extra-verify', '--set-extra-verify', [CompletionResultType]::ParameterName, 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;completions' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;check' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--trust-cache', 'trust-cache', [CompletionResultType]::ParameterName, 'Don''t verify the data saved in the cache') - [CompletionResult]::new('--read-data', 'read-data', [CompletionResultType]::ParameterName, 'Read all data blobs') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--trust-cache', '--trust-cache', [CompletionResultType]::ParameterName, 'Don''t verify the data saved in the cache') + [CompletionResult]::new('--read-data', '--read-data', [CompletionResultType]::ParameterName, 'Read all data blobs') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;copy' { - [CompletionResult]::new('--hostname', 'hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') - [CompletionResult]::new('--username', 'username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--init', 'init', [CompletionResultType]::ParameterName, 'Initialize non-existing target repositories') - [CompletionResult]::new('--with-created', 'with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--hostname', '--hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') + [CompletionResult]::new('--username', '--username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--init', '--init', [CompletionResultType]::ParameterName, 'Initialize non-existing target repositories') + [CompletionResult]::new('--with-created', '--with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;diff' { - [CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') - [CompletionResult]::new('--iglob', 'iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') - [CompletionResult]::new('--glob-file', 'glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') - [CompletionResult]::new('--iglob-file', 'iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') - [CompletionResult]::new('--exclude-if-present', 'exclude-if-present', [CompletionResultType]::ParameterName, 'Exclude contents of directories containing this filename (can be specified multiple times)') - [CompletionResult]::new('--exclude-larger-than', 'exclude-larger-than', [CompletionResultType]::ParameterName, 'Maximum size of files to be backed up. Larger files will be excluded') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--metadata', 'metadata', [CompletionResultType]::ParameterName, 'show differences in metadata') - [CompletionResult]::new('--no-content', 'no-content', [CompletionResultType]::ParameterName, 'don''t check for different file contents') - [CompletionResult]::new('--git-ignore', 'git-ignore', [CompletionResultType]::ParameterName, 'Ignore files based on .gitignore files') - [CompletionResult]::new('--no-require-git', 'no-require-git', [CompletionResultType]::ParameterName, 'Do not require a git repository to apply git-ignore rule') - [CompletionResult]::new('-x', 'x', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') - [CompletionResult]::new('--one-file-system', 'one-file-system', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--glob', '--glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') + [CompletionResult]::new('--iglob', '--iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') + [CompletionResult]::new('--glob-file', '--glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') + [CompletionResult]::new('--iglob-file', '--iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') + [CompletionResult]::new('--custom-ignorefile', '--custom-ignorefile', [CompletionResultType]::ParameterName, 'Treat the provided filename like a .gitignore file (can be specified multiple times)') + [CompletionResult]::new('--exclude-if-present', '--exclude-if-present', [CompletionResultType]::ParameterName, 'Exclude contents of directories containing this filename (can be specified multiple times)') + [CompletionResult]::new('--exclude-larger-than', '--exclude-larger-than', [CompletionResultType]::ParameterName, 'Maximum size of files to be backed up. Larger files will be excluded') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--metadata', '--metadata', [CompletionResultType]::ParameterName, 'show differences in metadata') + [CompletionResult]::new('--no-content', '--no-content', [CompletionResultType]::ParameterName, 'don''t check for different file contents') + [CompletionResult]::new('--git-ignore', '--git-ignore', [CompletionResultType]::ParameterName, 'Ignore files based on .gitignore files') + [CompletionResult]::new('--no-require-git', '--no-require-git', [CompletionResultType]::ParameterName, 'Do not require a git repository to apply git-ignore rule') + [CompletionResult]::new('-x', '-x', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') + [CompletionResult]::new('--one-file-system', '--one-file-system', [CompletionResultType]::ParameterName, 'Exclude other file systems, don''t cross filesystem boundaries and subvolumes') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;dump' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'rustic;find' { + [CompletionResult]::new('--glob', '--glob', [CompletionResultType]::ParameterName, 'pattern to find (can be specified multiple times)') + [CompletionResult]::new('--iglob', '--iglob', [CompletionResultType]::ParameterName, 'pattern to find case-insensitive (can be specified multiple times)') + [CompletionResult]::new('--path', '--path', [CompletionResultType]::ParameterName, 'exact path to find') + [CompletionResult]::new('-g', '-g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') + [CompletionResult]::new('--group-by', '--group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Show all snapshots instead of summarizing snapshots with identical search results') + [CompletionResult]::new('--show-misses', '--show-misses', [CompletionResultType]::ParameterName, 'Also show snapshots which don''t contain a search result') + [CompletionResult]::new('--numeric-uid-gid', '--numeric-uid-gid', [CompletionResultType]::ParameterName, 'Show uid/gid instead of user/group') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;forget' { - [CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")') - [CompletionResult]::new('--group-by', 'group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--keep-tags', 'keep-tags', [CompletionResultType]::ParameterName, 'Keep snapshots with this taglist (can be specified multiple times)') - [CompletionResult]::new('--keep-id', 'keep-id', [CompletionResultType]::ParameterName, 'Keep snapshots ids that start with ID (can be specified multiple times)') - [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'Keep the last N snapshots (N == -1: keep all snapshots)') - [CompletionResult]::new('--keep-last', 'keep-last', [CompletionResultType]::ParameterName, 'Keep the last N snapshots (N == -1: keep all snapshots)') - [CompletionResult]::new('-H', 'H ', [CompletionResultType]::ParameterName, 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)') - [CompletionResult]::new('--keep-hourly', 'keep-hourly', [CompletionResultType]::ParameterName, 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)') - [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)') - [CompletionResult]::new('--keep-daily', 'keep-daily', [CompletionResultType]::ParameterName, 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)') - [CompletionResult]::new('-w', 'w', [CompletionResultType]::ParameterName, 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)') - [CompletionResult]::new('--keep-weekly', 'keep-weekly', [CompletionResultType]::ParameterName, 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)') - [CompletionResult]::new('-m', 'm', [CompletionResultType]::ParameterName, 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)') - [CompletionResult]::new('--keep-monthly', 'keep-monthly', [CompletionResultType]::ParameterName, 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)') - [CompletionResult]::new('--keep-quarter-yearly', 'keep-quarter-yearly', [CompletionResultType]::ParameterName, 'Keep the last N quarter-yearly snapshots (N == -1: keep all quarter-yearly snapshots)') - [CompletionResult]::new('--keep-half-yearly', 'keep-half-yearly', [CompletionResultType]::ParameterName, 'Keep the last N half-yearly snapshots (N == -1: keep all half-yearly snapshots)') - [CompletionResult]::new('-y', 'y', [CompletionResultType]::ParameterName, 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)') - [CompletionResult]::new('--keep-yearly', 'keep-yearly', [CompletionResultType]::ParameterName, 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)') - [CompletionResult]::new('--keep-within', 'keep-within', [CompletionResultType]::ParameterName, 'Keep snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-hourly', 'keep-within-hourly', [CompletionResultType]::ParameterName, 'Keep hourly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-daily', 'keep-within-daily', [CompletionResultType]::ParameterName, 'Keep daily snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-weekly', 'keep-within-weekly', [CompletionResultType]::ParameterName, 'Keep weekly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-monthly', 'keep-within-monthly', [CompletionResultType]::ParameterName, 'Keep monthly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-quarter-yearly', 'keep-within-quarter-yearly', [CompletionResultType]::ParameterName, 'Keep quarter-yearly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-half-yearly', 'keep-within-half-yearly', [CompletionResultType]::ParameterName, 'Keep half-yearly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--keep-within-yearly', 'keep-within-yearly', [CompletionResultType]::ParameterName, 'Keep yearly snapshots newer than DURATION relative to latest snapshot') - [CompletionResult]::new('--max-repack', 'max-repack', [CompletionResultType]::ParameterName, 'Define maximum data to repack in % of reposize or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') - [CompletionResult]::new('--max-unused', 'max-unused', [CompletionResultType]::ParameterName, 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') - [CompletionResult]::new('--keep-pack', 'keep-pack', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won''t be repacked or marked for deletion within this prune run') - [CompletionResult]::new('--keep-delete', 'keep-delete', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won''t be deleted within this prune run') - [CompletionResult]::new('--repack-cacheable-only', 'repack-cacheable-only', [CompletionResultType]::ParameterName, 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Show infos in json format') - [CompletionResult]::new('--prune', 'prune', [CompletionResultType]::ParameterName, 'Also prune the repository') - [CompletionResult]::new('--instant-delete', 'instant-delete', [CompletionResultType]::ParameterName, 'Delete files immediately instead of marking them. This also removes all files already marked for deletion') - [CompletionResult]::new('--fast-repack', 'fast-repack', [CompletionResultType]::ParameterName, 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting') - [CompletionResult]::new('--repack-uncompressed', 'repack-uncompressed', [CompletionResultType]::ParameterName, 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0') - [CompletionResult]::new('--repack-all', 'repack-all', [CompletionResultType]::ParameterName, 'Repack all packs. Implies --max-unused=0') - [CompletionResult]::new('--no-resize', 'no-resize', [CompletionResultType]::ParameterName, 'Do not repack packs which only needs to be resized') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-g', '-g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")') + [CompletionResult]::new('--group-by', '--group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags (default: "host,label,paths")') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--keep-tags', '--keep-tags', [CompletionResultType]::ParameterName, 'Keep snapshots with this taglist (can be specified multiple times)') + [CompletionResult]::new('--keep-id', '--keep-id', [CompletionResultType]::ParameterName, 'Keep snapshots ids that start with ID (can be specified multiple times)') + [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'Keep the last N snapshots (N == -1: keep all snapshots)') + [CompletionResult]::new('--keep-last', '--keep-last', [CompletionResultType]::ParameterName, 'Keep the last N snapshots (N == -1: keep all snapshots)') + [CompletionResult]::new('-H', '-H ', [CompletionResultType]::ParameterName, 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)') + [CompletionResult]::new('--keep-hourly', '--keep-hourly', [CompletionResultType]::ParameterName, 'Keep the last N hourly snapshots (N == -1: keep all hourly snapshots)') + [CompletionResult]::new('-d', '-d', [CompletionResultType]::ParameterName, 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)') + [CompletionResult]::new('--keep-daily', '--keep-daily', [CompletionResultType]::ParameterName, 'Keep the last N daily snapshots (N == -1: keep all daily snapshots)') + [CompletionResult]::new('-w', '-w', [CompletionResultType]::ParameterName, 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)') + [CompletionResult]::new('--keep-weekly', '--keep-weekly', [CompletionResultType]::ParameterName, 'Keep the last N weekly snapshots (N == -1: keep all weekly snapshots)') + [CompletionResult]::new('-m', '-m', [CompletionResultType]::ParameterName, 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)') + [CompletionResult]::new('--keep-monthly', '--keep-monthly', [CompletionResultType]::ParameterName, 'Keep the last N monthly snapshots (N == -1: keep all monthly snapshots)') + [CompletionResult]::new('--keep-quarter-yearly', '--keep-quarter-yearly', [CompletionResultType]::ParameterName, 'Keep the last N quarter-yearly snapshots (N == -1: keep all quarter-yearly snapshots)') + [CompletionResult]::new('--keep-half-yearly', '--keep-half-yearly', [CompletionResultType]::ParameterName, 'Keep the last N half-yearly snapshots (N == -1: keep all half-yearly snapshots)') + [CompletionResult]::new('-y', '-y', [CompletionResultType]::ParameterName, 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)') + [CompletionResult]::new('--keep-yearly', '--keep-yearly', [CompletionResultType]::ParameterName, 'Keep the last N yearly snapshots (N == -1: keep all yearly snapshots)') + [CompletionResult]::new('--keep-within', '--keep-within', [CompletionResultType]::ParameterName, 'Keep snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-hourly', '--keep-within-hourly', [CompletionResultType]::ParameterName, 'Keep hourly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-daily', '--keep-within-daily', [CompletionResultType]::ParameterName, 'Keep daily snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-weekly', '--keep-within-weekly', [CompletionResultType]::ParameterName, 'Keep weekly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-monthly', '--keep-within-monthly', [CompletionResultType]::ParameterName, 'Keep monthly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-quarter-yearly', '--keep-within-quarter-yearly', [CompletionResultType]::ParameterName, 'Keep quarter-yearly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-half-yearly', '--keep-within-half-yearly', [CompletionResultType]::ParameterName, 'Keep half-yearly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--keep-within-yearly', '--keep-within-yearly', [CompletionResultType]::ParameterName, 'Keep yearly snapshots newer than DURATION relative to latest snapshot') + [CompletionResult]::new('--max-repack', '--max-repack', [CompletionResultType]::ParameterName, 'Define maximum data to repack in % of reposize or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') + [CompletionResult]::new('--max-unused', '--max-unused', [CompletionResultType]::ParameterName, 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') + [CompletionResult]::new('--keep-pack', '--keep-pack', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won''t be repacked or marked for deletion within this prune run') + [CompletionResult]::new('--keep-delete', '--keep-delete', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won''t be deleted within this prune run') + [CompletionResult]::new('--repack-cacheable-only', '--repack-cacheable-only', [CompletionResultType]::ParameterName, 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'Show infos in json format') + [CompletionResult]::new('--quiet', '--quiet', [CompletionResultType]::ParameterName, 'Don''t show any output') + [CompletionResult]::new('--prune', '--prune', [CompletionResultType]::ParameterName, 'Also prune the repository') + [CompletionResult]::new('--keep-none', '--keep-none', [CompletionResultType]::ParameterName, 'Allow to keep no snapshot') + [CompletionResult]::new('--instant-delete', '--instant-delete', [CompletionResultType]::ParameterName, 'Delete files immediately instead of marking them. This also removes all files already marked for deletion') + [CompletionResult]::new('--early-delete-index', '--early-delete-index', [CompletionResultType]::ParameterName, 'Delete index files early. This allows to run prune if there is few or no space left') + [CompletionResult]::new('--fast-repack', '--fast-repack', [CompletionResultType]::ParameterName, 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting') + [CompletionResult]::new('--repack-uncompressed', '--repack-uncompressed', [CompletionResultType]::ParameterName, 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0') + [CompletionResult]::new('--repack-all', '--repack-all', [CompletionResultType]::ParameterName, 'Repack all packs. Implies --max-unused=0') + [CompletionResult]::new('--no-resize', '--no-resize', [CompletionResultType]::ParameterName, 'Do not repack packs which only needs to be resized') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;init' { - [CompletionResult]::new('--hostname', 'hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') - [CompletionResult]::new('--username', 'username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') - [CompletionResult]::new('--set-compression', 'set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') - [CompletionResult]::new('--set-version', 'set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') - [CompletionResult]::new('--set-treepack-size', 'set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') - [CompletionResult]::new('--set-treepack-size-limit', 'set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-treepack-growfactor', 'set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size', 'set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') - [CompletionResult]::new('--set-datapack-growfactor', 'set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') - [CompletionResult]::new('--set-datapack-size-limit', 'set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately `4 GiB`') - [CompletionResult]::new('--set-min-packsize-tolerate-percent', 'set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') - [CompletionResult]::new('--set-max-packsize-tolerate-percent', 'set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--with-created', 'with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--hostname', '--hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') + [CompletionResult]::new('--username', '--username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') + [CompletionResult]::new('--set-compression', '--set-compression', [CompletionResultType]::ParameterName, 'Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression') + [CompletionResult]::new('--set-version', '--set-version', [CompletionResultType]::ParameterName, 'Set repository version. Allowed versions: 1,2') + [CompletionResult]::new('--set-append-only', '--set-append-only', [CompletionResultType]::ParameterName, 'Set append-only mode. Note that only append-only commands work once this is set. `forget`, `prune` or `config` won''t work any longer') + [CompletionResult]::new('--set-treepack-size', '--set-treepack-size', [CompletionResultType]::ParameterName, 'Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `4 MiB` if not set') + [CompletionResult]::new('--set-treepack-size-limit', '--set-treepack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-treepack-growfactor', '--set-treepack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to `32` (= 1MB per square root of total treesize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size', '--set-datapack-size', [CompletionResultType]::ParameterName, 'Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to `32 MiB` if not set') + [CompletionResult]::new('--set-datapack-growfactor', '--set-datapack-growfactor', [CompletionResultType]::ParameterName, 'Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to `32` (= 1MB per square root of total datasize in GiB) if not set') + [CompletionResult]::new('--set-datapack-size-limit', '--set-datapack-size-limit', [CompletionResultType]::ParameterName, 'Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately `4 GiB`') + [CompletionResult]::new('--set-min-packsize-tolerate-percent', '--set-min-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set minimum tolerated packsize in percent of the targeted packsize. Defaults to `30` if not set') + [CompletionResult]::new('--set-max-packsize-tolerate-percent', '--set-max-packsize-tolerate-percent', [CompletionResultType]::ParameterName, 'Set maximum tolerated packsize in percent of the targeted packsize A value of `0` means packs larger than the targeted packsize are always tolerated. Default if not set: larger packfiles are always tolerated') + [CompletionResult]::new('--set-extra-verify', '--set-extra-verify', [CompletionResultType]::ParameterName, 'Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default: true') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--with-created', '--with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;key' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('add', 'add', [CompletionResultType]::ParameterValue, 'Add a new key to the repository') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } 'rustic;key;add' { - [CompletionResult]::new('--new-password-file', 'new-password-file', [CompletionResultType]::ParameterName, 'File from which to read the new password') - [CompletionResult]::new('--hostname', 'hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') - [CompletionResult]::new('--username', 'username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--with-created', 'with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--new-password', '--new-password', [CompletionResultType]::ParameterName, 'New password') + [CompletionResult]::new('--new-password-file', '--new-password-file', [CompletionResultType]::ParameterName, 'File from which to read the new password') + [CompletionResult]::new('--new-password-command', '--new-password-command', [CompletionResultType]::ParameterName, 'Command to get the new password from') + [CompletionResult]::new('--hostname', '--hostname', [CompletionResultType]::ParameterName, 'Set ''hostname'' in public key information') + [CompletionResult]::new('--username', '--username', [CompletionResultType]::ParameterName, 'Set ''username'' in public key information') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--with-created', '--with-created', [CompletionResultType]::ParameterName, 'Add ''created'' date in public key information') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;key;help' { @@ -795,385 +891,411 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { break } 'rustic;list' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;ls' { - [CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') - [CompletionResult]::new('--iglob', 'iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') - [CompletionResult]::new('--glob-file', 'glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') - [CompletionResult]::new('--iglob-file', 'iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'show summary') - [CompletionResult]::new('--summary', 'summary', [CompletionResultType]::ParameterName, 'show summary') - [CompletionResult]::new('-l', 'l', [CompletionResultType]::ParameterName, 'show long listing') - [CompletionResult]::new('--long', 'long', [CompletionResultType]::ParameterName, 'show long listing') - [CompletionResult]::new('--recursive', 'recursive', [CompletionResultType]::ParameterName, 'recursively list the dir') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--glob', '--glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') + [CompletionResult]::new('--iglob', '--iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') + [CompletionResult]::new('--glob-file', '--glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') + [CompletionResult]::new('--iglob-file', '--iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-s', '-s', [CompletionResultType]::ParameterName, 'show summary') + [CompletionResult]::new('--summary', '--summary', [CompletionResultType]::ParameterName, 'show summary') + [CompletionResult]::new('-l', '-l', [CompletionResultType]::ParameterName, 'show long listing') + [CompletionResult]::new('--long', '--long', [CompletionResultType]::ParameterName, 'show long listing') + [CompletionResult]::new('--numeric-uid-gid', '--numeric-uid-gid', [CompletionResultType]::ParameterName, 'show uid/gid instead of user/group') + [CompletionResult]::new('--recursive', '--recursive', [CompletionResultType]::ParameterName, 'recursively list the dir') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;merge' { - [CompletionResult]::new('--label', 'label', [CompletionResultType]::ParameterName, 'Label snapshot with given label') - [CompletionResult]::new('--tag', 'tag', [CompletionResultType]::ParameterName, 'Tags to add to snapshot (can be specified multiple times)') - [CompletionResult]::new('--description', 'description', [CompletionResultType]::ParameterName, 'Add description to snapshot') - [CompletionResult]::new('--description-from', 'description-from', [CompletionResultType]::ParameterName, 'Add description to snapshot from file') - [CompletionResult]::new('--time', 'time', [CompletionResultType]::ParameterName, 'Set the backup time manually') - [CompletionResult]::new('--delete-after', 'delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') - [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'Set the host name manually') - [CompletionResult]::new('--command', 'command', [CompletionResultType]::ParameterName, 'Set the backup command manually') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Output generated snapshot in json format') - [CompletionResult]::new('--delete', 'delete', [CompletionResultType]::ParameterName, 'Remove input snapshots after merging') - [CompletionResult]::new('--delete-never', 'delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--label', '--label', [CompletionResultType]::ParameterName, 'Label snapshot with given label') + [CompletionResult]::new('--tag', '--tag', [CompletionResultType]::ParameterName, 'Tags to add to snapshot (can be specified multiple times)') + [CompletionResult]::new('--description', '--description', [CompletionResultType]::ParameterName, 'Add description to snapshot') + [CompletionResult]::new('--description-from', '--description-from', [CompletionResultType]::ParameterName, 'Add description to snapshot from file') + [CompletionResult]::new('--time', '--time', [CompletionResultType]::ParameterName, 'Set the backup time manually') + [CompletionResult]::new('--delete-after', '--delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') + [CompletionResult]::new('--host', '--host', [CompletionResultType]::ParameterName, 'Set the host name manually') + [CompletionResult]::new('--command', '--command', [CompletionResultType]::ParameterName, 'Set the backup command manually') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'Output generated snapshot in json format') + [CompletionResult]::new('--delete', '--delete', [CompletionResultType]::ParameterName, 'Remove input snapshots after merging') + [CompletionResult]::new('--delete-never', '--delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;snapshots' { - [CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') - [CompletionResult]::new('--group-by', 'group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--long', 'long', [CompletionResultType]::ParameterName, 'Show detailed information about snapshots') - [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Show snapshots in json format') - [CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'Show all snapshots instead of summarizing identical follow-up snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-g', '-g', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') + [CompletionResult]::new('--group-by', '--group-by', [CompletionResultType]::ParameterName, 'Group snapshots by any combination of host,label,paths,tags') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--long', '--long', [CompletionResultType]::ParameterName, 'Show detailed information about snapshots') + [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'Show snapshots in json format') + [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Show all snapshots instead of summarizing identical follow-up snapshots') + [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'Run in interactive UI mode') + [CompletionResult]::new('--interactive', '--interactive', [CompletionResultType]::ParameterName, 'Run in interactive UI mode') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;show-config' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;self-update' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--force', 'force', [CompletionResultType]::ParameterName, 'Do not ask before processing the self-update') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--force', '--force', [CompletionResultType]::ParameterName, 'Do not ask before processing the self-update') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;prune' { - [CompletionResult]::new('--max-repack', 'max-repack', [CompletionResultType]::ParameterName, 'Define maximum data to repack in % of reposize or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') - [CompletionResult]::new('--max-unused', 'max-unused', [CompletionResultType]::ParameterName, 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') - [CompletionResult]::new('--keep-pack', 'keep-pack', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won''t be repacked or marked for deletion within this prune run') - [CompletionResult]::new('--keep-delete', 'keep-delete', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won''t be deleted within this prune run') - [CompletionResult]::new('--repack-cacheable-only', 'repack-cacheable-only', [CompletionResultType]::ParameterName, 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--instant-delete', 'instant-delete', [CompletionResultType]::ParameterName, 'Delete files immediately instead of marking them. This also removes all files already marked for deletion') - [CompletionResult]::new('--fast-repack', 'fast-repack', [CompletionResultType]::ParameterName, 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting') - [CompletionResult]::new('--repack-uncompressed', 'repack-uncompressed', [CompletionResultType]::ParameterName, 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0') - [CompletionResult]::new('--repack-all', 'repack-all', [CompletionResultType]::ParameterName, 'Repack all packs. Implies --max-unused=0') - [CompletionResult]::new('--no-resize', 'no-resize', [CompletionResultType]::ParameterName, 'Do not repack packs which only needs to be resized') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--max-repack', '--max-repack', [CompletionResultType]::ParameterName, 'Define maximum data to repack in % of reposize or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') + [CompletionResult]::new('--max-unused', '--max-unused', [CompletionResultType]::ParameterName, 'Tolerate limit of unused data in % of reposize after pruning or as size (e.g. ''5b'', ''2 kB'', ''3M'', ''4TiB'') or ''unlimited''') + [CompletionResult]::new('--keep-pack', '--keep-pack', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won''t be repacked or marked for deletion within this prune run') + [CompletionResult]::new('--keep-delete', '--keep-delete', [CompletionResultType]::ParameterName, 'Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won''t be deleted within this prune run') + [CompletionResult]::new('--repack-cacheable-only', '--repack-cacheable-only', [CompletionResultType]::ParameterName, 'Only repack packs which are cacheable [default: true for a hot/cold repository, else false]') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--instant-delete', '--instant-delete', [CompletionResultType]::ParameterName, 'Delete files immediately instead of marking them. This also removes all files already marked for deletion') + [CompletionResult]::new('--early-delete-index', '--early-delete-index', [CompletionResultType]::ParameterName, 'Delete index files early. This allows to run prune if there is few or no space left') + [CompletionResult]::new('--fast-repack', '--fast-repack', [CompletionResultType]::ParameterName, 'Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting') + [CompletionResult]::new('--repack-uncompressed', '--repack-uncompressed', [CompletionResultType]::ParameterName, 'Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0') + [CompletionResult]::new('--repack-all', '--repack-all', [CompletionResultType]::ParameterName, 'Repack all packs. Implies --max-unused=0') + [CompletionResult]::new('--no-resize', '--no-resize', [CompletionResultType]::ParameterName, 'Do not repack packs which only needs to be resized') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;restore' { - [CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') - [CompletionResult]::new('--iglob', 'iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') - [CompletionResult]::new('--glob-file', 'glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') - [CompletionResult]::new('--iglob-file', 'iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--delete', 'delete', [CompletionResultType]::ParameterName, 'Remove all files/dirs in destination which are not contained in snapshot') - [CompletionResult]::new('--numeric-id', 'numeric-id', [CompletionResultType]::ParameterName, 'Use numeric ids instead of user/group when restoring uid/gui') - [CompletionResult]::new('--no-ownership', 'no-ownership', [CompletionResultType]::ParameterName, 'Don''t restore ownership (user/group)') - [CompletionResult]::new('--verify-existing', 'verify-existing', [CompletionResultType]::ParameterName, 'Always read and verify existing files (don''t trust correct modification time and file size)') - [CompletionResult]::new('--recursive', 'recursive', [CompletionResultType]::ParameterName, 'recursively list the dir') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--glob', '--glob', [CompletionResultType]::ParameterName, 'Glob pattern to exclude/include (can be specified multiple times)') + [CompletionResult]::new('--iglob', '--iglob', [CompletionResultType]::ParameterName, 'Same as --glob pattern but ignores the casing of filenames') + [CompletionResult]::new('--glob-file', '--glob-file', [CompletionResultType]::ParameterName, 'Read glob patterns to exclude/include from this file (can be specified multiple times)') + [CompletionResult]::new('--iglob-file', '--iglob-file', [CompletionResultType]::ParameterName, 'Same as --glob-file ignores the casing of filenames in patterns') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--delete', '--delete', [CompletionResultType]::ParameterName, 'Remove all files/dirs in destination which are not contained in snapshot') + [CompletionResult]::new('--numeric-id', '--numeric-id', [CompletionResultType]::ParameterName, 'Use numeric ids instead of user/group when restoring uid/gui') + [CompletionResult]::new('--no-ownership', '--no-ownership', [CompletionResultType]::ParameterName, 'Don''t restore ownership (user/group)') + [CompletionResult]::new('--verify-existing', '--verify-existing', [CompletionResultType]::ParameterName, 'Always read and verify existing files (don''t trust correct modification time and file size)') + [CompletionResult]::new('--recursive', '--recursive', [CompletionResultType]::ParameterName, 'recursively list the dir') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;repair' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') [CompletionResult]::new('index', 'index', [CompletionResultType]::ParameterValue, 'Repair the repository index') [CompletionResult]::new('snapshots', 'snapshots', [CompletionResultType]::ParameterValue, 'Repair snapshots') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } 'rustic;repair;index' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--read-all', 'read-all', [CompletionResultType]::ParameterName, 'Read all data packs, i.e. completely re-create the index') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--read-all', '--read-all', [CompletionResultType]::ParameterName, 'Read all data packs, i.e. completely re-create the index') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;repair;snapshots' { - [CompletionResult]::new('--suffix', 'suffix', [CompletionResultType]::ParameterName, 'Append this suffix to repaired directory or file name') - [CompletionResult]::new('--tag', 'tag', [CompletionResultType]::ParameterName, 'Tag list to set on repaired snapshots (can be specified multiple times)') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--delete', 'delete', [CompletionResultType]::ParameterName, 'Also remove defect snapshots') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--suffix', '--suffix', [CompletionResultType]::ParameterName, 'Append this suffix to repaired directory or file name') + [CompletionResult]::new('--tag', '--tag', [CompletionResultType]::ParameterName, 'Tag list to set on repaired snapshots (can be specified multiple times)') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--delete', '--delete', [CompletionResultType]::ParameterName, 'Also remove defect snapshots') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;repair;help' { @@ -1192,72 +1314,113 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { break } 'rustic;repoinfo' { - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--only-files', 'only-files', [CompletionResultType]::ParameterName, 'Only scan repository files (doesn''t need repository password)') - [CompletionResult]::new('--only-index', 'only-index', [CompletionResultType]::ParameterName, 'Only scan index') - [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Show infos in json format') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--only-files', '--only-files', [CompletionResultType]::ParameterName, 'Only scan repository files (doesn''t need repository password)') + [CompletionResult]::new('--only-index', '--only-index', [CompletionResultType]::ParameterName, 'Only scan index') + [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'Show infos in json format') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;tag' { - [CompletionResult]::new('--add', 'add', [CompletionResultType]::ParameterName, 'Tags to add (can be specified multiple times)') - [CompletionResult]::new('--remove', 'remove', [CompletionResultType]::ParameterName, 'Tags to remove (can be specified multiple times)') - [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'Tag list to set (can be specified multiple times)') - [CompletionResult]::new('--set-delete-after', 'set-delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') - [CompletionResult]::new('-P', 'P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--use-profile', 'use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') - [CompletionResult]::new('--log-level', 'log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') - [CompletionResult]::new('--log-file', 'log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') - [CompletionResult]::new('--progress-interval', 'progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') - [CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repository', 'repository', [CompletionResultType]::ParameterName, 'Repository to use') - [CompletionResult]::new('--repo-hot', 'repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') - [CompletionResult]::new('--password', 'password', [CompletionResultType]::ParameterName, 'Password of the repository') - [CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-file', 'password-file', [CompletionResultType]::ParameterName, 'File to read the password from') - [CompletionResult]::new('--password-command', 'password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') - [CompletionResult]::new('--cache-dir', 'cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') - [CompletionResult]::new('--warm-up-command', 'warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') - [CompletionResult]::new('--warm-up-wait', 'warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') - [CompletionResult]::new('--filter-host', 'filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-label', 'filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-paths', 'filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-tags', 'filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') - [CompletionResult]::new('--filter-fn', 'filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') - [CompletionResult]::new('--remove-delete', 'remove-delete', [CompletionResultType]::ParameterName, 'Remove any delete mark') - [CompletionResult]::new('--set-delete-never', 'set-delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') - [CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') - [CompletionResult]::new('--no-progress', 'no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') - [CompletionResult]::new('--no-cache', 'no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') - [CompletionResult]::new('--warm-up', 'warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') - [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') - [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--add', '--add', [CompletionResultType]::ParameterName, 'Tags to add (can be specified multiple times)') + [CompletionResult]::new('--remove', '--remove', [CompletionResultType]::ParameterName, 'Tags to remove (can be specified multiple times)') + [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'Tag list to set (can be specified multiple times)') + [CompletionResult]::new('--set-delete-after', '--set-delete-after', [CompletionResultType]::ParameterName, 'Mark snapshot to be deleted after given duration (e.g. 10d)') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--remove-delete', '--remove-delete', [CompletionResultType]::ParameterName, 'Remove any delete mark') + [CompletionResult]::new('--set-delete-never', '--set-delete-never', [CompletionResultType]::ParameterName, 'Mark snapshot as uneraseable') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + break + } + 'rustic;webdav' { + [CompletionResult]::new('--address', '--address', [CompletionResultType]::ParameterName, 'Address to bind the webdav server to. [default: "localhost:8000"]') + [CompletionResult]::new('--path-template', '--path-template', [CompletionResultType]::ParameterName, 'The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. [default: "[{hostname}]/[{label}]/{time}"]') + [CompletionResult]::new('--time-template', '--time-template', [CompletionResultType]::ParameterName, 'The time template to use to display times in the path template. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. [default: "%Y-%m-%d_%H-%M-%S"]') + [CompletionResult]::new('--file-access', '--file-access', [CompletionResultType]::ParameterName, 'How to handle access to files. [default: "forbidden" for hot/cold repositories, else "read"]') + [CompletionResult]::new('-P', '-P ', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--use-profile', '--use-profile', [CompletionResultType]::ParameterName, 'Config profile to use. This parses the file `.toml` in the config directory. [default: "rustic"]') + [CompletionResult]::new('--log-level', '--log-level', [CompletionResultType]::ParameterName, 'Use this log level [default: info]') + [CompletionResult]::new('--log-file', '--log-file', [CompletionResultType]::ParameterName, 'Write log messages to the given file instead of printing them') + [CompletionResult]::new('--progress-interval', '--progress-interval', [CompletionResultType]::ParameterName, 'Interval to update progress bars') + [CompletionResult]::new('-r', '-r', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repository', '--repository', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo', '--repo', [CompletionResultType]::ParameterName, 'Repository to use') + [CompletionResult]::new('--repo-hot', '--repo-hot', [CompletionResultType]::ParameterName, 'Repository to use as hot storage') + [CompletionResult]::new('--password', '--password', [CompletionResultType]::ParameterName, 'Password of the repository') + [CompletionResult]::new('-p', '-p', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-file', '--password-file', [CompletionResultType]::ParameterName, 'File to read the password from') + [CompletionResult]::new('--password-command', '--password-command', [CompletionResultType]::ParameterName, 'Command to read the password from. Password is read from stdout') + [CompletionResult]::new('--cache-dir', '--cache-dir', [CompletionResultType]::ParameterName, 'Use this dir as cache dir instead of the standard cache dir') + [CompletionResult]::new('--warm-up-command', '--warm-up-command', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by running the command with %id replaced by pack id') + [CompletionResult]::new('--warm-up-wait', '--warm-up-wait', [CompletionResultType]::ParameterName, 'Duration (e.g. 10m) to wait after warm up') + [CompletionResult]::new('--filter-host', '--filter-host', [CompletionResultType]::ParameterName, 'Hostname to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-label', '--filter-label', [CompletionResultType]::ParameterName, 'Label to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-paths', '--filter-paths', [CompletionResultType]::ParameterName, 'Path list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-tags', '--filter-tags', [CompletionResultType]::ParameterName, 'Tag list to filter (can be specified multiple times)') + [CompletionResult]::new('--filter-fn', '--filter-fn', [CompletionResultType]::ParameterName, 'Function to filter snapshots') + [CompletionResult]::new('--symlinks', '--symlinks', [CompletionResultType]::ParameterName, 'Use symlinks. This may not be supported by all WebDAV clients') + [CompletionResult]::new('-n', '-n', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--dry-run', '--dry-run', [CompletionResultType]::ParameterName, 'Only show what would be done without modifying anything. Does not affect read-only commands') + [CompletionResult]::new('--check-index', '--check-index', [CompletionResultType]::ParameterName, 'Check if index matches pack files and read pack headers if neccessary') + [CompletionResult]::new('--no-progress', '--no-progress', [CompletionResultType]::ParameterName, 'Don''t show any progress bar') + [CompletionResult]::new('--no-cache', '--no-cache', [CompletionResultType]::ParameterName, 'Don''t use a cache') + [CompletionResult]::new('--warm-up', '--warm-up', [CompletionResultType]::ParameterName, 'Warm up needed data pack files by only requesting them without processing') + [CompletionResult]::new('-h', '-h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') + [CompletionResult]::new('--help', '--help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')') break } 'rustic;help' { @@ -1269,6 +1432,7 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { [CompletionResult]::new('copy', 'copy', [CompletionResultType]::ParameterValue, 'Copy snapshots to other repositories. Note: The target repositories must be given in the config file!') [CompletionResult]::new('diff', 'diff', [CompletionResultType]::ParameterValue, 'Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path') [CompletionResult]::new('dump', 'dump', [CompletionResultType]::ParameterValue, 'dump the contents of a file in a snapshot to stdout') + [CompletionResult]::new('find', 'find', [CompletionResultType]::ParameterValue, 'Find in given snapshots') [CompletionResult]::new('forget', 'forget', [CompletionResultType]::ParameterValue, 'Remove snapshots from the repository') [CompletionResult]::new('init', 'init', [CompletionResultType]::ParameterValue, 'Initialize a new repository') [CompletionResult]::new('key', 'key', [CompletionResultType]::ParameterValue, 'Manage keys') @@ -1283,6 +1447,7 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { [CompletionResult]::new('repair', 'repair', [CompletionResultType]::ParameterValue, 'Repair a snapshot/path') [CompletionResult]::new('repoinfo', 'repoinfo', [CompletionResultType]::ParameterValue, 'Show general information about the repository') [CompletionResult]::new('tag', 'tag', [CompletionResultType]::ParameterValue, 'Change tags of snapshots') + [CompletionResult]::new('webdav', 'webdav', [CompletionResultType]::ParameterValue, 'Start a webdav server which allows to access the repository') [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Print this message or the help of the given subcommand(s)') break } @@ -1334,6 +1499,9 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { 'rustic;help;dump' { break } + 'rustic;help;find' { + break + } 'rustic;help;forget' { break } @@ -1388,6 +1556,9 @@ Register-ArgumentCompleter -Native -CommandName 'rustic' -ScriptBlock { 'rustic;help;tag' { break } + 'rustic;help;webdav' { + break + } 'rustic;help;help' { break } diff --git a/tests/completions-fixtures/zsh.txt b/tests/completions-fixtures/zsh.txt index 8cb04dba7..60aaa0e41 100644 --- a/tests/completions-fixtures/zsh.txt +++ b/tests/completions-fixtures/zsh.txt @@ -14,20 +14,21 @@ _rustic() { fi local context curcontext="$curcontext" state line - _arguments "${_arguments_options[@]}" \ + _arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -37,6 +38,7 @@ _rustic() { '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -54,9 +56,9 @@ _rustic() { curcontext="${curcontext%:*:*}:rustic-command-$line[1]:" case $line[1] in (backup) -_arguments "${_arguments_options[@]}" \ -'--stdin-filename=[Set filename to be used when backing up from stdin]:FILENAME: ' \ -'--as-path=[Manually set backup path in snapshot]:PATH:_files' \ +_arguments "${_arguments_options[@]}" : \ +'--stdin-filename=[Set filename to be used when backing up from stdin]:FILENAME:_files' \ +'--as-path=[Manually set backup path in snapshot]:PATH:_files -/' \ '-g+[Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default\: host,label,paths)]:CRITERION: ' \ '--group-by=[Group snapshots by any combination of host,label,paths,tags to find a suitable parent (default\: host,label,paths)]:CRITERION: ' \ '(-f --force)--parent=[Snapshot to use as parent]:SNAPSHOT: ' \ @@ -64,6 +66,7 @@ _arguments "${_arguments_options[@]}" \ '*--iglob=[Same as --glob pattern but ignores the casing of filenames]:GLOB: ' \ '*--glob-file=[Read glob patterns to exclude/include from this file (can be specified multiple times)]:FILE: ' \ '*--iglob-file=[Same as --glob-file ignores the casing of filenames in patterns]:FILE: ' \ +'*--custom-ignorefile=[Treat the provided filename like a .gitignore file (can be specified multiple times)]:FILE: ' \ '*--exclude-if-present=[Exclude contents of directories containing this filename (can be specified multiple times)]:FILE: ' \ '--exclude-larger-than=[Maximum size of files to be backed up. Larger files will be excluded]:SIZE: ' \ '--label=[Label snapshot with given label]:LABEL: ' \ @@ -78,27 +81,30 @@ _arguments "${_arguments_options[@]}" \ '--username=[Set '\''username'\'' in public key information]:USERNAME: ' \ '--set-compression=[Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression]:LEVEL: ' \ '--set-version=[Set repository version. Allowed versions\: 1,2]:VERSION: ' \ +'--set-append-only=[Set append-only mode. Note that only append-only commands work once this is set. \`forget\`, \`prune\` or \`config\` won'\''t work any longer]:SET_APPEND_ONLY:(true false)' \ '--set-treepack-size=[Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`4 MiB\` if not set]:SIZE: ' \ -'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-treepack-growfactor=[Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to \`32\` (= 1MB per square root of total treesize in GiB) if not set]:FACTOR: ' \ '--set-datapack-size=[Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`32 MiB\` if not set]:SIZE: ' \ '--set-datapack-growfactor=[Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to \`32\` (= 1MB per square root of total datasize in GiB) if not set]:FACTOR: ' \ -'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-min-packsize-tolerate-percent=[Set minimum tolerated packsize in percent of the targeted packsize. Defaults to \`30\` if not set]:PERCENT: ' \ '--set-max-packsize-tolerate-percent=[Set maximum tolerated packsize in percent of the targeted packsize A value of \`0\` means packs larger than the targeted packsize are always tolerated. Default if not set\: larger packfiles are always tolerated]:PERCENT: ' \ +'--set-extra-verify=[Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default\: true]:SET_EXTRA_VERIFY:(true false)' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -108,8 +114,11 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '--with-atime[Save access time for files and directories]' \ '--ignore-devid[Don'\''t save device ID for files and directories]' \ +'--no-scan[Don'\''t scan the backup source for its size - this disables ETA estimation for backup]' \ '--json[Output generated snapshot in json format]' \ +'(--json)--quiet[Don'\''t show any output]' \ '--init[Initialize repository, if it doesn'\''t exist yet]' \ +'--skip-identical-parent[Skip writing of snapshot if nothing changed w.r.t. the parent snapshot]' \ '(--parent)-f[Use no parent, read all files]' \ '(--parent)--force[Use no parent, read all files]' \ '(-f --force)--ignore-ctime[Ignore ctime changes when checking for modified files]' \ @@ -122,29 +131,31 @@ _arguments "${_arguments_options[@]}" \ '--with-created[Add '\''created'\'' date in public key information]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ -'*::cli_sources -- Backup source (can be specified multiple times), use - for stdin. If no source is given, uses all sources defined in the config file:' \ +'*::cli_sources -- Backup source (can be specified multiple times), use - for stdin. If no source is given, uses all sources defined in the config file:_files' \ && ret=0 ;; (cat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -154,6 +165,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -170,20 +182,21 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-cat-command-$line[1]:" case $line[1] in (tree-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -193,6 +206,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -202,20 +216,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (data-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -225,6 +240,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -234,20 +250,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -257,6 +274,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -265,20 +283,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -288,6 +307,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -297,20 +317,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (snapshot) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -320,6 +341,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -329,20 +351,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (tree) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -352,6 +375,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -361,7 +385,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__cat__help_commands" \ "*::: :->help" \ && ret=0 @@ -373,31 +397,31 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-cat-help-command-$line[1]:" case $line[1] in (tree-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (data-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (snapshot) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tree) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -409,30 +433,33 @@ esac esac ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--set-compression=[Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression]:LEVEL: ' \ '--set-version=[Set repository version. Allowed versions\: 1,2]:VERSION: ' \ +'--set-append-only=[Set append-only mode. Note that only append-only commands work once this is set. \`forget\`, \`prune\` or \`config\` won'\''t work any longer]:SET_APPEND_ONLY:(true false)' \ '--set-treepack-size=[Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`4 MiB\` if not set]:SIZE: ' \ -'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-treepack-growfactor=[Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to \`32\` (= 1MB per square root of total treesize in GiB) if not set]:FACTOR: ' \ '--set-datapack-size=[Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`32 MiB\` if not set]:SIZE: ' \ '--set-datapack-growfactor=[Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to \`32\` (= 1MB per square root of total datasize in GiB) if not set]:FACTOR: ' \ -'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-min-packsize-tolerate-percent=[Set minimum tolerated packsize in percent of the targeted packsize. Defaults to \`30\` if not set]:PERCENT: ' \ '--set-max-packsize-tolerate-percent=[Set maximum tolerated packsize in percent of the targeted packsize A value of \`0\` means packs larger than the targeted packsize are always tolerated. Default if not set\: larger packfiles are always tolerated]:PERCENT: ' \ +'--set-extra-verify=[Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default\: true]:SET_EXTRA_VERIFY:(true false)' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -442,6 +469,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -450,20 +478,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (completions) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -473,6 +502,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -482,20 +512,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (check) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -507,6 +538,7 @@ _arguments "${_arguments_options[@]}" \ '--read-data[Read all data blobs]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -515,7 +547,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (copy) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--hostname=[Set '\''hostname'\'' in public key information]:HOSTNAME: ' \ '--username=[Set '\''username'\'' in public key information]:USERNAME: ' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ @@ -523,14 +555,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -542,6 +575,7 @@ _arguments "${_arguments_options[@]}" \ '--with-created[Add '\''created'\'' date in public key information]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -551,11 +585,12 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (diff) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*--glob=[Glob pattern to exclude/include (can be specified multiple times)]:GLOB: ' \ '*--iglob=[Same as --glob pattern but ignores the casing of filenames]:GLOB: ' \ '*--glob-file=[Read glob patterns to exclude/include from this file (can be specified multiple times)]:FILE: ' \ '*--iglob-file=[Same as --glob-file ignores the casing of filenames in patterns]:FILE: ' \ +'*--custom-ignorefile=[Treat the provided filename like a .gitignore file (can be specified multiple times)]:FILE: ' \ '*--exclude-if-present=[Exclude contents of directories containing this filename (can be specified multiple times)]:FILE: ' \ '--exclude-larger-than=[Maximum size of files to be backed up. Larger files will be excluded]:SIZE: ' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ @@ -563,14 +598,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -586,30 +622,32 @@ _arguments "${_arguments_options[@]}" \ '--one-file-system[Exclude other file systems, don'\''t cross filesystem boundaries and subvolumes]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ '-h[Print help (see more with '\''--help'\'')]' \ '--help[Print help (see more with '\''--help'\'')]' \ ':snap1 -- Reference snapshot/path:' \ -':snap2 -- New snapshot/path or local path \[default for PATH2\: PATH1\]:' \ +':snap2 -- New snapshot/path or local path \[default for PATH2\: PATH1\]:_files' \ && ret=0 ;; (dump) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -619,6 +657,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -627,8 +666,50 @@ _arguments "${_arguments_options[@]}" \ ':snap -- file from snapshot to dump:' \ && ret=0 ;; +(find) +_arguments "${_arguments_options[@]}" : \ +'(--path)*--glob=[pattern to find (can be specified multiple times)]:PATTERN: ' \ +'(--path)*--iglob=[pattern to find case-insensitive (can be specified multiple times)]:PATTERN: ' \ +'--path=[exact path to find]:PATH:_files' \ +'-g+[Group snapshots by any combination of host,label,paths,tags]:CRITERION: ' \ +'--group-by=[Group snapshots by any combination of host,label,paths,tags]:CRITERION: ' \ +'*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ +'*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ +'--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ +'--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ +'(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ +'--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ +'--password=[Password of the repository]:PASSWORD: ' \ +'(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ +'(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ +'(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ +'(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ +'--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ +'*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ +'*--filter-label=[Label to filter (can be specified multiple times)]:LABEL: ' \ +'*--filter-paths=[Path list to filter (can be specified multiple times)]:PATH[,PATH,..]: ' \ +'*--filter-tags=[Tag list to filter (can be specified multiple times)]:TAG[,TAG,..]: ' \ +'--filter-fn=[Function to filter snapshots]:FUNC: ' \ +'--all[Show all snapshots instead of summarizing snapshots with identical search results]' \ +'--show-misses[Also show snapshots which don'\''t contain a search result]' \ +'--numeric-uid-gid[Show uid/gid instead of user/group]' \ +'-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ +'--no-progress[Don'\''t show any progress bar]' \ +'--no-cache[Don'\''t use a cache]' \ +'--warm-up[Warm up needed data pack files by only requesting them without processing]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'*::ids -- Snapshots to search in. If none is given, use filter options to filter from all snapshots:' \ +&& ret=0 +;; (forget) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-g+[Group snapshots by any combination of host,label,paths,tags (default\: "host,label,paths")]:CRITERION: ' \ '--group-by=[Group snapshots by any combination of host,label,paths,tags (default\: "host,label,paths")]:CRITERION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -670,25 +751,30 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '--json[Show infos in json format]' \ +'(--json)--quiet[Don'\''t show any output]' \ '--prune[Also prune the repository]' \ +'--keep-none[Allow to keep no snapshot]' \ '--instant-delete[Delete files immediately instead of marking them. This also removes all files already marked for deletion]' \ +'--early-delete-index[Delete index files early. This allows to run prune if there is few or no space left]' \ '--fast-repack[Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting]' \ '(--fast-repack)--repack-uncompressed[Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0]' \ '--repack-all[Repack all packs. Implies --max-unused=0]' \ '--no-resize[Do not repack packs which only needs to be resized]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -698,32 +784,35 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (init) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--hostname=[Set '\''hostname'\'' in public key information]:HOSTNAME: ' \ '--username=[Set '\''username'\'' in public key information]:USERNAME: ' \ '--set-compression=[Set compression level. Allowed levels are 1 to 22 and -1 to -7, see . Note that 0 equals to no compression]:LEVEL: ' \ '--set-version=[Set repository version. Allowed versions\: 1,2]:VERSION: ' \ +'--set-append-only=[Set append-only mode. Note that only append-only commands work once this is set. \`forget\`, \`prune\` or \`config\` won'\''t work any longer]:SET_APPEND_ONLY:(true false)' \ '--set-treepack-size=[Set default packsize for tree packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`4 MiB\` if not set]:SIZE: ' \ -'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-treepack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-treepack-growfactor=[Set grow factor for tree packs. The default packsize grows by the square root of the total size of all tree packs multiplied with this factor. This means 32 kiB times this factor per square root of total treesize in GiB. Defaults to \`32\` (= 1MB per square root of total treesize in GiB) if not set]:FACTOR: ' \ '--set-datapack-size=[Set default packsize for data packs. rustic tries to always produce packs greater than this value. Note that for large repos, this value is grown by the grown factor. Defaults to \`32 MiB\` if not set]:SIZE: ' \ '--set-datapack-growfactor=[Set grow factor for data packs. The default packsize grows by the square root of the total size of all data packs multiplied with this factor. This means 32 kiB times this factor per square root of total datasize in GiB. Defaults to \`32\` (= 1MB per square root of total datasize in GiB) if not set]:FACTOR: ' \ -'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get up to some MiBs larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ +'--set-datapack-size-limit=[Set upper limit for default packsize for tree packs. Note that packs actually can get a bit larger. If not set, pack sizes can grow up to approximately \`4 GiB\`]:SIZE: ' \ '--set-min-packsize-tolerate-percent=[Set minimum tolerated packsize in percent of the targeted packsize. Defaults to \`30\` if not set]:PERCENT: ' \ '--set-max-packsize-tolerate-percent=[Set maximum tolerated packsize in percent of the targeted packsize A value of \`0\` means packs larger than the targeted packsize are always tolerated. Default if not set\: larger packfiles are always tolerated]:PERCENT: ' \ +'--set-extra-verify=[Do an extra verification by decompressing/decrypting all data before uploading to the repository. Default\: true]:SET_EXTRA_VERIFY:(true false)' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -734,6 +823,7 @@ _arguments "${_arguments_options[@]}" \ '--with-created[Add '\''created'\'' date in public key information]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -742,20 +832,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (key) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -765,6 +856,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -781,8 +873,10 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-key-command-$line[1]:" case $line[1] in (add) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +'--new-password=[New password]:NEW_PASSWORD: ' \ '--new-password-file=[File from which to read the new password]:NEW_PASSWORD_FILE:_files' \ +'*--new-password-command=[Command to get the new password from]:NEW_PASSWORD_COMMAND: ' \ '--hostname=[Set '\''hostname'\'' in public key information]:HOSTNAME: ' \ '--username=[Set '\''username'\'' in public key information]:USERNAME: ' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ @@ -790,14 +884,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -808,6 +903,7 @@ _arguments "${_arguments_options[@]}" \ '--with-created[Add '\''created'\'' date in public key information]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -816,7 +912,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__key__help_commands" \ "*::: :->help" \ && ret=0 @@ -828,11 +924,11 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-key-help-command-$line[1]:" case $line[1] in (add) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -844,20 +940,21 @@ esac esac ;; (list) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -867,6 +964,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -876,7 +974,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (ls) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*--glob=[Glob pattern to exclude/include (can be specified multiple times)]:GLOB: ' \ '*--iglob=[Same as --glob pattern but ignores the casing of filenames]:GLOB: ' \ '*--glob-file=[Read glob patterns to exclude/include from this file (can be specified multiple times)]:FILE: ' \ @@ -886,14 +984,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -905,9 +1004,11 @@ _arguments "${_arguments_options[@]}" \ '--summary[show summary]' \ '-l[show long listing]' \ '--long[show long listing]' \ +'--numeric-uid-gid[show uid/gid instead of user/group]' \ '--recursive[recursively list the dir]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -917,7 +1018,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (merge) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--label=[Label snapshot with given label]:LABEL: ' \ '*--tag=[Tags to add to snapshot (can be specified multiple times)]:TAG[,TAG,..]: ' \ '--description=[Add description to snapshot]:DESCRIPTION: ' \ @@ -931,14 +1032,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -951,6 +1053,7 @@ _arguments "${_arguments_options[@]}" \ '(--delete-after)--delete-never[Mark snapshot as uneraseable]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -960,7 +1063,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (snapshots) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '-g+[Group snapshots by any combination of host,label,paths,tags]:CRITERION: ' \ '--group-by=[Group snapshots by any combination of host,label,paths,tags]:CRITERION: ' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ @@ -968,14 +1071,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -986,8 +1090,11 @@ _arguments "${_arguments_options[@]}" \ '--long[Show detailed information about snapshots]' \ '(--long)--json[Show snapshots in json format]' \ '(--long --json)--all[Show all snapshots instead of summarizing identical follow-up snapshots]' \ +'-i[Run in interactive UI mode]' \ +'--interactive[Run in interactive UI mode]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -997,20 +1104,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (show-config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1020,6 +1128,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1028,20 +1137,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (self-update) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1052,6 +1162,7 @@ _arguments "${_arguments_options[@]}" \ '(-n --dry-run)--force[Do not ask before processing the self-update]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1060,7 +1171,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (prune) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--max-repack=[Define maximum data to repack in % of reposize or as size (e.g. '\''5b'\'', '\''2 kB'\'', '\''3M'\'', '\''4TiB'\'') or '\''unlimited'\'']:LIMIT: ' \ '--max-unused=[Tolerate limit of unused data in % of reposize after pruning or as size (e.g. '\''5b'\'', '\''2 kB'\'', '\''3M'\'', '\''4TiB'\'') or '\''unlimited'\'']:LIMIT: ' \ '--keep-pack=[Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created packs won'\''t be repacked or marked for deletion within this prune run]:DURATION: ' \ @@ -1071,14 +1182,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1087,12 +1199,14 @@ _arguments "${_arguments_options[@]}" \ '*--filter-tags=[Tag list to filter (can be specified multiple times)]:TAG[,TAG,..]: ' \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '--instant-delete[Delete files immediately instead of marking them. This also removes all files already marked for deletion]' \ +'--early-delete-index[Delete index files early. This allows to run prune if there is few or no space left]' \ '--fast-repack[Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting]' \ '(--fast-repack)--repack-uncompressed[Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. Implies --max-unused=0]' \ '--repack-all[Repack all packs. Implies --max-unused=0]' \ '--no-resize[Do not repack packs which only needs to be resized]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1101,7 +1215,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (restore) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*--glob=[Glob pattern to exclude/include (can be specified multiple times)]:GLOB: ' \ '*--iglob=[Same as --glob pattern but ignores the casing of filenames]:GLOB: ' \ '*--glob-file=[Read glob patterns to exclude/include from this file (can be specified multiple times)]:FILE: ' \ @@ -1116,14 +1230,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '--delete[Remove all files/dirs in destination which are not contained in snapshot]' \ @@ -1133,6 +1248,7 @@ _arguments "${_arguments_options[@]}" \ '--recursive[recursively list the dir]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1143,20 +1259,21 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (repair) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1166,6 +1283,7 @@ _arguments "${_arguments_options[@]}" \ '--filter-fn=[Function to filter snapshots]:FUNC: ' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1182,20 +1300,21 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-repair-command-$line[1]:" case $line[1] in (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1206,6 +1325,7 @@ _arguments "${_arguments_options[@]}" \ '--read-all[Read all data packs, i.e. completely re-create the index]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1214,7 +1334,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (snapshots) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '--suffix=[Append this suffix to repaired directory or file name]:SUFFIX: ' \ '*--tag=[Tag list to set on repaired snapshots (can be specified multiple times)]:TAG[,TAG,..]: ' \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ @@ -1222,14 +1342,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1240,6 +1361,7 @@ _arguments "${_arguments_options[@]}" \ '--delete[Also remove defect snapshots]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1249,7 +1371,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__repair__help_commands" \ "*::: :->help" \ && ret=0 @@ -1261,15 +1383,15 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-repair-help-command-$line[1]:" case $line[1] in (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (snapshots) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -1281,20 +1403,21 @@ esac esac ;; (repoinfo) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1307,6 +1430,7 @@ _arguments "${_arguments_options[@]}" \ '--json[Show infos in json format]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1315,7 +1439,7 @@ _arguments "${_arguments_options[@]}" \ && ret=0 ;; (tag) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ '(--remove)*--add=[Tags to add (can be specified multiple times)]:TAG[,TAG,..]: ' \ '*--remove=[Tags to remove (can be specified multiple times)]:TAG[,TAG,..]: ' \ '(--remove)*--set=[Tag list to set (can be specified multiple times)]:TAG[,TAG,..]: ' \ @@ -1325,14 +1449,15 @@ _arguments "${_arguments_options[@]}" \ '--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ '--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ '(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ -'-r+[Repository to use]:REPOSITORY: ' \ -'--repository=[Repository to use]:REPOSITORY: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ '--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ '--password=[Password of the repository]:PASSWORD: ' \ '(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ '(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ '(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ -'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ '(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ '--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ '*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ @@ -1344,6 +1469,7 @@ _arguments "${_arguments_options[@]}" \ '(--set-delete-after)--set-delete-never[Mark snapshot as uneraseable]' \ '-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ '--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ '--no-progress[Don'\''t show any progress bar]' \ '--no-cache[Don'\''t use a cache]' \ '--warm-up[Warm up needed data pack files by only requesting them without processing]' \ @@ -1352,8 +1478,47 @@ _arguments "${_arguments_options[@]}" \ '*::ids -- Snapshots to change tags. If none is given, use filter to filter from all snapshots:' \ && ret=0 ;; +(webdav) +_arguments "${_arguments_options[@]}" : \ +'--address=[Address to bind the webdav server to. \[default\: "localhost\:8000"\]]:ADDRESS: ' \ +'--path-template=[The path template to use for snapshots. {id}, {id_long}, {time}, {username}, {hostname}, {label}, {tags}, {backup_start}, {backup_end} are replaced. \[default\: "\[{hostname}\]/\[{label}\]/{time}"\]]:PATH_TEMPLATE: ' \ +'--time-template=[The time template to use to display times in the path template. See https\://docs.rs/chrono/latest/chrono/format/strftime/index.html for format options. \[default\: "%Y-%m-%d_%H-%M-%S"\]]:TIME_TEMPLATE: ' \ +'--file-access=[How to handle access to files. \[default\: "forbidden" for hot/cold repositories, else "read"\]]:FILE_ACCESS: ' \ +'*-P+[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ +'*--use-profile=[Config profile to use. This parses the file \`.toml\` in the config directory. \[default\: "rustic"\]]:PROFILE: ' \ +'--log-level=[Use this log level \[default\: info\]]:LOG_LEVEL: ' \ +'--log-file=[Write log messages to the given file instead of printing them]:LOGFILE:_files' \ +'(--no-progress)--progress-interval=[Interval to update progress bars]:DURATION: ' \ +'-r+[Repository to use]:REPOSITORY:_files -/' \ +'--repository=[Repository to use]:REPOSITORY:_files -/' \ +'--repo=[Repository to use]:REPOSITORY:_files -/' \ +'--repo-hot=[Repository to use as hot storage]:REPO_HOT: ' \ +'--password=[Password of the repository]:PASSWORD: ' \ +'(--password)-p+[File to read the password from]:PASSWORD_FILE:_files' \ +'(--password)--password-file=[File to read the password from]:PASSWORD_FILE:_files' \ +'(--password -p --password-file)--password-command=[Command to read the password from. Password is read from stdout]:PASSWORD_COMMAND: ' \ +'(--no-cache)--cache-dir=[Use this dir as cache dir instead of the standard cache dir]:CACHE_DIR:_files -/' \ +'(--warm-up)--warm-up-command=[Warm up needed data pack files by running the command with %id replaced by pack id]:WARM_UP_COMMAND: ' \ +'--warm-up-wait=[Duration (e.g. 10m) to wait after warm up]:DURATION: ' \ +'*--filter-host=[Hostname to filter (can be specified multiple times)]:HOSTNAME: ' \ +'*--filter-label=[Label to filter (can be specified multiple times)]:LABEL: ' \ +'*--filter-paths=[Path list to filter (can be specified multiple times)]:PATH[,PATH,..]: ' \ +'*--filter-tags=[Tag list to filter (can be specified multiple times)]:TAG[,TAG,..]: ' \ +'--filter-fn=[Function to filter snapshots]:FUNC: ' \ +'--symlinks[Use symlinks. This may not be supported by all WebDAV clients]' \ +'-n[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--dry-run[Only show what would be done without modifying anything. Does not affect read-only commands]' \ +'--check-index[Check if index matches pack files and read pack headers if neccessary]' \ +'--no-progress[Don'\''t show any progress bar]' \ +'--no-cache[Don'\''t use a cache]' \ +'--warm-up[Warm up needed data pack files by only requesting them without processing]' \ +'-h[Print help (see more with '\''--help'\'')]' \ +'--help[Print help (see more with '\''--help'\'')]' \ +'::snapshot_path -- Specify directly which snapshot/path to serve:' \ +&& ret=0 +;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__help_commands" \ "*::: :->help" \ && ret=0 @@ -1365,11 +1530,11 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-help-command-$line[1]:" case $line[1] in (backup) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (cat) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__help__cat_commands" \ "*::: :->cat" \ && ret=0 @@ -1381,27 +1546,27 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-help-cat-command-$line[1]:" case $line[1] in (tree-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (data-blob) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (snapshot) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tree) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -1409,39 +1574,43 @@ _arguments "${_arguments_options[@]}" \ esac ;; (config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (completions) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (check) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (copy) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (diff) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (dump) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(find) +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (forget) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (init) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (key) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__help__key_commands" \ "*::: :->key" \ && ret=0 @@ -1453,7 +1622,7 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-help-key-command-$line[1]:" case $line[1] in (add) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -1461,39 +1630,39 @@ _arguments "${_arguments_options[@]}" \ esac ;; (list) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (ls) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (merge) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (snapshots) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (show-config) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (self-update) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (prune) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (restore) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (repair) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ ":: :_rustic__help__repair_commands" \ "*::: :->repair" \ && ret=0 @@ -1505,11 +1674,11 @@ _arguments "${_arguments_options[@]}" \ curcontext="${curcontext%:*:*}:rustic-help-repair-command-$line[1]:" case $line[1] in (index) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (snapshots) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -1517,15 +1686,19 @@ _arguments "${_arguments_options[@]}" \ esac ;; (repoinfo) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (tag) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ +&& ret=0 +;; +(webdav) +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; (help) -_arguments "${_arguments_options[@]}" \ +_arguments "${_arguments_options[@]}" : \ && ret=0 ;; esac @@ -1548,6 +1721,7 @@ _rustic_commands() { 'copy:Copy snapshots to other repositories. Note\: The target repositories must be given in the config file!' \ 'diff:Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' \ 'dump:dump the contents of a file in a snapshot to stdout' \ +'find:Find in given snapshots' \ 'forget:Remove snapshots from the repository' \ 'init:Initialize a new repository' \ 'key:Manage keys' \ @@ -1562,35 +1736,16 @@ _rustic_commands() { 'repair:Repair a snapshot/path' \ 'repoinfo:Show general information about the repository' \ 'tag:Change tags of snapshots' \ +'webdav:Start a webdav server which allows to access the repository' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'rustic commands' commands "$@" } -(( $+functions[_rustic__help__key__add_commands] )) || -_rustic__help__key__add_commands() { - local commands; commands=() - _describe -t commands 'rustic help key add commands' commands "$@" -} -(( $+functions[_rustic__key__add_commands] )) || -_rustic__key__add_commands() { - local commands; commands=() - _describe -t commands 'rustic key add commands' commands "$@" -} -(( $+functions[_rustic__key__help__add_commands] )) || -_rustic__key__help__add_commands() { - local commands; commands=() - _describe -t commands 'rustic key help add commands' commands "$@" -} (( $+functions[_rustic__backup_commands] )) || _rustic__backup_commands() { local commands; commands=() _describe -t commands 'rustic backup commands' commands "$@" } -(( $+functions[_rustic__help__backup_commands] )) || -_rustic__help__backup_commands() { - local commands; commands=() - _describe -t commands 'rustic help backup commands' commands "$@" -} (( $+functions[_rustic__cat_commands] )) || _rustic__cat_commands() { local commands; commands=( @@ -1604,8 +1759,18 @@ _rustic__cat_commands() { ) _describe -t commands 'rustic cat commands' commands "$@" } -(( $+functions[_rustic__help__cat_commands] )) || -_rustic__help__cat_commands() { +(( $+functions[_rustic__cat__config_commands] )) || +_rustic__cat__config_commands() { + local commands; commands=() + _describe -t commands 'rustic cat config commands' commands "$@" +} +(( $+functions[_rustic__cat__data-blob_commands] )) || +_rustic__cat__data-blob_commands() { + local commands; commands=() + _describe -t commands 'rustic cat data-blob commands' commands "$@" +} +(( $+functions[_rustic__cat__help_commands] )) || +_rustic__cat__help_commands() { local commands; commands=( 'tree-blob:Display a tree blob' \ 'data-blob:Display a data blob' \ @@ -1613,127 +1778,105 @@ _rustic__help__cat_commands() { 'index:Display an index file' \ 'snapshot:Display a snapshot file' \ 'tree:Display a tree within a snapshot' \ +'help:Print this message or the help of the given subcommand(s)' \ ) - _describe -t commands 'rustic help cat commands' commands "$@" + _describe -t commands 'rustic cat help commands' commands "$@" } -(( $+functions[_rustic__check_commands] )) || -_rustic__check_commands() { +(( $+functions[_rustic__cat__help__config_commands] )) || +_rustic__cat__help__config_commands() { local commands; commands=() - _describe -t commands 'rustic check commands' commands "$@" + _describe -t commands 'rustic cat help config commands' commands "$@" } -(( $+functions[_rustic__help__check_commands] )) || -_rustic__help__check_commands() { +(( $+functions[_rustic__cat__help__data-blob_commands] )) || +_rustic__cat__help__data-blob_commands() { local commands; commands=() - _describe -t commands 'rustic help check commands' commands "$@" + _describe -t commands 'rustic cat help data-blob commands' commands "$@" } -(( $+functions[_rustic__completions_commands] )) || -_rustic__completions_commands() { +(( $+functions[_rustic__cat__help__help_commands] )) || +_rustic__cat__help__help_commands() { local commands; commands=() - _describe -t commands 'rustic completions commands' commands "$@" + _describe -t commands 'rustic cat help help commands' commands "$@" } -(( $+functions[_rustic__help__completions_commands] )) || -_rustic__help__completions_commands() { +(( $+functions[_rustic__cat__help__index_commands] )) || +_rustic__cat__help__index_commands() { local commands; commands=() - _describe -t commands 'rustic help completions commands' commands "$@" + _describe -t commands 'rustic cat help index commands' commands "$@" } -(( $+functions[_rustic__cat__config_commands] )) || -_rustic__cat__config_commands() { +(( $+functions[_rustic__cat__help__snapshot_commands] )) || +_rustic__cat__help__snapshot_commands() { local commands; commands=() - _describe -t commands 'rustic cat config commands' commands "$@" + _describe -t commands 'rustic cat help snapshot commands' commands "$@" } -(( $+functions[_rustic__cat__help__config_commands] )) || -_rustic__cat__help__config_commands() { +(( $+functions[_rustic__cat__help__tree_commands] )) || +_rustic__cat__help__tree_commands() { local commands; commands=() - _describe -t commands 'rustic cat help config commands' commands "$@" + _describe -t commands 'rustic cat help tree commands' commands "$@" } -(( $+functions[_rustic__config_commands] )) || -_rustic__config_commands() { +(( $+functions[_rustic__cat__help__tree-blob_commands] )) || +_rustic__cat__help__tree-blob_commands() { local commands; commands=() - _describe -t commands 'rustic config commands' commands "$@" + _describe -t commands 'rustic cat help tree-blob commands' commands "$@" } -(( $+functions[_rustic__help__cat__config_commands] )) || -_rustic__help__cat__config_commands() { +(( $+functions[_rustic__cat__index_commands] )) || +_rustic__cat__index_commands() { local commands; commands=() - _describe -t commands 'rustic help cat config commands' commands "$@" + _describe -t commands 'rustic cat index commands' commands "$@" } -(( $+functions[_rustic__help__config_commands] )) || -_rustic__help__config_commands() { +(( $+functions[_rustic__cat__snapshot_commands] )) || +_rustic__cat__snapshot_commands() { local commands; commands=() - _describe -t commands 'rustic help config commands' commands "$@" + _describe -t commands 'rustic cat snapshot commands' commands "$@" } -(( $+functions[_rustic__copy_commands] )) || -_rustic__copy_commands() { +(( $+functions[_rustic__cat__tree_commands] )) || +_rustic__cat__tree_commands() { local commands; commands=() - _describe -t commands 'rustic copy commands' commands "$@" + _describe -t commands 'rustic cat tree commands' commands "$@" } -(( $+functions[_rustic__help__copy_commands] )) || -_rustic__help__copy_commands() { +(( $+functions[_rustic__cat__tree-blob_commands] )) || +_rustic__cat__tree-blob_commands() { local commands; commands=() - _describe -t commands 'rustic help copy commands' commands "$@" + _describe -t commands 'rustic cat tree-blob commands' commands "$@" } -(( $+functions[_rustic__cat__data-blob_commands] )) || -_rustic__cat__data-blob_commands() { +(( $+functions[_rustic__check_commands] )) || +_rustic__check_commands() { local commands; commands=() - _describe -t commands 'rustic cat data-blob commands' commands "$@" + _describe -t commands 'rustic check commands' commands "$@" } -(( $+functions[_rustic__cat__help__data-blob_commands] )) || -_rustic__cat__help__data-blob_commands() { +(( $+functions[_rustic__completions_commands] )) || +_rustic__completions_commands() { local commands; commands=() - _describe -t commands 'rustic cat help data-blob commands' commands "$@" + _describe -t commands 'rustic completions commands' commands "$@" } -(( $+functions[_rustic__help__cat__data-blob_commands] )) || -_rustic__help__cat__data-blob_commands() { +(( $+functions[_rustic__config_commands] )) || +_rustic__config_commands() { local commands; commands=() - _describe -t commands 'rustic help cat data-blob commands' commands "$@" + _describe -t commands 'rustic config commands' commands "$@" +} +(( $+functions[_rustic__copy_commands] )) || +_rustic__copy_commands() { + local commands; commands=() + _describe -t commands 'rustic copy commands' commands "$@" } (( $+functions[_rustic__diff_commands] )) || _rustic__diff_commands() { local commands; commands=() _describe -t commands 'rustic diff commands' commands "$@" } -(( $+functions[_rustic__help__diff_commands] )) || -_rustic__help__diff_commands() { - local commands; commands=() - _describe -t commands 'rustic help diff commands' commands "$@" -} (( $+functions[_rustic__dump_commands] )) || _rustic__dump_commands() { local commands; commands=() _describe -t commands 'rustic dump commands' commands "$@" } -(( $+functions[_rustic__help__dump_commands] )) || -_rustic__help__dump_commands() { +(( $+functions[_rustic__find_commands] )) || +_rustic__find_commands() { local commands; commands=() - _describe -t commands 'rustic help dump commands' commands "$@" + _describe -t commands 'rustic find commands' commands "$@" } (( $+functions[_rustic__forget_commands] )) || _rustic__forget_commands() { local commands; commands=() _describe -t commands 'rustic forget commands' commands "$@" } -(( $+functions[_rustic__help__forget_commands] )) || -_rustic__help__forget_commands() { - local commands; commands=() - _describe -t commands 'rustic help forget commands' commands "$@" -} -(( $+functions[_rustic__cat__help_commands] )) || -_rustic__cat__help_commands() { - local commands; commands=( -'tree-blob:Display a tree blob' \ -'data-blob:Display a data blob' \ -'config:Display the config file' \ -'index:Display an index file' \ -'snapshot:Display a snapshot file' \ -'tree:Display a tree within a snapshot' \ -'help:Print this message or the help of the given subcommand(s)' \ - ) - _describe -t commands 'rustic cat help commands' commands "$@" -} -(( $+functions[_rustic__cat__help__help_commands] )) || -_rustic__cat__help__help_commands() { - local commands; commands=() - _describe -t commands 'rustic cat help help commands' commands "$@" -} (( $+functions[_rustic__help_commands] )) || _rustic__help_commands() { local commands; commands=( @@ -1745,6 +1888,7 @@ _rustic__help_commands() { 'copy:Copy snapshots to other repositories. Note\: The target repositories must be given in the config file!' \ 'diff:Compare two snapshots/paths Note that the exclude options only apply for comparison with a local path' \ 'dump:dump the contents of a file in a snapshot to stdout' \ +'find:Find in given snapshots' \ 'forget:Remove snapshots from the repository' \ 'init:Initialize a new repository' \ 'key:Manage keys' \ @@ -1759,82 +1903,108 @@ _rustic__help_commands() { 'repair:Repair a snapshot/path' \ 'repoinfo:Show general information about the repository' \ 'tag:Change tags of snapshots' \ +'webdav:Start a webdav server which allows to access the repository' \ 'help:Print this message or the help of the given subcommand(s)' \ ) _describe -t commands 'rustic help commands' commands "$@" } -(( $+functions[_rustic__help__help_commands] )) || -_rustic__help__help_commands() { +(( $+functions[_rustic__help__backup_commands] )) || +_rustic__help__backup_commands() { local commands; commands=() - _describe -t commands 'rustic help help commands' commands "$@" + _describe -t commands 'rustic help backup commands' commands "$@" } -(( $+functions[_rustic__key__help_commands] )) || -_rustic__key__help_commands() { +(( $+functions[_rustic__help__cat_commands] )) || +_rustic__help__cat_commands() { local commands; commands=( -'add:Add a new key to the repository' \ -'help:Print this message or the help of the given subcommand(s)' \ +'tree-blob:Display a tree blob' \ +'data-blob:Display a data blob' \ +'config:Display the config file' \ +'index:Display an index file' \ +'snapshot:Display a snapshot file' \ +'tree:Display a tree within a snapshot' \ ) - _describe -t commands 'rustic key help commands' commands "$@" + _describe -t commands 'rustic help cat commands' commands "$@" } -(( $+functions[_rustic__key__help__help_commands] )) || -_rustic__key__help__help_commands() { +(( $+functions[_rustic__help__cat__config_commands] )) || +_rustic__help__cat__config_commands() { local commands; commands=() - _describe -t commands 'rustic key help help commands' commands "$@" -} -(( $+functions[_rustic__repair__help_commands] )) || -_rustic__repair__help_commands() { - local commands; commands=( -'index:Repair the repository index' \ -'snapshots:Repair snapshots' \ -'help:Print this message or the help of the given subcommand(s)' \ - ) - _describe -t commands 'rustic repair help commands' commands "$@" + _describe -t commands 'rustic help cat config commands' commands "$@" } -(( $+functions[_rustic__repair__help__help_commands] )) || -_rustic__repair__help__help_commands() { +(( $+functions[_rustic__help__cat__data-blob_commands] )) || +_rustic__help__cat__data-blob_commands() { local commands; commands=() - _describe -t commands 'rustic repair help help commands' commands "$@" + _describe -t commands 'rustic help cat data-blob commands' commands "$@" } -(( $+functions[_rustic__cat__help__index_commands] )) || -_rustic__cat__help__index_commands() { +(( $+functions[_rustic__help__cat__index_commands] )) || +_rustic__help__cat__index_commands() { local commands; commands=() - _describe -t commands 'rustic cat help index commands' commands "$@" + _describe -t commands 'rustic help cat index commands' commands "$@" } -(( $+functions[_rustic__cat__index_commands] )) || -_rustic__cat__index_commands() { +(( $+functions[_rustic__help__cat__snapshot_commands] )) || +_rustic__help__cat__snapshot_commands() { local commands; commands=() - _describe -t commands 'rustic cat index commands' commands "$@" + _describe -t commands 'rustic help cat snapshot commands' commands "$@" } -(( $+functions[_rustic__help__cat__index_commands] )) || -_rustic__help__cat__index_commands() { +(( $+functions[_rustic__help__cat__tree_commands] )) || +_rustic__help__cat__tree_commands() { local commands; commands=() - _describe -t commands 'rustic help cat index commands' commands "$@" + _describe -t commands 'rustic help cat tree commands' commands "$@" } -(( $+functions[_rustic__help__repair__index_commands] )) || -_rustic__help__repair__index_commands() { +(( $+functions[_rustic__help__cat__tree-blob_commands] )) || +_rustic__help__cat__tree-blob_commands() { local commands; commands=() - _describe -t commands 'rustic help repair index commands' commands "$@" + _describe -t commands 'rustic help cat tree-blob commands' commands "$@" } -(( $+functions[_rustic__repair__help__index_commands] )) || -_rustic__repair__help__index_commands() { +(( $+functions[_rustic__help__check_commands] )) || +_rustic__help__check_commands() { local commands; commands=() - _describe -t commands 'rustic repair help index commands' commands "$@" + _describe -t commands 'rustic help check commands' commands "$@" } -(( $+functions[_rustic__repair__index_commands] )) || -_rustic__repair__index_commands() { +(( $+functions[_rustic__help__completions_commands] )) || +_rustic__help__completions_commands() { local commands; commands=() - _describe -t commands 'rustic repair index commands' commands "$@" + _describe -t commands 'rustic help completions commands' commands "$@" +} +(( $+functions[_rustic__help__config_commands] )) || +_rustic__help__config_commands() { + local commands; commands=() + _describe -t commands 'rustic help config commands' commands "$@" +} +(( $+functions[_rustic__help__copy_commands] )) || +_rustic__help__copy_commands() { + local commands; commands=() + _describe -t commands 'rustic help copy commands' commands "$@" +} +(( $+functions[_rustic__help__diff_commands] )) || +_rustic__help__diff_commands() { + local commands; commands=() + _describe -t commands 'rustic help diff commands' commands "$@" +} +(( $+functions[_rustic__help__dump_commands] )) || +_rustic__help__dump_commands() { + local commands; commands=() + _describe -t commands 'rustic help dump commands' commands "$@" +} +(( $+functions[_rustic__help__find_commands] )) || +_rustic__help__find_commands() { + local commands; commands=() + _describe -t commands 'rustic help find commands' commands "$@" +} +(( $+functions[_rustic__help__forget_commands] )) || +_rustic__help__forget_commands() { + local commands; commands=() + _describe -t commands 'rustic help forget commands' commands "$@" +} +(( $+functions[_rustic__help__help_commands] )) || +_rustic__help__help_commands() { + local commands; commands=() + _describe -t commands 'rustic help help commands' commands "$@" } (( $+functions[_rustic__help__init_commands] )) || _rustic__help__init_commands() { local commands; commands=() _describe -t commands 'rustic help init commands' commands "$@" } -(( $+functions[_rustic__init_commands] )) || -_rustic__init_commands() { - local commands; commands=() - _describe -t commands 'rustic init commands' commands "$@" -} (( $+functions[_rustic__help__key_commands] )) || _rustic__help__key_commands() { local commands; commands=( @@ -1842,54 +2012,31 @@ _rustic__help__key_commands() { ) _describe -t commands 'rustic help key commands' commands "$@" } -(( $+functions[_rustic__key_commands] )) || -_rustic__key_commands() { - local commands; commands=( -'add:Add a new key to the repository' \ -'help:Print this message or the help of the given subcommand(s)' \ - ) - _describe -t commands 'rustic key commands' commands "$@" +(( $+functions[_rustic__help__key__add_commands] )) || +_rustic__help__key__add_commands() { + local commands; commands=() + _describe -t commands 'rustic help key add commands' commands "$@" } (( $+functions[_rustic__help__list_commands] )) || _rustic__help__list_commands() { local commands; commands=() _describe -t commands 'rustic help list commands' commands "$@" } -(( $+functions[_rustic__list_commands] )) || -_rustic__list_commands() { - local commands; commands=() - _describe -t commands 'rustic list commands' commands "$@" -} (( $+functions[_rustic__help__ls_commands] )) || _rustic__help__ls_commands() { local commands; commands=() _describe -t commands 'rustic help ls commands' commands "$@" } -(( $+functions[_rustic__ls_commands] )) || -_rustic__ls_commands() { - local commands; commands=() - _describe -t commands 'rustic ls commands' commands "$@" -} (( $+functions[_rustic__help__merge_commands] )) || _rustic__help__merge_commands() { local commands; commands=() _describe -t commands 'rustic help merge commands' commands "$@" } -(( $+functions[_rustic__merge_commands] )) || -_rustic__merge_commands() { - local commands; commands=() - _describe -t commands 'rustic merge commands' commands "$@" -} (( $+functions[_rustic__help__prune_commands] )) || _rustic__help__prune_commands() { local commands; commands=() _describe -t commands 'rustic help prune commands' commands "$@" } -(( $+functions[_rustic__prune_commands] )) || -_rustic__prune_commands() { - local commands; commands=() - _describe -t commands 'rustic prune commands' commands "$@" -} (( $+functions[_rustic__help__repair_commands] )) || _rustic__help__repair_commands() { local commands; commands=( @@ -1898,134 +2045,184 @@ _rustic__help__repair_commands() { ) _describe -t commands 'rustic help repair commands' commands "$@" } -(( $+functions[_rustic__repair_commands] )) || -_rustic__repair_commands() { - local commands; commands=( -'index:Repair the repository index' \ -'snapshots:Repair snapshots' \ -'help:Print this message or the help of the given subcommand(s)' \ - ) - _describe -t commands 'rustic repair commands' commands "$@" +(( $+functions[_rustic__help__repair__index_commands] )) || +_rustic__help__repair__index_commands() { + local commands; commands=() + _describe -t commands 'rustic help repair index commands' commands "$@" +} +(( $+functions[_rustic__help__repair__snapshots_commands] )) || +_rustic__help__repair__snapshots_commands() { + local commands; commands=() + _describe -t commands 'rustic help repair snapshots commands' commands "$@" } (( $+functions[_rustic__help__repoinfo_commands] )) || _rustic__help__repoinfo_commands() { local commands; commands=() _describe -t commands 'rustic help repoinfo commands' commands "$@" } -(( $+functions[_rustic__repoinfo_commands] )) || -_rustic__repoinfo_commands() { - local commands; commands=() - _describe -t commands 'rustic repoinfo commands' commands "$@" -} (( $+functions[_rustic__help__restore_commands] )) || _rustic__help__restore_commands() { local commands; commands=() _describe -t commands 'rustic help restore commands' commands "$@" } -(( $+functions[_rustic__restore_commands] )) || -_rustic__restore_commands() { - local commands; commands=() - _describe -t commands 'rustic restore commands' commands "$@" -} (( $+functions[_rustic__help__self-update_commands] )) || _rustic__help__self-update_commands() { local commands; commands=() _describe -t commands 'rustic help self-update commands' commands "$@" } -(( $+functions[_rustic__self-update_commands] )) || -_rustic__self-update_commands() { - local commands; commands=() - _describe -t commands 'rustic self-update commands' commands "$@" -} (( $+functions[_rustic__help__show-config_commands] )) || _rustic__help__show-config_commands() { local commands; commands=() _describe -t commands 'rustic help show-config commands' commands "$@" } -(( $+functions[_rustic__show-config_commands] )) || -_rustic__show-config_commands() { +(( $+functions[_rustic__help__snapshots_commands] )) || +_rustic__help__snapshots_commands() { local commands; commands=() - _describe -t commands 'rustic show-config commands' commands "$@" + _describe -t commands 'rustic help snapshots commands' commands "$@" } -(( $+functions[_rustic__cat__help__snapshot_commands] )) || -_rustic__cat__help__snapshot_commands() { +(( $+functions[_rustic__help__tag_commands] )) || +_rustic__help__tag_commands() { local commands; commands=() - _describe -t commands 'rustic cat help snapshot commands' commands "$@" + _describe -t commands 'rustic help tag commands' commands "$@" } -(( $+functions[_rustic__cat__snapshot_commands] )) || -_rustic__cat__snapshot_commands() { +(( $+functions[_rustic__help__webdav_commands] )) || +_rustic__help__webdav_commands() { local commands; commands=() - _describe -t commands 'rustic cat snapshot commands' commands "$@" + _describe -t commands 'rustic help webdav commands' commands "$@" } -(( $+functions[_rustic__help__cat__snapshot_commands] )) || -_rustic__help__cat__snapshot_commands() { +(( $+functions[_rustic__init_commands] )) || +_rustic__init_commands() { local commands; commands=() - _describe -t commands 'rustic help cat snapshot commands' commands "$@" + _describe -t commands 'rustic init commands' commands "$@" } -(( $+functions[_rustic__help__repair__snapshots_commands] )) || -_rustic__help__repair__snapshots_commands() { +(( $+functions[_rustic__key_commands] )) || +_rustic__key_commands() { + local commands; commands=( +'add:Add a new key to the repository' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'rustic key commands' commands "$@" +} +(( $+functions[_rustic__key__add_commands] )) || +_rustic__key__add_commands() { local commands; commands=() - _describe -t commands 'rustic help repair snapshots commands' commands "$@" + _describe -t commands 'rustic key add commands' commands "$@" } -(( $+functions[_rustic__help__snapshots_commands] )) || -_rustic__help__snapshots_commands() { +(( $+functions[_rustic__key__help_commands] )) || +_rustic__key__help_commands() { + local commands; commands=( +'add:Add a new key to the repository' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'rustic key help commands' commands "$@" +} +(( $+functions[_rustic__key__help__add_commands] )) || +_rustic__key__help__add_commands() { local commands; commands=() - _describe -t commands 'rustic help snapshots commands' commands "$@" + _describe -t commands 'rustic key help add commands' commands "$@" +} +(( $+functions[_rustic__key__help__help_commands] )) || +_rustic__key__help__help_commands() { + local commands; commands=() + _describe -t commands 'rustic key help help commands' commands "$@" +} +(( $+functions[_rustic__list_commands] )) || +_rustic__list_commands() { + local commands; commands=() + _describe -t commands 'rustic list commands' commands "$@" +} +(( $+functions[_rustic__ls_commands] )) || +_rustic__ls_commands() { + local commands; commands=() + _describe -t commands 'rustic ls commands' commands "$@" +} +(( $+functions[_rustic__merge_commands] )) || +_rustic__merge_commands() { + local commands; commands=() + _describe -t commands 'rustic merge commands' commands "$@" +} +(( $+functions[_rustic__prune_commands] )) || +_rustic__prune_commands() { + local commands; commands=() + _describe -t commands 'rustic prune commands' commands "$@" +} +(( $+functions[_rustic__repair_commands] )) || +_rustic__repair_commands() { + local commands; commands=( +'index:Repair the repository index' \ +'snapshots:Repair snapshots' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'rustic repair commands' commands "$@" +} +(( $+functions[_rustic__repair__help_commands] )) || +_rustic__repair__help_commands() { + local commands; commands=( +'index:Repair the repository index' \ +'snapshots:Repair snapshots' \ +'help:Print this message or the help of the given subcommand(s)' \ + ) + _describe -t commands 'rustic repair help commands' commands "$@" +} +(( $+functions[_rustic__repair__help__help_commands] )) || +_rustic__repair__help__help_commands() { + local commands; commands=() + _describe -t commands 'rustic repair help help commands' commands "$@" +} +(( $+functions[_rustic__repair__help__index_commands] )) || +_rustic__repair__help__index_commands() { + local commands; commands=() + _describe -t commands 'rustic repair help index commands' commands "$@" } (( $+functions[_rustic__repair__help__snapshots_commands] )) || _rustic__repair__help__snapshots_commands() { local commands; commands=() _describe -t commands 'rustic repair help snapshots commands' commands "$@" } +(( $+functions[_rustic__repair__index_commands] )) || +_rustic__repair__index_commands() { + local commands; commands=() + _describe -t commands 'rustic repair index commands' commands "$@" +} (( $+functions[_rustic__repair__snapshots_commands] )) || _rustic__repair__snapshots_commands() { local commands; commands=() _describe -t commands 'rustic repair snapshots commands' commands "$@" } -(( $+functions[_rustic__snapshots_commands] )) || -_rustic__snapshots_commands() { - local commands; commands=() - _describe -t commands 'rustic snapshots commands' commands "$@" -} -(( $+functions[_rustic__help__tag_commands] )) || -_rustic__help__tag_commands() { - local commands; commands=() - _describe -t commands 'rustic help tag commands' commands "$@" -} -(( $+functions[_rustic__tag_commands] )) || -_rustic__tag_commands() { +(( $+functions[_rustic__repoinfo_commands] )) || +_rustic__repoinfo_commands() { local commands; commands=() - _describe -t commands 'rustic tag commands' commands "$@" + _describe -t commands 'rustic repoinfo commands' commands "$@" } -(( $+functions[_rustic__cat__help__tree_commands] )) || -_rustic__cat__help__tree_commands() { +(( $+functions[_rustic__restore_commands] )) || +_rustic__restore_commands() { local commands; commands=() - _describe -t commands 'rustic cat help tree commands' commands "$@" + _describe -t commands 'rustic restore commands' commands "$@" } -(( $+functions[_rustic__cat__tree_commands] )) || -_rustic__cat__tree_commands() { +(( $+functions[_rustic__self-update_commands] )) || +_rustic__self-update_commands() { local commands; commands=() - _describe -t commands 'rustic cat tree commands' commands "$@" + _describe -t commands 'rustic self-update commands' commands "$@" } -(( $+functions[_rustic__help__cat__tree_commands] )) || -_rustic__help__cat__tree_commands() { +(( $+functions[_rustic__show-config_commands] )) || +_rustic__show-config_commands() { local commands; commands=() - _describe -t commands 'rustic help cat tree commands' commands "$@" + _describe -t commands 'rustic show-config commands' commands "$@" } -(( $+functions[_rustic__cat__help__tree-blob_commands] )) || -_rustic__cat__help__tree-blob_commands() { +(( $+functions[_rustic__snapshots_commands] )) || +_rustic__snapshots_commands() { local commands; commands=() - _describe -t commands 'rustic cat help tree-blob commands' commands "$@" + _describe -t commands 'rustic snapshots commands' commands "$@" } -(( $+functions[_rustic__cat__tree-blob_commands] )) || -_rustic__cat__tree-blob_commands() { +(( $+functions[_rustic__tag_commands] )) || +_rustic__tag_commands() { local commands; commands=() - _describe -t commands 'rustic cat tree-blob commands' commands "$@" + _describe -t commands 'rustic tag commands' commands "$@" } -(( $+functions[_rustic__help__cat__tree-blob_commands] )) || -_rustic__help__cat__tree-blob_commands() { +(( $+functions[_rustic__webdav_commands] )) || +_rustic__webdav_commands() { local commands; commands=() - _describe -t commands 'rustic help cat tree-blob commands' commands "$@" + _describe -t commands 'rustic webdav commands' commands "$@" } if [ "$funcstack[1]" = "_rustic" ]; then diff --git a/tests/completions.rs b/tests/completions.rs index f278df9c4..d2e15fcb2 100644 --- a/tests/completions.rs +++ b/tests/completions.rs @@ -13,10 +13,9 @@ use std::{ io::{Read, Write}, path::PathBuf, + sync::LazyLock, }; -use once_cell::sync::Lazy; - use abscissa_core::testing::prelude::*; use rustic_testing::{files_differ, get_temp_file, TestResult}; @@ -25,7 +24,7 @@ use rustic_testing::{files_differ, get_temp_file, TestResult}; /// the runner acquire a mutex when executing commands and inspecting /// exit statuses, serializing what would otherwise be multithreaded /// invocations as `cargo test` executes tests in parallel by default. -pub static LAZY_RUNNER: Lazy = Lazy::new(|| { +pub static LAZY_RUNNER: LazyLock = LazyLock::new(|| { let mut runner = CmdRunner::new(env!("CARGO_BIN_EXE_rustic")); runner.exclusive().capture_stdout(); runner diff --git a/tests/config.rs b/tests/config.rs index 0993067ea..1741c71ed 100644 --- a/tests/config.rs +++ b/tests/config.rs @@ -1,31 +1,17 @@ //! Configuration file tests -use log::LevelFilter; +use anyhow::Result; +use rstest::*; use rustic_rs::RusticConfig; -use std::{error::Error, fs, path::PathBuf, str::FromStr}; +use std::{fs, path::PathBuf}; -type Result = std::result::Result>; - -fn get_config_file_path() -> PathBuf { - ["config", "full.toml"].iter().collect() -} -/// Ensure `full.toml` parses as a valid config file -#[test] -fn parse_full_toml_example() -> Result<()> { - let output = std::process::Command::new("cargo") - .args(["locate-project", "--workspace", "--message-format", "plain"]) - .output()?; - let root = PathBuf::from_str(String::from_utf8(output.stdout)?.as_str())?; - let root_dir = root.parent().unwrap(); - let config_path = root_dir.join(get_config_file_path()); +/// Ensure all `configs` parse as a valid config files +#[rstest] +fn test_parse_rustic_configs_is_ok( + #[files("config/**/*.toml")] config_path: PathBuf, +) -> Result<()> { let toml_string = fs::read_to_string(config_path)?; - let config: RusticConfig = toml::from_str(&toml_string)?; - - assert_eq!( - LevelFilter::from_str(config.global.log_level.unwrap().as_str())?, - LevelFilter::Info - ); - assert!(!config.global.dry_run); + let _ = toml::from_str::(&toml_string)?; Ok(()) } diff --git a/tests/generated/.gitkeep b/tests/generated/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/tests/hooks-fixtures/backup_hooks_failure.toml b/tests/hooks-fixtures/backup_hooks_failure.toml new file mode 100644 index 000000000..cd30d6ea3 --- /dev/null +++ b/tests/hooks-fixtures/backup_hooks_failure.toml @@ -0,0 +1,12 @@ +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before > tests/generated/backup_hooks_failure.log'", + "false", + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/backup_hooks_failure.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/backup_hooks_failure.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/backup_hooks_failure.log'", +] diff --git a/tests/hooks-fixtures/backup_hooks_success.toml b/tests/hooks-fixtures/backup_hooks_success.toml new file mode 100644 index 000000000..8cee9a4af --- /dev/null +++ b/tests/hooks-fixtures/backup_hooks_success.toml @@ -0,0 +1,13 @@ +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before > tests/generated/backup_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running backup hooks after >> tests/generated/backup_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/backup_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/backup_hooks_success.log'", +] diff --git a/tests/hooks-fixtures/check_not_backup_hooks_success.toml b/tests/hooks-fixtures/check_not_backup_hooks_success.toml new file mode 100644 index 000000000..1a5cd5365 --- /dev/null +++ b/tests/hooks-fixtures/check_not_backup_hooks_success.toml @@ -0,0 +1,41 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/check_not_backup_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/check_not_backup_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/check_not_backup_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/check_not_backup_hooks_success.log'", +] + +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before >> tests/generated/check_not_backup_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/check_not_backup_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/check_not_backup_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/check_not_backup_hooks_success.log'", +] + +[backup.hooks] +run-before = [ + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/check_not_backup_hooks_success.log'", +] +run-after = [ + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/check_not_backup_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/check_not_backup_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/check_not_backup_hooks_success.log'", +] diff --git a/tests/hooks-fixtures/commands_hooks_access_success.tpl b/tests/hooks-fixtures/commands_hooks_access_success.tpl new file mode 100644 index 000000000..3afc70510 --- /dev/null +++ b/tests/hooks-fixtures/commands_hooks_access_success.tpl @@ -0,0 +1,41 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/${{filename}}.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/${{filename}}.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/${{filename}}.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/${{filename}}.log'", +] + +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before >> tests/generated/${{filename}}.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/${{filename}}.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/${{filename}}.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/${{filename}}.log'", +] + +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before >> tests/generated/${{filename}}.log'", +] +run-after = [ + "sh -c 'echo Running backup hooks after >> tests/generated/${{filename}}.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/${{filename}}.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/${{filename}}.log'", +] diff --git a/tests/hooks-fixtures/empty_hooks_success.toml b/tests/hooks-fixtures/empty_hooks_success.toml new file mode 100644 index 000000000..c64dfc74b --- /dev/null +++ b/tests/hooks-fixtures/empty_hooks_success.toml @@ -0,0 +1,17 @@ +[global.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[repository.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[backup.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] diff --git a/tests/hooks-fixtures/full_hooks_before_backup_failure.toml b/tests/hooks-fixtures/full_hooks_before_backup_failure.toml new file mode 100644 index 000000000..bdf12c364 --- /dev/null +++ b/tests/hooks-fixtures/full_hooks_before_backup_failure.toml @@ -0,0 +1,43 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/full_hooks_before_backup_failure.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/full_hooks_before_backup_failure.log'", +] + +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/full_hooks_before_backup_failure.log'", +] + +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before >> tests/generated/full_hooks_before_backup_failure.log'", + "false", + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-after = [ + "sh -c 'echo Running backup hooks after >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/full_hooks_before_backup_failure.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/full_hooks_before_backup_failure.log'", +] diff --git a/tests/hooks-fixtures/full_hooks_before_repo_failure.toml b/tests/hooks-fixtures/full_hooks_before_repo_failure.toml new file mode 100644 index 000000000..ba2e36a12 --- /dev/null +++ b/tests/hooks-fixtures/full_hooks_before_repo_failure.toml @@ -0,0 +1,43 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/full_hooks_before_repo_failure.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/full_hooks_before_repo_failure.log'", +] + +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before >> tests/generated/full_hooks_before_repo_failure.log'", + "false", + "sh -c 'echo MUST NOT SHOW UP >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/full_hooks_before_repo_failure.log'", +] + +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-after = [ + "sh -c 'echo Running backup hooks after >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/full_hooks_before_repo_failure.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/full_hooks_before_repo_failure.log'", +] diff --git a/tests/hooks-fixtures/full_hooks_success.toml b/tests/hooks-fixtures/full_hooks_success.toml new file mode 100644 index 000000000..8e51936e7 --- /dev/null +++ b/tests/hooks-fixtures/full_hooks_success.toml @@ -0,0 +1,41 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/full_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/full_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/full_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/full_hooks_success.log'", +] + +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before >> tests/generated/full_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/full_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/full_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/full_hooks_success.log'", +] + +[backup.hooks] +run-before = [ + "sh -c 'echo Running backup hooks before >> tests/generated/full_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running backup hooks after >> tests/generated/full_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running backup hooks failed >> tests/generated/full_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running backup hooks finally >> tests/generated/full_hooks_success.log'", +] diff --git a/tests/hooks-fixtures/global_hooks_success.toml b/tests/hooks-fixtures/global_hooks_success.toml new file mode 100644 index 000000000..0295c319e --- /dev/null +++ b/tests/hooks-fixtures/global_hooks_success.toml @@ -0,0 +1,13 @@ +[global.hooks] +run-before = [ + "sh -c 'echo Running global hooks before > tests/generated/global_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running global hooks after >> tests/generated/global_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running global hooks failed >> tests/generated/global_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running global hooks finally >> tests/generated/global_hooks_success.log'", +] diff --git a/tests/hooks-fixtures/repository_hooks_success.toml b/tests/hooks-fixtures/repository_hooks_success.toml new file mode 100644 index 000000000..f5ac989cd --- /dev/null +++ b/tests/hooks-fixtures/repository_hooks_success.toml @@ -0,0 +1,13 @@ +[repository.hooks] +run-before = [ + "sh -c 'echo Running repository hooks before > tests/generated/repository_hooks_success.log'", +] +run-after = [ + "sh -c 'echo Running repository hooks after >> tests/generated/repository_hooks_success.log'", +] +run-failed = [ + "sh -c 'echo Running repository hooks failed >> tests/generated/repository_hooks_success.log'", +] +run-finally = [ + "sh -c 'echo Running repository hooks finally >> tests/generated/repository_hooks_success.log'", +] diff --git a/tests/hooks.rs b/tests/hooks.rs new file mode 100644 index 000000000..897f32c14 --- /dev/null +++ b/tests/hooks.rs @@ -0,0 +1,314 @@ +//! Hooks test: runs the application as a subprocess and asserts its +//! interaction with different files due to hooks + +// #![forbid(unsafe_code)] +// #![warn( +// missing_docs, +// rust_2018_idioms, +// trivial_casts, +// unused_lifetimes, +// unused_qualifications +// )] + +use std::path::PathBuf; + +use abscissa_core::fs::remove_file; +use assert_cmd::Command; +use predicates::prelude::predicate; +use rstest::{fixture, rstest}; +use tempfile::{tempdir, TempDir}; + +use rustic_testing::TestResult; +#[fixture] +fn hook_fixture_dir() -> PathBuf { + ["tests", "hooks-fixtures"].iter().collect() +} + +#[fixture] +fn generated_dir() -> PathBuf { + ["tests", "generated"].iter().collect() +} + +#[fixture] +fn toml_fixture_dir() -> PathBuf { + hook_fixture_dir() +} + +#[fixture] +fn log_fixture_dir() -> PathBuf { + hook_fixture_dir().join("log") +} + +pub fn rustic_runner(temp_dir: &TempDir) -> TestResult { + let password = "test"; + let repo_dir = temp_dir.path().join("repo"); + + let mut runner = Command::new(env!("CARGO_BIN_EXE_rustic")); + + runner + .arg("-r") + .arg(repo_dir) + .arg("--password") + .arg(password) + .arg("--no-progress"); + + Ok(runner) +} + +#[allow(dead_code)] +enum BackupAction { + WithBackup, + WithoutBackup, +} + +// Load a template from a file and replace a placeholder with a value +// and write the result to a new file +fn load_template_replace_and_write( + template_path: &PathBuf, + placeholder: &str, + value: &str, + output_path: &PathBuf, +) -> TestResult<()> { + let template = std::fs::read_to_string(template_path)?; + let replaced = template.replace(placeholder, value); + std::fs::write(output_path, replaced)?; + + Ok(()) +} + +fn setup(with_backup: BackupAction) -> TestResult { + let temp_dir = tempdir()?; + rustic_runner(&temp_dir)? + .args(["init"]) + .assert() + .success() + .stderr(predicate::str::contains("successfully created.")) + .stderr(predicate::str::contains("successfully added.")); + + match with_backup { + BackupAction::WithBackup => { + rustic_runner(&temp_dir)? + // We need this so output on stderr is not being taken as an error + .arg("--log-level=error") + .args(["backup", "src/"]) + .assert() + .success(); + } + BackupAction::WithoutBackup => {} + } + + Ok(temp_dir) +} + +#[derive(Debug, PartialEq, Clone, Copy)] +enum RunnerStatus { + Success, + Failure, +} + +fn run_hook_comparison( + temp_dir: TempDir, + hooks_config: PathBuf, + args: &[&str], + snapshot_name: &str, + log_live_path: PathBuf, + status: RunnerStatus, +) -> TestResult<()> { + { + let runner = rustic_runner(&temp_dir)? + // We need this so output on stderr is not being taken as an error + .arg("--log-level=error") + .args(["-P", hooks_config.to_str().unwrap()]) + .args(args) + .assert(); + + match status { + RunnerStatus::Success => runner.success(), + RunnerStatus::Failure => runner.failure(), + }; + } + + let log_live = std::fs::read_to_string(&log_live_path)?; + remove_file(log_live_path)?; + insta::assert_ron_snapshot!(snapshot_name, log_live); + + Ok(()) +} + +#[rstest] +fn test_empty_hooks_do_nothing_passes(toml_fixture_dir: PathBuf) -> TestResult<()> { + let hooks_config = toml_fixture_dir.join("empty_hooks_success"); + + let temp_dir = setup(BackupAction::WithoutBackup)?; + + { + rustic_runner(&temp_dir)? + .args(["-P", hooks_config.to_str().unwrap()]) + .arg("repoinfo") + .assert() + .success() + .stdout(predicate::str::contains("Total Size")); + } + + Ok(()) +} + +macro_rules! generate_test_hook_function { + ($name:ident, $fixture:expr, $args:expr, $status:expr) => { + #[rstest] + fn $name(toml_fixture_dir: PathBuf, generated_dir: PathBuf) -> TestResult<()> { + let hooks_config_path = toml_fixture_dir.join($fixture); + let args = $args; + + let file_name = format!("{}.log", $fixture); + let log_live_path = generated_dir.join(&file_name); + + run_hook_comparison( + setup(BackupAction::WithoutBackup)?, + hooks_config_path, + args, + $fixture, + log_live_path, + $status, + )?; + + Ok(()) + } + }; +} + +// Scenario: Global hooks pass in order +generate_test_hook_function!( + test_global_hooks_order_passes, + "global_hooks_success", + &["repoinfo"], + RunnerStatus::Success +); + +// Scenario: Repository hooks pass in order +generate_test_hook_function!( + test_repository_hooks_order_passes, + "repository_hooks_success", + &["check"], + RunnerStatus::Success +); + +// Scenario: Backup hooks pass in order +generate_test_hook_function!( + test_backup_hooks_order_passes, + "backup_hooks_success", + &["backup", "src/"], + RunnerStatus::Success +); + +// Scenario: Full hooks pass in order +generate_test_hook_function!( + test_full_hooks_order_passes, + "full_hooks_success", + &["backup", "src/"], + RunnerStatus::Success +); + +// Scenario: Check do not run backup hooks +generate_test_hook_function!( + test_check_do_not_run_backup_hooks_passes, + "check_not_backup_hooks_success", + &["check"], + RunnerStatus::Success +); + +// Scenario: Failure in before backup hook does not run backup +generate_test_hook_function!( + test_backup_hooks_with_failure_passes, + "backup_hooks_failure", + &["backup", "src/"], + RunnerStatus::Failure +); + +// Scenario: Failure in after backup hook does run repo and global +// hooks failed and finally +generate_test_hook_function!( + test_full_hooks_with_failure_before_backup_passes, + "full_hooks_before_backup_failure", + &["backup", "src/"], + RunnerStatus::Failure +); + +// Scenario: Failure in before repo hook does run repo and global +// hooks failed and finally +generate_test_hook_function!( + test_full_hooks_with_failure_before_repo_passes, + "full_hooks_before_repo_failure", + &["backup", "src/"], + RunnerStatus::Failure +); + +#[rstest] +#[case(vec!["backup", "src/"], "backup", BackupAction::WithoutBackup)] +#[case(vec!["cat", "tree", "latest"], "cat", BackupAction::WithBackup)] +#[case(vec!["config"], "config", BackupAction::WithoutBackup)] +#[case(vec!["completions", "bash"], "completions", BackupAction::WithoutBackup)] +#[case(vec!["check"], "check", BackupAction::WithBackup)] +// #[case(vec!["copy"], "copy", BackupAction::WithBackup)] +// #[case(vec!["diff"], "diff", BackupAction::WithBackup)] +// TODO: Does it work? Also: Docs command requires a TTY +// #[case(vec!["docs", "--help"], "docs", BackupAction::WithoutBackup)] +#[case(vec!["dump", "latest:src/lib.rs"], "dump", BackupAction::WithBackup)] +#[case(vec!["find"], "find", BackupAction::WithoutBackup)] +#[case(vec!["forget"], "forget", BackupAction::WithoutBackup)] +// TODO: Needs special handling +// #[case(vec!["init", "--dry-run"], "init", BackupAction::WithoutBackup)] +// TODO: Needs user input +// #[case(vec!["key", "add"], "key", BackupAction::WithoutBackup)] +#[case(vec!["list", "indexpacks"], "list", BackupAction::WithBackup)] +#[case(vec!["ls", "latest"], "ls", BackupAction::WithBackup)] +#[case(vec!["merge"], "merge", BackupAction::WithoutBackup)] +#[case(vec!["snapshots"], "snapshots", BackupAction::WithBackup)] +#[case(vec!["show-config"], "show-config", BackupAction::WithoutBackup)] +// TODO: Github API errors with `NetworkError: api request failed with status: 403` +// #[case(vec!["self-update"], "self-update", BackupAction::WithoutBackup)] +#[case(vec!["prune"], "prune", BackupAction::WithBackup)] +#[case(vec!["repoinfo"], "repoinfo", BackupAction::WithBackup)] +#[case(vec!["repair", "index"], "repair", BackupAction::WithBackup)] +#[case(vec!["restore", "latest", "tests/generated/test-restore", "--dry-run"], "restore", BackupAction::WithBackup)] +#[case(vec!["tag"], "tag", BackupAction::WithBackup)] +// TODO: Requires user input +// #[case(vec!["webdav"], "webdav", BackupAction::WithBackup)] +fn test_hooks_access_for_all_commands_passes( + #[case] command_args: Vec<&str>, + #[case] command_name: &str, + #[case] backup_action: BackupAction, + toml_fixture_dir: PathBuf, + generated_dir: PathBuf, +) -> TestResult<()> { + let file_name = format!("{command_name}_hooks_access_success"); + let mut output_config_file_name = file_name.clone(); + output_config_file_name.push_str(".toml"); + + let hooks_config_path = generated_dir.join(&file_name); + let output_config_path = generated_dir.join(output_config_file_name); + + load_template_replace_and_write( + &toml_fixture_dir.join("commands_hooks_access_success.tpl"), + "${{filename}}", + &file_name, + &output_config_path, + )?; + + let log_live_path = generated_dir.join(format!("{file_name}.log")); + + let setup = setup(backup_action)?; + + run_hook_comparison( + setup, + hooks_config_path.clone(), + command_args.as_slice(), + &file_name, + log_live_path.clone(), + RunnerStatus::Success, + )?; + + remove_file(output_config_path)?; + + Ok(()) +} diff --git a/tests/show-config-fixtures/empty.txt b/tests/show-config-fixtures/empty.txt new file mode 100644 index 000000000..c7ede0bed --- /dev/null +++ b/tests/show-config-fixtures/empty.txt @@ -0,0 +1,86 @@ +[global] +use-profiles = [] +dry-run = false +check-index = false +no-progress = false + +[global.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[global.env] + +[repository] +no-cache = false +warm-up = false + +[repository.options] + +[repository.options-hot] + +[repository.options-cold] + +[repository.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[snapshot-filter] +filter-hosts = [] +filter-labels = [] +filter-paths = [] +filter-paths-exact = [] +filter-tags = [] +filter-tags-exact = [] + +[backup] +stdin-filename = "" +with-atime = false +ignore-devid = false +no-scan = false +json = false +long = false +quiet = false +init = false +skip-identical-parent = false +force = false +ignore-ctime = false +ignore-inode = false +globs = [] +iglobs = [] +glob-files = [] +iglob-files = [] +git-ignore = false +no-require-git = false +custom-ignorefiles = [] +exclude-if-present = [] +one-file-system = false +tags = [] +delete-never = false +snapshots = [] +sources = [] + +[backup.hooks] +run-before = [] +run-after = [] +run-failed = [] +run-finally = [] + +[copy] +targets = [] + +[forget] +prune = false +filter-hosts = [] +filter-labels = [] +filter-paths = [] +filter-paths-exact = [] +filter-tags = [] +filter-tags-exact = [] + +[webdav] +symlinks = false + diff --git a/tests/show-config.rs b/tests/show-config.rs new file mode 100644 index 000000000..582228e3b --- /dev/null +++ b/tests/show-config.rs @@ -0,0 +1,65 @@ +//! Config profile test: runs the application as a subprocess and asserts its +//! output for the `show-config` command + +// #![forbid(unsafe_code)] +// #![warn( +// missing_docs, +// rust_2018_idioms, +// trivial_casts, +// unused_lifetimes, +// unused_qualifications +// )] + +use std::{ + io::{Read, Write}, + path::PathBuf, + sync::LazyLock, +}; + +use abscissa_core::testing::prelude::*; + +use rustic_testing::{files_differ, get_temp_file, TestResult}; + +// Storing this value as a [`Lazy`] static ensures that all instances of +// the runner acquire a mutex when executing commands and inspecting +// exit statuses, serializing what would otherwise be multithreaded +// invocations as `cargo test` executes tests in parallel by default. +pub static LAZY_RUNNER: LazyLock = LazyLock::new(|| { + let mut runner = CmdRunner::new(env!("CARGO_BIN_EXE_rustic")); + runner.exclusive().capture_stdout(); + runner +}); + +fn cmd_runner() -> CmdRunner { + LAZY_RUNNER.clone() +} + +fn fixture() -> PathBuf { + ["tests", "show-config-fixtures", "empty.txt"] + .iter() + .collect() +} + +#[test] +fn test_show_config_passes() -> TestResult<()> { + let fixture_file = fixture(); + let mut file = get_temp_file()?; + + { + let file = file.as_file_mut(); + let mut runner = cmd_runner(); + let mut cmd = runner.args(["show-config"]).run(); + + let mut output = String::new(); + cmd.stdout().read_to_string(&mut output)?; + file.write_all(output.as_bytes())?; + file.sync_all()?; + cmd.wait()?.expect_success(); + } + + if files_differ(fixture_file, file.path())? { + panic!("generated empty.txt differs, breaking change!"); + } + + Ok(()) +} diff --git a/tests/snapshots/hooks__backup_hooks_access_success.snap b/tests/snapshots/hooks__backup_hooks_access_success.snap new file mode 100644 index 000000000..d27c136b2 --- /dev/null +++ b/tests/snapshots/hooks__backup_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning backup hooks before\nRunning backup hooks after\nRunning backup hooks finally\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__backup_hooks_failure.snap b/tests/snapshots/hooks__backup_hooks_failure.snap new file mode 100644 index 000000000..d07707eb0 --- /dev/null +++ b/tests/snapshots/hooks__backup_hooks_failure.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running backup hooks before\nRunning backup hooks failed\nRunning backup hooks finally\n" diff --git a/tests/snapshots/hooks__backup_hooks_success.snap b/tests/snapshots/hooks__backup_hooks_success.snap new file mode 100644 index 000000000..6241ce609 --- /dev/null +++ b/tests/snapshots/hooks__backup_hooks_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running backup hooks before\nRunning backup hooks after\nRunning backup hooks finally\n" diff --git a/tests/snapshots/hooks__cat_hooks_access_success.snap b/tests/snapshots/hooks__cat_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__cat_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__check_hooks_access_success.snap b/tests/snapshots/hooks__check_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__check_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__check_not_backup_hooks_success.snap b/tests/snapshots/hooks__check_not_backup_hooks_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__check_not_backup_hooks_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__completions_hooks_access_success.snap b/tests/snapshots/hooks__completions_hooks_access_success.snap new file mode 100644 index 000000000..98755ed10 --- /dev/null +++ b/tests/snapshots/hooks__completions_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__config_hooks_access_success.snap b/tests/snapshots/hooks__config_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__config_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__dump_hooks_access_success.snap b/tests/snapshots/hooks__dump_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__dump_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__find_hooks_access_success.snap b/tests/snapshots/hooks__find_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__find_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__forget_hooks_access_success.snap b/tests/snapshots/hooks__forget_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__forget_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__full_hooks_before_backup_failure.snap b/tests/snapshots/hooks__full_hooks_before_backup_failure.snap new file mode 100644 index 000000000..99130c8bd --- /dev/null +++ b/tests/snapshots/hooks__full_hooks_before_backup_failure.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning backup hooks before\nRunning backup hooks failed\nRunning backup hooks finally\nRunning repository hooks failed\nRunning repository hooks finally\nRunning global hooks failed\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__full_hooks_before_repo_failure.snap b/tests/snapshots/hooks__full_hooks_before_repo_failure.snap new file mode 100644 index 000000000..2a556c524 --- /dev/null +++ b/tests/snapshots/hooks__full_hooks_before_repo_failure.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks failed\nRunning repository hooks finally\nRunning global hooks failed\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__full_hooks_success.snap b/tests/snapshots/hooks__full_hooks_success.snap new file mode 100644 index 000000000..d27c136b2 --- /dev/null +++ b/tests/snapshots/hooks__full_hooks_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning backup hooks before\nRunning backup hooks after\nRunning backup hooks finally\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__global_hooks_success.snap b/tests/snapshots/hooks__global_hooks_success.snap new file mode 100644 index 000000000..98755ed10 --- /dev/null +++ b/tests/snapshots/hooks__global_hooks_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__list_hooks_access_success.snap b/tests/snapshots/hooks__list_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__list_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__ls_hooks_access_success.snap b/tests/snapshots/hooks__ls_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__ls_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__merge_hooks_access_success.snap b/tests/snapshots/hooks__merge_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__merge_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__prune_hooks_access_success.snap b/tests/snapshots/hooks__prune_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__prune_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__repair_hooks_access_success.snap b/tests/snapshots/hooks__repair_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__repair_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__repoinfo_hooks_access_success.snap b/tests/snapshots/hooks__repoinfo_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__repoinfo_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__repository_hooks_success.snap b/tests/snapshots/hooks__repository_hooks_success.snap new file mode 100644 index 000000000..3f15c4171 --- /dev/null +++ b/tests/snapshots/hooks__repository_hooks_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\n" diff --git a/tests/snapshots/hooks__restore_hooks_access_success.snap b/tests/snapshots/hooks__restore_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__restore_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__self-update_hooks_access_success.snap b/tests/snapshots/hooks__self-update_hooks_access_success.snap new file mode 100644 index 000000000..98755ed10 --- /dev/null +++ b/tests/snapshots/hooks__self-update_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__show-config_hooks_access_success.snap b/tests/snapshots/hooks__show-config_hooks_access_success.snap new file mode 100644 index 000000000..98755ed10 --- /dev/null +++ b/tests/snapshots/hooks__show-config_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__snapshots_hooks_access_success.snap b/tests/snapshots/hooks__snapshots_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__snapshots_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/tests/snapshots/hooks__tag_hooks_access_success.snap b/tests/snapshots/hooks__tag_hooks_access_success.snap new file mode 100644 index 000000000..08af39767 --- /dev/null +++ b/tests/snapshots/hooks__tag_hooks_access_success.snap @@ -0,0 +1,5 @@ +--- +source: tests/hooks.rs +expression: log_live +--- +"Running global hooks before\nRunning repository hooks before\nRunning repository hooks after\nRunning repository hooks finally\nRunning global hooks after\nRunning global hooks finally\n" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml deleted file mode 100644 index eef61707b..000000000 --- a/xtask/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "xtask" -version = "0.1.0" -edition = "2021" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow.workspace = true -clap.workspace = true -dialoguer = "0.11.0" -duct = "0.13.6" -fs_extra = "1.3.0" -glob = "0.3.1" diff --git a/xtask/src/helpers.rs b/xtask/src/helpers.rs deleted file mode 100644 index 5b676577e..000000000 --- a/xtask/src/helpers.rs +++ /dev/null @@ -1,92 +0,0 @@ -use anyhow::Result as AnyResult; -use dialoguer::{theme::ColorfulTheme, Confirm}; -use fs_extra as fsx; -use fsx::dir::CopyOptions; -use glob::glob; -use std::path::{Path, PathBuf}; - -/// -/// Remove a set of files given a glob -/// -/// # Errors -/// -/// Fails if listing or removal fails -/// -pub fn clean_files(pattern: &str) -> AnyResult<()> { - let files: Result, _> = glob(pattern)?.collect(); - files?.iter().try_for_each(remove_file) -} - -/// -/// Remove a single file -/// -/// # Errors -/// -/// Fails if removal fails -/// -pub fn remove_file

(path: P) -> AnyResult<()> -where - P: AsRef, -{ - fsx::file::remove(path).map_err(anyhow::Error::msg) -} - -/// -/// Remove a directory with its contents -/// -/// # Errors -/// -/// Fails if removal fails -/// -pub fn remove_dir

(path: P) -> AnyResult<()> -where - P: AsRef, -{ - fsx::dir::remove(path).map_err(anyhow::Error::msg) -} - -/// Check if path exists -/// -pub fn exists

(path: P) -> bool -where - P: AsRef, -{ - std::path::Path::exists(path.as_ref()) -} - -/// Copy entire folder contents -/// -/// # Errors -/// -/// Fails if file operations fail -/// -pub fn copy_contents(from: P, to: Q, overwrite: bool) -> AnyResult -where - P: AsRef, - Q: AsRef, -{ - let mut opts = CopyOptions::new(); - opts.content_only = true; - opts.overwrite = overwrite; - fsx::dir::copy(from, to, &opts).map_err(anyhow::Error::msg) -} - -/// Prompt the user to confirm an action -/// -/// # Panics -/// Panics if input interaction fails -/// -pub fn confirm(question: &str) -> bool { - Confirm::with_theme(&ColorfulTheme::default()) - .with_prompt(question) - .interact() - .unwrap() -} - -/// Gets the cargo root dir -/// -pub fn root_dir() -> PathBuf { - let mut xtask_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - xtask_dir.pop(); - xtask_dir -} diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs deleted file mode 100644 index b67665b22..000000000 --- a/xtask/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod helpers; -pub mod tasks; - -pub use tasks::install_deps::InstallationKind; diff --git a/xtask/src/main.rs b/xtask/src/main.rs deleted file mode 100644 index 9223c2ef3..000000000 --- a/xtask/src/main.rs +++ /dev/null @@ -1,67 +0,0 @@ -#![allow(dead_code)] - -use clap::{Parser, Subcommand}; -use std::path::PathBuf; -use xtask::InstallationKind; - -#[derive(Parser)] -struct Xtask { - #[command(subcommand)] - command: Option, -} - -#[derive(Subcommand)] -enum Commands { - /// generate code coverage report - Coverage { - /// generate html report - #[arg(long)] - html: bool, - - /// run on complete workspace - #[arg(short, long)] - workspace: bool, - - /// custom Cargo target directory - #[arg(short, long, value_parser = clap::value_parser!(PathBuf))] - target_dir: Option, - }, - /// install dependencies - #[command(subcommand)] - InstallDeps(InstallationKind), - /// show longest times taken in release build using cargo-bloat - BloatTime { - #[arg(short = 'p', long, help = "package to build", required = true)] - package: Option, - }, - /// show biggest crates in release build using cargo-bloat - BloatDeps { - #[arg(short = 'p', long, help = "package to build", required = true)] - package: Option, - }, - /// show longest times taken in release build using cargo - Timings { - /// output timings as json - #[arg(short, long)] - json: bool, - }, -} - -fn main() -> Result<(), anyhow::Error> { - let cli = Xtask::parse(); - - match cli.command { - Some(Commands::Coverage { - html, - workspace, - target_dir, - }) => xtask::tasks::coverage(html, workspace, target_dir)?, - Some(Commands::InstallDeps(kind)) => xtask::tasks::install_deps(kind)?, - Some(Commands::BloatTime { package }) => xtask::tasks::bloat_time(package)?, - Some(Commands::BloatDeps { package }) => xtask::tasks::bloat_deps(package)?, - Some(Commands::Timings { json }) => xtask::tasks::timings(json)?, - None => {} - } - - Ok(()) -} diff --git a/xtask/src/tasks.rs b/xtask/src/tasks.rs deleted file mode 100644 index 7197bda6f..000000000 --- a/xtask/src/tasks.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod bloat; -pub mod coverage; -pub mod install_deps; -pub mod timings; - -pub use bloat::{bloat_deps, bloat_time}; -pub use coverage::coverage; -pub use install_deps::install_deps; -pub use timings::timings; diff --git a/xtask/src/tasks/bloat.rs b/xtask/src/tasks/bloat.rs deleted file mode 100644 index 81d79636a..000000000 --- a/xtask/src/tasks/bloat.rs +++ /dev/null @@ -1,27 +0,0 @@ -/// Show crate build times -use anyhow::Result; -use duct::cmd; - -/// Show longest times taken in release build -/// -/// # Errors -/// -/// Errors if the command failed -/// -pub fn bloat_time(package: impl Into>) -> Result<()> { - let package = package.into().unwrap_or("rustic".to_string()); - cmd!("cargo", "bloat", "--time", "-j", "1", "-p", package).run()?; - Ok(()) -} - -/// Show biggest crates in release build -/// -/// # Errors -/// -/// Errors if the command failed -/// -pub fn bloat_deps(package: impl Into>) -> Result<()> { - let package = package.into().unwrap_or("rustic".to_string()); - cmd!("cargo", "bloat", "--release", "--crates", "-p", package).run()?; - Ok(()) -} diff --git a/xtask/src/tasks/coverage.rs b/xtask/src/tasks/coverage.rs deleted file mode 100644 index 916eb2797..000000000 --- a/xtask/src/tasks/coverage.rs +++ /dev/null @@ -1,81 +0,0 @@ -use anyhow::Result; -use duct::cmd; -use std::{fs::create_dir_all, path::PathBuf}; - -pub fn coverage( - devmode: bool, - workspace: bool, - target_dir: impl Into>, -) -> Result<()> { - let mut target_dir_new = target_dir.into().unwrap_or(PathBuf::from("./target")); - crate::helpers::remove_dir("coverage")?; - create_dir_all("coverage")?; - - println!("=== running coverage ==="); - - let base_cmd = if workspace { - cmd!( - "cargo", - "test", - "--workspace", - "--target-dir", - target_dir_new.clone() - ) - } else { - cmd!("cargo", "test", "--target-dir", target_dir_new.clone()) - }; - - base_cmd - .env("CARGO_INCREMENTAL", "0") - .env("RUSTFLAGS", "-Cinstrument-coverage") - .env("LLVM_PROFILE_FILE", "cargo-test-%p-%m.profraw") - .run()?; - println!("ok."); - - println!("=== generating report ==="); - let (fmt, file) = if devmode { - ("html", "coverage/html") - } else { - ("lcov", "coverage/lcov.info") - }; - - target_dir_new = target_dir_new.join("debug").join("deps"); - - cmd!( - "grcov", - ".", - "--binary-path", - target_dir_new, - "-s", - ".", - "-t", - fmt, - "--branch", - "--ignore-not-existing", - "--ignore", - "../*", - "--ignore", - "/*", - "--ignore", - "xtask/*", - "--ignore", - "*/src/tests/*", - "-o", - file, - ) - .run()?; - println!("ok."); - - println!("=== cleaning up ==="); - crate::helpers::clean_files("**/*.profraw")?; - println!("ok."); - if devmode { - if crate::helpers::confirm("open report folder?") { - cmd!("open", file).run()?; - } else { - println!("report location: {file}"); - } - } - - Ok(()) -} diff --git a/xtask/src/tasks/install_deps.rs b/xtask/src/tasks/install_deps.rs deleted file mode 100644 index 6af06212b..000000000 --- a/xtask/src/tasks/install_deps.rs +++ /dev/null @@ -1,65 +0,0 @@ -use anyhow::Result; -use clap::Subcommand; -use duct::cmd; - -#[derive(Subcommand, Debug, Clone, Copy)] -pub enum InstallationKind { - /// only essential deps (cargo-bloat, llvm-tools-preview, grcov) - Essentials, - /// only code coverage deps (llvm-tools-preview, grcov) - CodeCoverage, - /// only mutation test deps (cargo-mutants) - Mutants, - /// only deps for fuzzing (cargo-fuzz) - Fuzzing, - /// only deps for (de-)bloating (cargo-bloat) - Bloat, - /// full deps (all of above) - Full, -} - -/// Install cargo tools -/// -/// # Errors -/// -/// Errors if one of the commands failed -/// -pub fn install_deps(kind: InstallationKind) -> Result<()> { - match kind { - InstallationKind::Essentials => { - install_essentials()?; - Ok(()) - } - InstallationKind::Full => { - install_essentials()?; - cmd!("cargo", "install", "cargo-watch").run()?; - cmd!("cargo", "install", "cargo-hack").run()?; - cmd!("cargo", "install", "cargo-mutants").run()?; - Ok(()) - } - InstallationKind::CodeCoverage => { - cmd!("rustup", "component", "add", "llvm-tools-preview").run()?; - cmd!("cargo", "install", "grcov").run()?; - Ok(()) - } - InstallationKind::Mutants => { - cmd!("cargo", "install", "cargo-mutants").run()?; - Ok(()) - } - InstallationKind::Fuzzing => { - cmd!("cargo", "install", "cargo-fuzz").run()?; - Ok(()) - } - InstallationKind::Bloat => { - cmd!("cargo", "install", "cargo-bloat").run()?; - Ok(()) - } - } -} - -fn install_essentials() -> Result<()> { - cmd!("cargo", "install", "cargo-bloat").run()?; - cmd!("rustup", "component", "add", "llvm-tools-preview").run()?; - cmd!("cargo", "install", "grcov").run()?; - Ok(()) -} diff --git a/xtask/src/tasks/timings.rs b/xtask/src/tasks/timings.rs deleted file mode 100644 index f8b0d3a81..000000000 --- a/xtask/src/tasks/timings.rs +++ /dev/null @@ -1,15 +0,0 @@ -use anyhow::{Ok, Result}; -use duct::cmd; - -pub fn timings(json: bool) -> Result<()> { - let mut timings_str = String::from("--timings="); - - if json { - timings_str.push_str("json") - } else { - timings_str.push_str("html") - } - - cmd!("cargo", "build", "--release", timings_str).run()?; - Ok(()) -}