Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package topgrade for openSUSE:Factory checked in at 2026-02-03 21:34:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/topgrade (Old) and /work/SRC/openSUSE:Factory/.topgrade.new.1995 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "topgrade" Tue Feb 3 21:34:23 2026 rev:19 rq:1330741 version:16.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/topgrade/topgrade.changes 2026-01-12 10:31:18.346163160 +0100 +++ /work/SRC/openSUSE:Factory/.topgrade.new.1995/topgrade.changes 2026-02-03 21:35:13.866021983 +0100 @@ -1,0 +2,36 @@ +Tue Feb 03 11:11:40 UTC 2026 - Gerald Chen <[email protected]> + +- Update to version 16.9.0: + * chore: release v16.9.0 (#1710) + * chore(pre-commit): autoupdate (#1723) + * chore(deps): update github/codeql-action action to v4.32.1 (#1722) + * chore(deps): update vmactions/openbsd-vm digest to a23337e (#1720) + * chore(deps): update rust crate notify-rust to ~4.12.0 (#1721) + * refactor(system,home-manager): make matches more explicit (#1719) + * fix: add missing import (#1718) + * fix(nix): make nix-{channel,env} optional for flake-enabled systems (#1716) + * feat(system,home_manager): integrate nh into nix-based updaters (#1712) + * chore(pre-commit): autoupdate (#1704) + * chore(deps): update release-plz/action digest to e592230 (#1698) + * chore(deps): update actions/checkout action to v6.0.2 (#1699) + * chore(deps): update github/codeql-action action to v4.32.0 (#1700) + * chore(deps): update actions/attest-build-provenance action to v3.2.0 (#1703) + * chore(deps): update vmactions/openbsd-vm digest to f5b9bc1 (#1706) + * chore(renovate): disable rate-limiting (#1697) + * chore(renovate): disable rate-limiting (#1696) + * chore(deps): update dependency rust to v1.93.0 (#1695) + * chore(renovate): add rust-toolchain updating (#1694) + * chore: pin toolchain to stable instead of MSRV, add MSRV testing, simplify CI workflow (#1690) + * chore(pre-commit): autoupdate (#1687) + * feat(cargo): add `git` and `quiet` options (#1685) + * chore(renovate): use preset for lockfile config (#1684) + * chore(pre-commit): autoupdate (#1682) + * chore(deps): update github/codeql-action action to v4.31.10 (#1680) + * chore(deb): update copyright + * chore(deps): unpin toml + * docs(installation): add Pacstall Ubuntu package to README (#1676) + * chore(deps): update rust crate toml to v0.9.11 (#1675) + * ci(release): fix OpenBSD release job (#1674) + * ci(release): fix OpenBSD release job (#1672) + +------------------------------------------------------------------- Old: ---- topgrade-16.8.0.tar.zst New: ---- topgrade-16.9.0.tar.zst ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ topgrade.spec ++++++ --- /var/tmp/diff_new_pack.376kzC/_old 2026-02-03 21:35:15.678098138 +0100 +++ /var/tmp/diff_new_pack.376kzC/_new 2026-02-03 21:35:15.682098307 +0100 @@ -17,7 +17,7 @@ Name: topgrade -Version: 16.8.0 +Version: 16.9.0 Release: 0 Summary: Upgrade all the things License: GPL-3.0-only ++++++ _service ++++++ --- /var/tmp/diff_new_pack.376kzC/_old 2026-02-03 21:35:15.726100156 +0100 +++ /var/tmp/diff_new_pack.376kzC/_new 2026-02-03 21:35:15.734100492 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/topgrade-rs/topgrade.git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="scm">git</param> - <param name="revision">v16.8.0</param> + <param name="revision">v16.9.0</param> <param name="match-tag">*</param> <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> <param name="versionrewrite-replacement">\1</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.376kzC/_old 2026-02-03 21:35:15.774102173 +0100 +++ /var/tmp/diff_new_pack.376kzC/_new 2026-02-03 21:35:15.782102510 +0100 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/topgrade-rs/topgrade.git</param> - <param name="changesrevision">0dfc6dd72c59d7628d6d0c8b6bcc018b729f1fc3</param></service><service name="tar_scm"> + <param name="changesrevision">dce9b6bf8933ba2b3da186bc19ab3462b65f2395</param></service><service name="tar_scm"> <param name="url">https://ghproxy.net/https://github.com/topgrade-rs/topgrade.git</param> <param name="changesrevision">ef0a0d69bbe0cb08d6c4930ee18b734e03c215fb</param></service></servicedata> (No newline at EOF) ++++++ topgrade-16.8.0.tar.zst -> topgrade-16.9.0.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/renovate.json5 new/topgrade-16.9.0/.github/renovate.json5 --- old/topgrade-16.8.0/.github/renovate.json5 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/renovate.json5 2026-02-03 11:49:42.000000000 +0100 @@ -4,8 +4,21 @@ "config:best-practices", ":semanticCommits", ":semanticCommitTypeAll(chore)", + ":maintainLockFilesWeekly", + ":disableRateLimiting", + ], + customManagers: [ + { + customType: "regex", + managerFilePatterns: [ + "/(^|/)rust-toolchain\\.toml?$/", + ], + matchStrings: [ + "channel\\s*=\\s*\"(?<currentValue>\\d+\\.\\d+(\\.\\d+)?)\"", + ], + depNameTemplate: "rust", + packageNameTemplate: "rust-lang/rust", + datasourceTemplate: "github-tags", + }, ], - lockFileMaintenance: { - enabled: true, - }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/check_config_creation_if_not_exists.yml new/topgrade-16.9.0/.github/workflows/check_config_creation_if_not_exists.yml --- old/topgrade-16.8.0/.github/workflows/check_config_creation_if_not_exists.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/check_config_creation_if_not_exists.yml 2026-02-03 11:49:42.000000000 +0100 @@ -15,7 +15,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/check_i18n.yml new/topgrade-16.9.0/.github/workflows/check_i18n.yml --- old/topgrade-16.8.0/.github/workflows/check_i18n.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/check_i18n.yml 2026-02-03 11:49:42.000000000 +0100 @@ -14,7 +14,7 @@ runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/check_security_vulnerability.yml new/topgrade-16.9.0/.github/workflows/check_security_vulnerability.yml --- old/topgrade-16.8.0/.github/workflows/check_security_vulnerability.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/check_security_vulnerability.yml 2026-02-03 11:49:42.000000000 +0100 @@ -24,7 +24,7 @@ security-events: write steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -32,6 +32,6 @@ uses: microsoft/DevSkim-Action@4b5047945a44163b94642a1cecc0d93a3f428cc6 # v1.0.16 - name: Upload DevSkim scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/upload-sarif@6bc82e05fd0ea64601dd4b465378bbcf57de0314 # v4.32.1 with: sarif_file: devskim-results.sarif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/ci.yml new/topgrade-16.9.0/.github/workflows/ci.yml --- old/topgrade-16.8.0/.github/workflows/ci.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/ci.yml 2026-02-03 11:49:42.000000000 +0100 @@ -1,14 +1,20 @@ +name: Rust CI + on: pull_request: push: branches: - main -name: CI +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: CROSS_VER: '0.2.5' CARGO_NET_RETRY: 3 + CARGO_TERM_COLOR: always + RUST_BACKTRACE: full permissions: contents: read @@ -18,28 +24,24 @@ shell: bash jobs: - fmt: - name: Rustfmt + format: + name: Format (cargo fmt) runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Run cargo fmt - env: - TERM: xterm-256color - run: | - rustup component add rustfmt - cargo fmt --all -- --check + - run: rustup component add rustfmt + + - name: cargo fmt + run: cargo fmt --all -- --check custom-checks: name: Custom checks runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -92,74 +94,92 @@ # exit 1 fi + msrv: + name: MSRV check + needs: [ format, custom-checks ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + with: + persist-credentials: false + + - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 + + - name: Pin toolchain to MSRV + run: | + msrv=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].rust_version') + rustup override set "$msrv" + + - name: Print toolchain version + run: rustc --version + + - name: cargo check + run: cargo check --locked --all-features + main: - needs: [ fmt, custom-checks ] - name: ${{ matrix.target_name }} (check, clippy) + needs: [ format, custom-checks ] + name: ${{ matrix.target_name }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - - target: x86_64-linux-android - target_name: Android - use_cross: true + - target_name: Linux + target: x86_64-unknown-linux-gnu os: ubuntu-latest - - target: x86_64-unknown-freebsd - target_name: FreeBSD - use_cross: true - os: ubuntu-latest + - target_name: Windows + target: x86_64-pc-windows-msvc + os: windows-latest - - target: x86_64-unknown-linux-gnu - target_name: Linux - os: ubuntu-latest + - target_name: macOS-aarch64 + target: aarch64-apple-darwin + os: macos-latest - - target: x86_64-apple-darwin - target_name: macOS-x86_64 + - target_name: macOS-x86_64 + target: x86_64-apple-darwin os: macos-15-intel - - target: aarch64-apple-darwin - target_name: macOS-aarch64 - os: macos-latest + - target_name: FreeBSD + target: x86_64-unknown-freebsd + use_cross: true + os: ubuntu-latest - - target: x86_64-unknown-netbsd - target_name: NetBSD + - target_name: NetBSD + target: x86_64-unknown-netbsd use_cross: true os: ubuntu-latest - - target: x86_64-pc-windows-msvc - target_name: Windows - os: windows-latest + - target_name: Android + target: x86_64-linux-android + use_cross: true + os: ubuntu-latest env: cargo_cmd: ${{ matrix.use_cross == true && 'cross' || 'cargo' }} matrix_target: ${{ matrix.target }} steps: - - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Setup Rust Cache - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 + - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 with: prefix-key: ${{ matrix.target }} - name: Setup cross if: matrix.use_cross == true - run: | - curl -fL --retry 3 "https://github.com/cross-rs/cross/releases/download/v${CROSS_VER}/cross-x86_64-unknown-linux-musl.tar.gz" | tar vxz -C /usr/local/bin + run: curl -fL --retry 3 "https://github.com/cross-rs/cross/releases/download/v${CROSS_VER}/cross-x86_64-unknown-linux-musl.tar.gz" | tar vxz -C /usr/local/bin - - name: Run cargo/cross check - run: | - "${cargo_cmd}" check --locked --target "${matrix_target}" + - run: rustup component add clippy + + - name: Print toolchain version + run: rustc --version - - name: Run cargo/cross clippy + - name: cargo clippy run: | - rustup component add clippy - "${cargo_cmd}" clippy --locked --target "${matrix_target}" --all-features -- -D warnings + "${cargo_cmd}" clippy --locked --target "${matrix_target}" --all-features -- --deny warnings - - name: Run cargo test + - name: cargo test # ONLY run test with cargo if: matrix.use_cross == false - run: | - cargo test --locked --target "${matrix_target}" + run: cargo test --locked --target "${matrix_target}" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/create_release_assets.yml new/topgrade-16.9.0/.github/workflows/create_release_assets.yml --- old/topgrade-16.8.0/.github/workflows/create_release_assets.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/create_release_assets.yml 2026-02-03 11:49:42.000000000 +0100 @@ -33,7 +33,7 @@ env: tag: ${{ github.event.client_payload.tag }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -137,7 +137,7 @@ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate artifact attestations - uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0 + uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 with: subject-path: assets/* @@ -169,7 +169,7 @@ matrix_target: ${{ matrix.target }} tag: ${{ github.event.client_payload.tag }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -284,7 +284,7 @@ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate artifact attestations - uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0 + uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 with: subject-path: assets/* @@ -303,12 +303,12 @@ shell: openbsd {0} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Start OpenBSD VM - uses: vmactions/openbsd-vm@00753f2835e62704570734312de6f212069dfef7 # v1 + uses: vmactions/openbsd-vm@a23337e408f7990a9369882eafbc24af55f5d3af # v1 with: arch: x86_64 sync: nfs @@ -327,25 +327,37 @@ pkg_add -v rust-rustfmt rust-clippy - name: Check format - run: cargo fmt --all -- --check + run: | + cd $GITHUB_WORKSPACE + cargo fmt --all -- --check - name: Run clippy - run: cargo clippy --all-targets --locked -- -D warnings + run: | + cd $GITHUB_WORKSPACE + cargo clippy --all-targets --locked -- -D warnings - name: Run clippy (All features) - run: cargo clippy --all-targets --locked --all-features -- -D warnings + run: | + cd $GITHUB_WORKSPACE + cargo clippy --all-targets --locked --all-features -- -D warnings - name: Run tests - run: cargo test + run: | + cd $GITHUB_WORKSPACE + cargo test - name: Build Release binary - run: cargo build --release --all-features + run: | + cd $GITHUB_WORKSPACE + cargo build --release --all-features - name: Package OpenBSD release run: | + cd $GITHUB_WORKSPACE cargo install default-target mkdir -p assets - FILENAME=topgrade-${tag}-$(default-target) + # TODO: this should use the env var (${tag}), but can't because it's not set in the VM. + FILENAME=topgrade-${{ github.event.client_payload.tag }}-$(/root/.cargo/bin/default-target) mv target/release/topgrade assets cd assets tar -F ustar -czf "$FILENAME.tar.gz" topgrade @@ -353,12 +365,13 @@ ls . - name: Upload assets + shell: bash run: gh release upload "${tag}" assets/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate artifact attestations - uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0 + uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 with: subject-path: assets/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/dependency-review.yml new/topgrade-16.9.0/.github/workflows/dependency-review.yml --- old/topgrade-16.8.0/.github/workflows/dependency-review.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/dependency-review.yml 2026-02-03 11:49:42.000000000 +0100 @@ -17,7 +17,7 @@ runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/release-plz.yml new/topgrade-16.9.0/.github/workflows/release-plz.yml --- old/topgrade-16.8.0/.github/workflows/release-plz.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/release-plz.yml 2026-02-03 11:49:42.000000000 +0100 @@ -25,7 +25,7 @@ uses: dtolnay/rust-toolchain@stable - name: Run release-plz id: release-plz - uses: release-plz/action@487eb7b5c085a664d5c5ca05f4159bd9b591182a # v0.5 + uses: release-plz/action@e592230ad39e3ec735402572601fc621aa24355c # v0.5 with: command: release env: @@ -60,7 +60,7 @@ - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable - name: Run release-plz - uses: release-plz/action@487eb7b5c085a664d5c5ca05f4159bd9b591182a # v0.5 + uses: release-plz/action@e592230ad39e3ec735402572601fc621aa24355c # v0.5 with: command: release-pr env: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/release_to_pypi.yml new/topgrade-16.9.0/.github/workflows/release_to_pypi.yml --- old/topgrade-16.8.0/.github/workflows/release_to_pypi.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/release_to_pypi.yml 2026-02-03 11:49:42.000000000 +0100 @@ -15,7 +15,7 @@ matrix: target: [x86_64, x86, aarch64] steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -37,7 +37,7 @@ matrix: target: [x64, x86] steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -58,7 +58,7 @@ matrix: target: [x86_64, aarch64] steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -76,7 +76,7 @@ sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -108,7 +108,7 @@ - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - name: Generate artifact attestation - uses: actions/attest-build-provenance@00014ed6ed5efc5b1ab7f7f34a39eb55d41aa4f8 # v3.1.0 + uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 with: subject-path: 'wheels-*/*' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.github/workflows/scorecards.yml new/topgrade-16.9.0/.github/workflows/scorecards.yml --- old/topgrade-16.8.0/.github/workflows/scorecards.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.github/workflows/scorecards.yml 2026-02-03 11:49:42.000000000 +0100 @@ -36,7 +36,7 @@ steps: - name: "Checkout code" - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -71,6 +71,6 @@ # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/upload-sarif@6bc82e05fd0ea64601dd4b465378bbcf57de0314 # v4.32.1 with: sarif_file: results.sarif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/.pre-commit-config.yaml new/topgrade-16.9.0/.pre-commit-config.yaml --- old/topgrade-16.8.0/.pre-commit-config.yaml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/.pre-commit-config.yaml 2026-02-03 11:49:42.000000000 +0100 @@ -16,7 +16,7 @@ - id: trailing-whitespace - repo: https://github.com/crate-ci/typos - rev: v1.41.0 + rev: v1.43.0 hooks: - id: typos diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/BREAKINGCHANGES_dev.md new/topgrade-16.9.0/BREAKINGCHANGES_dev.md --- old/topgrade-16.8.0/BREAKINGCHANGES_dev.md 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/BREAKINGCHANGES_dev.md 2026-02-03 11:49:42.000000000 +0100 @@ -1,3 +1,9 @@ 1. The `jet_brains_toolbox` step was renamed to `jetbrains_toolbox`. If you're using the old name in your configuration file in the `disable` or `only` fields, simply change it to `jetbrains_toolbox`. +2. The `nix_helper` step was deprecated. Its `home_manager`-replacing + functionality has been merged into that step. When on NixOS, the `system` + step will decide whether to use `nh` according to the new config option + `misc.nix_handler`. +3. Since the `nix_helper` step is gone and `nix-darwin` support is otherwise + untested, `nh darwin` support has been removed for the time being as well. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/CHANGELOG.md new/topgrade-16.9.0/CHANGELOG.md --- old/topgrade-16.8.0/CHANGELOG.md 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/CHANGELOG.md 2026-02-03 11:49:42.000000000 +0100 @@ -7,6 +7,47 @@ ## [Unreleased] +## [16.9.0](https://github.com/topgrade-rs/topgrade/compare/v16.8.0...v16.9.0) - 2026-02-03 + +### Added + +- *(system,home_manager)* integrate nh into nix-based updaters ([#1712](https://github.com/topgrade-rs/topgrade/pull/1712)) +- *(cargo)* add `git` and `quiet` options ([#1685](https://github.com/topgrade-rs/topgrade/pull/1685)) + +### Fixed + +- add missing import ([#1718](https://github.com/topgrade-rs/topgrade/pull/1718)) +- *(nix)* make nix-{channel,env} optional for flake-enabled systems ([#1716](https://github.com/topgrade-rs/topgrade/pull/1716)) + +### Other + +- *(pre-commit)* autoupdate ([#1723](https://github.com/topgrade-rs/topgrade/pull/1723)) +- *(deps)* update github/codeql-action action to v4.32.1 ([#1722](https://github.com/topgrade-rs/topgrade/pull/1722)) +- *(deps)* update vmactions/openbsd-vm digest to a23337e ([#1720](https://github.com/topgrade-rs/topgrade/pull/1720)) +- *(deps)* update rust crate notify-rust to ~4.12.0 ([#1721](https://github.com/topgrade-rs/topgrade/pull/1721)) +- *(system,home-manager)* make matches more explicit ([#1719](https://github.com/topgrade-rs/topgrade/pull/1719)) +- *(pre-commit)* autoupdate ([#1704](https://github.com/topgrade-rs/topgrade/pull/1704)) +- *(deps)* update release-plz/action digest to e592230 ([#1698](https://github.com/topgrade-rs/topgrade/pull/1698)) +- *(deps)* update actions/checkout action to v6.0.2 ([#1699](https://github.com/topgrade-rs/topgrade/pull/1699)) +- *(deps)* update github/codeql-action action to v4.32.0 ([#1700](https://github.com/topgrade-rs/topgrade/pull/1700)) +- *(deps)* update actions/attest-build-provenance action to v3.2.0 ([#1703](https://github.com/topgrade-rs/topgrade/pull/1703)) +- *(deps)* update vmactions/openbsd-vm digest to f5b9bc1 ([#1706](https://github.com/topgrade-rs/topgrade/pull/1706)) +- *(renovate)* disable rate-limiting ([#1697](https://github.com/topgrade-rs/topgrade/pull/1697)) +- *(renovate)* disable rate-limiting ([#1696](https://github.com/topgrade-rs/topgrade/pull/1696)) +- *(deps)* update dependency rust to v1.93.0 ([#1695](https://github.com/topgrade-rs/topgrade/pull/1695)) +- *(renovate)* add rust-toolchain updating ([#1694](https://github.com/topgrade-rs/topgrade/pull/1694)) +- pin toolchain to stable instead of MSRV, add MSRV testing, simplify CI workflow ([#1690](https://github.com/topgrade-rs/topgrade/pull/1690)) +- *(pre-commit)* autoupdate ([#1687](https://github.com/topgrade-rs/topgrade/pull/1687)) +- *(renovate)* use preset for lockfile config ([#1684](https://github.com/topgrade-rs/topgrade/pull/1684)) +- *(pre-commit)* autoupdate ([#1682](https://github.com/topgrade-rs/topgrade/pull/1682)) +- *(deps)* update github/codeql-action action to v4.31.10 ([#1680](https://github.com/topgrade-rs/topgrade/pull/1680)) +- *(deb)* update copyright +- *(deps)* unpin toml +- *(installation)* add Pacstall Ubuntu package to README ([#1676](https://github.com/topgrade-rs/topgrade/pull/1676)) +- *(deps)* update rust crate toml to v0.9.11 ([#1675](https://github.com/topgrade-rs/topgrade/pull/1675)) +- *(release)* fix OpenBSD release job ([#1674](https://github.com/topgrade-rs/topgrade/pull/1674)) +- *(release)* fix OpenBSD release job ([#1672](https://github.com/topgrade-rs/topgrade/pull/1672)) + ## [16.8.0](https://github.com/topgrade-rs/topgrade/compare/v16.7.0...v16.8.0) - 2026-01-07 ### Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/Cargo.lock new/topgrade-16.9.0/Cargo.lock --- old/topgrade-16.8.0/Cargo.lock 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/Cargo.lock 2026-02-03 11:49:42.000000000 +0100 @@ -1665,9 +1665,9 @@ [[package]] name = "notify-rust" -version = "4.11.7" +version = "4.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6442248665a5aa2514e794af3b39661a8e73033b1cc5e59899e1276117ee4400" +checksum = "21af20a1b50be5ac5861f74af1a863da53a11c38684d9818d82f1c42f7fdc6c2" dependencies = [ "futures-lite", "log", @@ -2907,9 +2907,9 @@ [[package]] name = "toml" -version = "0.9.10+spec-1.1.0" +version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ "indexmap", "serde_core", @@ -2987,7 +2987,7 @@ [[package]] name = "topgrade" -version = "16.8.0" +version = "16.9.0" dependencies = [ "async-lock", "base64ct", @@ -3027,7 +3027,7 @@ "tempfile", "thiserror 2.0.17", "tokio", - "toml 0.9.10+spec-1.1.0", + "toml 0.9.11+spec-1.1.0", "tracing", "tracing-subscriber", "walkdir", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/Cargo.toml new/topgrade-16.9.0/Cargo.toml --- old/topgrade-16.8.0/Cargo.toml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/Cargo.toml 2026-02-03 11:49:42.000000000 +0100 @@ -6,7 +6,7 @@ license = "GPL-3.0-or-later" repository = "https://github.com/topgrade-rs/topgrade" rust-version = "1.84.1" -version = "16.8.0" +version = "16.9.0" exclude = ["doc/screenshot.gif", "BREAKINGCHANGES_dev.md"] edition = "2021" @@ -16,7 +16,7 @@ home = "=0.5.11" etcetera = "=0.10.0" serde = { version = "~1.0", features = ["derive"] } -toml = { version = "=0.9.10", features = ["preserve_order"] } +toml = { version = "~0.9.11", features = ["preserve_order"] } which_crate = { version = "~8.0", package = "which" } shellexpand = "~3.1" clap = { version = "~4.5", features = ["cargo", "derive"] } @@ -39,7 +39,7 @@ tracing-subscriber = { version = "~0.3.20", features = ["env-filter", "time"] } merge = "~0.1" regex-split = "~0.1" -notify-rust = "~4.11" +notify-rust = "~4.12.0" wildmatch = "2.3.0" rust-i18n = "3.0.1" sys-locale = "0.3.1" @@ -63,7 +63,7 @@ [package.metadata.deb] name = "topgrade" maintainer = "Chris Gelatt <[email protected]>" -copyright = "2024, Topgrade Team" +copyright = "2026, Topgrade Team" license-file = ["LICENSE", "0"] depends = "$auto" extended-description = "Keeping your system up to date usually involves invoking multiple package managers. This results in big, non-portable shell one-liners saved in your shell. To remedy this, Topgrade detects which tools you use and runs the appropriate commands to update them." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/README.md new/topgrade-16.9.0/README.md --- old/topgrade-16.8.0/README.md 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/README.md 2026-02-03 11:49:42.000000000 +0100 @@ -48,6 +48,8 @@ `scoop bucket add main && scoop install main/topgrade`](https://scoop.sh/#/apps?q=topgrade) - macOS ([MacPorts](https://www.macports.org/)): [ `sudo port install topgrade`](https://ports.macports.org/port/topgrade/) +- Ubuntu ([Pacstall](https://pacstall.dev/)): + [`pacstall -I topgrade-bin`](https://github.com/pacstall/pacstall-programs/blob/master/packages/topgrade-bin/topgrade-bin.pacscript) - NixOS or Nix (nixpkgs): [topgrade](https://search.nixos.org/packages?show=topgrade) - Void Linux: [`sudo xbps-install -S topgrade`](https://voidlinux.org/packages/?arch=x86_64&q=topgrade) @@ -59,6 +61,10 @@ See [`config.example.toml`](https://github.com/topgrade-rs/topgrade/blob/main/config.example.toml) for an example configuration file. +## MSRV + +Find the current MSRV in `Cargo.toml` under `rust-version`. This MSRV will only be bumped in a major release. + ## Migration and Breaking Changes Whenever there is a **breaking change**, the major version number will be bumped, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/config.example.toml new/topgrade-16.9.0/config.example.toml --- old/topgrade-16.8.0/config.example.toml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/config.example.toml 2026-02-03 11:49:42.000000000 +0100 @@ -96,6 +96,12 @@ # (default: true) # show_distribution_summary = false +# For NixOS/home-manager, there are multiple ways to switch to newer configurations. +# When set to autodetect: use nh when available, fall back to vanilla +# Allowed values: +# autodetect, nh, vanilla +# nix_handler = "autodetect" + # Commands to run before anything [pre_commands] @@ -424,6 +430,18 @@ # (default: false) # aot = true +[cargo] +# If this is set to true, `cargo install-update` also updates git-originating packages. +# (default: true) +# git = false + +# If this is set to true, `cargo install-update` is run quietly. +# (default: false) +# quiet = true + +# Other options like `--locked` or `--jobs` can be passed to `cargo install` +# using the `CARGO_INSTALL_OPTS` environment variable. + [rustup] # If set, updates only these channels. # (default: [] (all channels)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/locales/app.yml new/topgrade-16.9.0/locales/app.yml --- old/topgrade-16.8.0/locales/app.yml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/locales/app.yml 2026-02-03 11:49:42.000000000 +0100 @@ -1402,22 +1402,30 @@ zh_CN: "<省略了 `deb-get clean` 的输出>" zh_TW: "<省略了 `deb-get clean` 的輸出>" de: "<Ausgabe von `deb-get clean` ausgelassen>" -"You have a flake inside of $FLAKE. This is deprecated for nh.": - en: "You have a flake inside of $FLAKE. This is deprecated for nh." - lt: "Jūs turite flake viduje $FLAKE. Tai yra pasenę nh." - es: "Tienes un flake dentro de $FLAKE. Esto está en desuso para nh." - fr: "Vous avez un flake à l'intérieur de $FLAKE. Ceci est obsolète pour nh." - zh_CN: "你在 $FLAKE 里有一个 flake。这在 nh 中已被弃用。" - zh_TW: "你在 $FLAKE 裡有一個 flake。這在 nh 中已被棄用。" - de: "Sie haben ein flake in $FLAKE. Dies ist für nh veraltet." -"nh cannot find any configured flakes": - en: "nh cannot find any configured flakes" - lt: "nh nepavyksta rasti jokių sukonfigūruotų flake" - es: "nh no puede encontrar ningún flake configurado" - fr: "nh ne peut trouver aucun flake configuré" - zh_CN: "nh 无法找到任何已配置的 flake" - zh_TW: "nh 找不到任何已設定的 flake" - de: "nh kann keine konfigurierten flakes finden" +"linux.nix_handler = \"{value}\", but {resulting_tool} is not available": + en: "linux.nix_handler = \"%{value}\", but %{resulting_tool} is not available" + lt: "linux.nix_handler = \"%{value}\", bet %{resulting_tool} nėra pasiekiamas" + es: "linux.nix_handler = \"%{value}\", pero %{resulting_tool} no está disponible" + fr: "linux.nix_handler = \"%{value}\", mais %{resulting_tool} n’est pas disponible" + zh_CN: "linux.nix_handler = \"%{value}\",但 %{resulting_tool} 不可用" + zh_TW: "linux.nix_handler = \"%{value}\",但 %{resulting_tool} 不可用" + de: "linux.nix_handler = \"%{value}\", aber %{resulting_tool} ist nicht verfügbar" +"{step}: linux.nix_handler = \"nh\", but neither $NH_FLAKE nor ${specific_var} were set": + en: "%{step}: linux.nix_handler = \"nh\", but neither $NH_FLAKE nor $%{specific_var} were set" + lt: "%{step}: linux.nix_handler = \"nh\", tačiau nebuvo nustatyti nei $NH_FLAKE, nei $%{specific_var}" + es: "%{step}: linux.nix_handler = \"nh\", pero no se establecieron ni $NH_FLAKE ni $%{specific_var}" + fr: "%{step} : linux.nix_handler = \"nh\", mais ni $NH_FLAKE ni $%{specific_var} n’ont été définis" + zh_CN: "%{step}:linux.nix_handler = \"nh\", 但未设置 $NH_FLAKE 和 $%{specific_var}" + zh_TW: "%{step}:linux.nix_handler = \"nh\",但未設定 $NH_FLAKE 與 $%{specific_var}" + de: "%{step}: linux.nix_handler = \"nh\", aber weder $NH_FLAKE noch $%{specific_var} wurden gesetzt" +"`{step}` step is deprecated": + en: "`%{step}` step is deprecated" + lt: "`%{step}` žingsnis yra nebenaudojamas" + es: "El paso `%{step}` está obsoleto" + fr: "L’étape `%{step}` est obsolète" + zh_CN: "`%{step}` 步骤已弃用" + zh_TW: "`%{step}` 步驟已棄用" + de: "Der Schritt `%{step}` ist veraltet" "System Manuals": en: "System Manuals" lt: "Sistemos Vadovai" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/rust-toolchain.toml new/topgrade-16.9.0/rust-toolchain.toml --- old/topgrade-16.8.0/rust-toolchain.toml 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/rust-toolchain.toml 2026-02-03 11:49:42.000000000 +0100 @@ -1,2 +1,2 @@ [toolchain] -channel = "1.84.1" +channel = "1.93.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/config.rs new/topgrade-16.9.0/src/config.rs --- old/topgrade-16.8.0/src/config.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/config.rs 2026-02-03 11:49:42.000000000 +0100 @@ -15,6 +15,7 @@ use merge::Merge; use regex::Regex; use regex_split::RegexSplit; +use rust_i18n::t; use serde::Deserialize; use strum::IntoEnumIterator; use tracing::{debug, error}; @@ -23,8 +24,9 @@ use super::utils::editor; use crate::command::CommandExt; use crate::execution_context::RunType; -use crate::step::Step; +use crate::step::{Step, DEPRECATED_STEPS}; use crate::sudo::SudoKind; +use crate::terminal::print_warning; use crate::utils::string_prepend_str; // TODO: Add i18n to this. Tracking issue: https://github.com/topgrade-rs/topgrade/issues/859 @@ -248,6 +250,15 @@ } } +#[derive(Debug, Deserialize, Clone, Copy, Default, PartialEq)] +#[serde(rename_all = "kebab-case")] +pub enum NixHandler { + #[default] + Autodetect, + Nh, + Vanilla, +} + #[derive(Deserialize, Default, Debug, Merge)] #[serde(deny_unknown_fields)] pub struct Linux { @@ -370,6 +381,8 @@ log_filters: Option<Vec<String>>, show_distribution_summary: Option<bool>, + + nix_handler: Option<NixHandler>, } #[derive(Clone, Copy, Debug, Deserialize, ValueEnum, Default)] @@ -421,6 +434,13 @@ #[derive(Deserialize, Default, Debug, Merge)] #[serde(deny_unknown_fields)] +pub struct Cargo { + git: Option<bool>, + quiet: Option<bool>, +} + +#[derive(Deserialize, Default, Debug, Merge)] +#[serde(deny_unknown_fields)] pub struct Rustup { channels: Option<Vec<String>>, } @@ -526,6 +546,9 @@ doom: Option<DoomConfig>, #[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)] + cargo: Option<Cargo>, + + #[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)] rustup: Option<Rustup>, #[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)] @@ -1023,10 +1046,15 @@ } } + let step_is_deprecated = |x| DEPRECATED_STEPS.contains(&x); + // If neither of those contain anything if enabled_steps.is_empty() { // All steps are enabled enabled_steps.extend(Step::iter()); + // Handle deprecated steps. Disable automatically when not explicitly mentioned in the + // config, so that the warning doesn't print. + enabled_steps.retain(|x| !step_is_deprecated(*x)); } let mut disabled_steps: Vec<Step> = Vec::new(); @@ -1037,6 +1065,15 @@ } } + // When a deprecated step is mentioned, + for step in enabled_steps + .iter() + .chain(disabled_steps.iter()) + .filter(|x| step_is_deprecated(**x)) + { + print_warning(t!("`{step}` step is deprecated", step = format!("{step:?}"))); + } + // All steps that are disabled are not enabled, except ones that are passed to `--only` enabled_steps.retain(|e| !disabled_steps.contains(e) || opt.only.contains(e)); enabled_steps @@ -1456,6 +1493,15 @@ .and_then(|linux| linux.dnf_arguments.as_deref()) } + /// Get the handler to use for NixOS/home-manager + pub fn nix_handler(&self) -> NixHandler { + self.config_file + .misc + .as_ref() + .and_then(|s| s.nix_handler) + .unwrap_or_default() + } + /// Extra nix arguments pub fn nix_arguments(&self) -> Option<&str> { self.config_file @@ -1584,6 +1630,22 @@ .unwrap_or(true) } + pub fn cargo_update_git(&self) -> bool { + self.config_file + .cargo + .as_ref() + .and_then(|cargo| cargo.git) + .unwrap_or(true) + } + + pub fn cargo_update_quiet(&self) -> bool { + self.config_file + .cargo + .as_ref() + .and_then(|cargo| cargo.quiet) + .unwrap_or(false) + } + pub fn rustup_channels(&self) -> Vec<String> { self.config_file .rustup diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/step.rs new/topgrade-16.9.0/src/step.rs --- old/topgrade-16.8.0/src/step.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/step.rs 2026-02-03 11:49:42.000000000 +0100 @@ -14,6 +14,8 @@ use crate::steps::*; use crate::utils::hostname; +pub const DEPRECATED_STEPS: [Step; 1] = [Step::NixHelper]; + #[derive(ValueEnum, EnumString, VariantNames, Debug, Clone, PartialEq, Eq, Deserialize, EnumIter, Copy, EnumCount)] #[clap(rename_all = "snake_case")] #[serde(rename_all = "snake_case")] @@ -445,11 +447,7 @@ #[cfg(unix)] runner.execute(*self, "nix upgrade-nix", || unix::run_nix_self_upgrade(ctx))? } - NixHelper => - { - #[cfg(unix)] - runner.execute(*self, "nh", || unix::run_nix_helper(ctx))? - } + NixHelper => {} Node => runner.execute(*self, "npm", || node::run_npm_upgrade(ctx))?, Opam => runner.execute(*self, "opam", || generic::run_opam_update(ctx))?, Pacdef => diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/steps/generic.rs new/topgrade-16.9.0/src/steps/generic.rs --- old/topgrade-16.8.0/src/steps/generic.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/steps/generic.rs 2026-02-03 11:49:42.000000000 +0100 @@ -70,9 +70,15 @@ return Err(SkipStep(message).into()); }; - ctx.execute(cargo_update) - .args(["install-update", "--git", "--all"]) - .status_checked()?; + let mut command = ctx.execute(cargo_update); + command.args(["install-update", "--all"]); + if ctx.config().cargo_update_git() { + command.arg("--git"); + } + if ctx.config().cargo_update_quiet() { + command.arg("--quiet"); + } + command.status_checked()?; if ctx.config().cleanup() { let cargo_cache = require("cargo-cache") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/steps/os/linux.rs new/topgrade-16.9.0/src/steps/os/linux.rs --- old/topgrade-16.8.0/src/steps/os/linux.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/steps/os/linux.rs 2026-02-03 11:49:42.000000000 +0100 @@ -7,11 +7,13 @@ use tracing::{debug, warn}; use crate::command::CommandExt; +use crate::config::NixHandler; use crate::error::{SkipStep, TopgradeError}; use crate::execution_context::ExecutionContext; use crate::step::Step; use crate::steps::generic::is_wsl; use crate::steps::os::archlinux; +use crate::steps::unix::{can_nh_switch, nh_switch, NhSwitchArgs}; use crate::sudo::SudoExecuteOpts; use crate::terminal::{print_separator, prompt_yesno}; use crate::utils::{require, require_one, which, PathExt}; @@ -799,15 +801,37 @@ fn upgrade_nixos(ctx: &ExecutionContext) -> Result<()> { let sudo = ctx.require_sudo()?; + let nix_handler = ctx.config().nix_handler(); + let nh_switch_args = NhSwitchArgs { + step: "system", + installable_type: "os", + specific_var: "NH_OS_FLAKE", + print_separator: false, + }; + let can_nh_switch = can_nh_switch(&nh_switch_args); - let mut command = sudo.execute(ctx, "/run/current-system/sw/bin/nixos-rebuild")?; - command.args(["switch", "--upgrade"]); + match (nix_handler, can_nh_switch) { + // nh is available and we want it + (NixHandler::Autodetect | NixHandler::Nh, Ok(nh)) => { + nh_switch(ctx, &nh, &nh_switch_args)?; + } + // nh is not available but we need it + (NixHandler::Nh, Err(e)) => return Err(e), + // nh is not available and we don't need it, so we fall back + (NixHandler::Autodetect, Err(_)) + // We need vanilla + | (NixHandler::Vanilla, _) => { + let mut command = sudo.execute(ctx, "/run/current-system/sw/bin/nixos-rebuild")?; + command.args(["switch", "--upgrade"]); - if let Some(args) = ctx.config().nix_arguments() { - command.args(args.split_whitespace()); + if let Some(args) = ctx.config().nix_arguments() { + command.args(args.split_whitespace()); + } + command.status_checked()?; + } } - command.status_checked()?; + // TODO: maybe use `nh clean` when available&&wanted ? if ctx.config().cleanup() { sudo.execute(ctx, "/run/current-system/sw/bin/nix-collect-garbage")? .arg("-d") @@ -1125,6 +1149,9 @@ pub fn run_auto_cpufreq(ctx: &ExecutionContext) -> Result<()> { let auto_cpu_freq = require("auto-cpufreq")?.canonicalize()?; + // The fix is *auto_cpu_freq != *"/usr/local/bin/auto-cpufreq", but that impl is not available in MSRV yet + // TODO: once MSRV is bumped high enough that it is, remove this and apply lint + #[allow(clippy::cmp_owned)] if auto_cpu_freq != PathBuf::from("/usr/local/bin/auto-cpufreq") { return Err(SkipStep(String::from( "`auto-cpufreq` was not installed by the official installer, but presumably by a package manager.", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/steps/os/macos.rs new/topgrade-16.9.0/src/steps/os/macos.rs --- old/topgrade-16.8.0/src/steps/os/macos.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/steps/os/macos.rs 2026-02-03 11:49:42.000000000 +0100 @@ -200,7 +200,7 @@ pub fn process_xcodes_releases(releases_filtered: Vec<String>, should_ask: bool, ctx: &ExecutionContext) -> Result<()> { let xcodes = require("xcodes")?; - if releases_filtered.last().map_or(true, |s| !s.contains("(Installed)")) && !releases_filtered.is_empty() { + if releases_filtered.last().is_none_or(|s| !s.contains("(Installed)")) && !releases_filtered.is_empty() { println!( "{} {}", t!("New Xcode release detected:"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/topgrade-16.8.0/src/steps/os/unix.rs new/topgrade-16.9.0/src/steps/os/unix.rs --- old/topgrade-16.8.0/src/steps/os/unix.rs 2026-01-09 13:43:16.000000000 +0100 +++ new/topgrade-16.9.0/src/steps/os/unix.rs 2026-02-03 11:49:42.000000000 +0100 @@ -19,7 +19,9 @@ use tracing::{debug, warn}; use crate::command::CommandExt; +use crate::config::NixHandler; use crate::sudo::SudoExecuteOpts; +use crate::utils::require_one; use crate::XDG_DIRS; use crate::{output_changed_message, HOME_DIR}; @@ -551,8 +553,6 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> { let nix = require("nix")?; - let nix_channel = require("nix-channel")?; - let nix_env = require("nix-env")?; // TODO: Is None possible here? let profile_path = match home::home_dir() { Some(home) => XDG_DIRS @@ -565,8 +565,6 @@ debug!("nix profile: {:?}", profile_path); let manifest_json_path = profile_path.join("manifest.json"); - print_separator("Nix"); - #[cfg(target_os = "macos")] { if require("darwin-rebuild").is_ok() { @@ -576,8 +574,6 @@ } } - ctx.execute(nix_channel).arg("--update").status_checked()?; - let nix_version = NixVersion::new(ctx, &nix)?; // Nix since 2.21.0 uses `--all --impure` rather than `.*` to upgrade all packages. @@ -588,7 +584,20 @@ vec![".*"] }; + // nix-channel might not be available and isn't always necessary to perform profile updates + let nix_channel_result = if let Ok(nix_channel) = require("nix-channel") { + print_separator("Nix Channels"); + ctx.execute(nix_channel).arg("--update").status_checked() + } else { + Ok(()) + }; + if Path::new(&manifest_json_path).exists() { + // nix-channel doesn't have to succeed when upgrading nix profiles, just warn about it + if let Err(e) = nix_channel_result { + warn!("`nix-channel --update` failed: {e}"); + } + print_separator("Nix Profiles"); ctx.execute(nix) .args(nix_args()) .arg("profile") @@ -597,6 +606,11 @@ .arg("--verbose") .status_checked() } else { + // a successful nix-channel run is expected to perform nix-env upgrades + nix_channel_result?; + let nix_env = require("nix-env")?; + print_separator("Nix"); + let mut command = ctx.execute(nix_env); command.arg("--upgrade"); if let Some(args) = ctx.config().nix_env_arguments() { @@ -731,79 +745,63 @@ /// Returns a directory from an environment variable, if and only if it is a directory which /// contains a flake.nix -fn flake_dir(var: &'static str) -> Option<PathBuf> { +pub(super) fn flake_dir(var: &'static str) -> Option<PathBuf> { std::env::var_os(var) .map(PathBuf::from) .take_if(|x| std::fs::exists(x.join("flake.nix")).is_ok_and(|x| x)) } -/// Update NixOS and home-manager through a flake using `nh` -/// -/// See: https://github.com/viperML/nh -pub fn run_nix_helper(ctx: &ExecutionContext) -> Result<()> { - require("nix")?; - let nix_helper = require("nh")?; - - let fallback_flake_path = flake_dir("NH_FLAKE"); - let darwin_flake_path = flake_dir("NH_DARWIN_FLAKE"); - let home_flake_path = flake_dir("NH_HOME_FLAKE"); - let nixos_flake_path = flake_dir("NH_OS_FLAKE"); - - let all_flake_paths: Vec<_> = [ - fallback_flake_path.as_ref(), - darwin_flake_path.as_ref(), - home_flake_path.as_ref(), - nixos_flake_path.as_ref(), - ] - .into_iter() - .flatten() - .collect(); - - // if none of the paths exist AND contain a `flake.nix`, skip - if all_flake_paths.is_empty() { - if flake_dir("FLAKE").is_some() { - warn!( - "{}", - t!("You have a flake inside of $FLAKE. This is deprecated for nh.") - ); - } - return Err(SkipStep(t!("nh cannot find any configured flakes").into()).into()); - } - - let nh_switch = |ty: &'static str| -> Result<()> { - print_separator(format!("nh {ty}")); - - let mut cmd = ctx.execute(&nix_helper); - cmd.arg(ty); - cmd.arg("switch"); - cmd.arg("-u"); - - if !ctx.config().yes(Step::NixHelper) { - cmd.arg("--ask"); - } - cmd.status_checked()?; - Ok(()) +pub(super) struct NhSwitchArgs<'a> { + pub step: &'a str, + pub installable_type: &'a str, + pub specific_var: &'a str, + pub print_separator: bool, +} + +pub(super) fn can_nh_switch(args: &NhSwitchArgs<'static>) -> Result<PathBuf> { + let nix_helper = require("nh"); + + if nix_helper.is_err() { + return Err(SkipStep( + t!( + "linux.nix_handler = \"{value}\", but {resulting_tool} is not available", + value = "nh", + resulting_tool = "nh" + ) + .into(), + ) + .into()); }; - // We assume that if the user has set these variables, we can throw an error if nh cannot find - // a flake there. So we do not anymore perform an eval check to find out whether we should skip - // or not. - #[cfg(target_os = "macos")] - if darwin_flake_path.is_some() || fallback_flake_path.is_some() { - nh_switch("darwin")?; + if flake_dir("NH_FLAKE").is_none() && flake_dir(args.specific_var).is_none() { + return Err(SkipStep( + t!( + "{step}: linux.nix_handler = \"nh\", but neither $NH_FLAKE nor ${specific_var} were set", + step = args.step, + specific_var = args.specific_var + ) + .into(), + ) + .into()); } - if home_flake_path.is_some() || fallback_flake_path.is_some() { - nh_switch("home")?; - } + nix_helper +} - #[cfg(target_os = "linux")] - if matches!(Distribution::detect(), Ok(Distribution::NixOS)) - && (nixos_flake_path.is_some() || fallback_flake_path.is_some()) - { - nh_switch("os")?; +pub(super) fn nh_switch(ctx: &ExecutionContext, nh: &PathBuf, args: &NhSwitchArgs<'static>) -> Result<()> { + if args.print_separator { + print_separator(format!("nh {}", args.installable_type)); } + let mut cmd = ctx.execute(nh); + cmd.arg(args.installable_type); + cmd.arg("switch"); + cmd.arg("-u"); + + if !ctx.config().yes(Step::System) { + cmd.arg("--ask"); + } + cmd.status_checked()?; Ok(()) } @@ -906,18 +904,49 @@ } pub fn run_home_manager(ctx: &ExecutionContext) -> Result<()> { - let home_manager = require("home-manager")?; + require_one(["home-manager", "nh"])?; + let home_manager = require("home-manager"); + let nix_handler = ctx.config().nix_handler(); + let nh_switch_args = NhSwitchArgs { + step: "home_manager", + installable_type: "home", + specific_var: "NH_HOME_FLAKE", + print_separator: true, + }; + let can_nh_switch = can_nh_switch(&nh_switch_args); - print_separator("home-manager"); + match (home_manager, nix_handler, can_nh_switch) { + // nh is available and we want it + (_, NixHandler::Autodetect | NixHandler::Nh, Ok(nh)) => nh_switch(ctx, &nh, &nh_switch_args), + // nh is not available but we need it + (_, NixHandler::Nh, Err(e)) => Err(e), + // home-manager is not available but we need it + (Err(_), NixHandler::Vanilla, _) => Err(SkipStep( + t!( + "linux.nix_handler = \"{value}\", but {resulting_tool} is not available", + value = "vanilla", + resulting_tool = "home-manager" + ) + .into(), + ) + .into()), + // nh is not available and we don't need it, so we fall back + (Ok(home_manager), NixHandler::Autodetect, Err(_)) + // We need home-manager + | (Ok(home_manager), NixHandler::Vanilla, _) => { + print_separator("home-manager"); - let mut cmd = ctx.execute(home_manager); - cmd.arg("switch"); + let mut cmd = ctx.execute(home_manager); + cmd.arg("switch"); - if let Some(extra_args) = ctx.config().home_manager() { - cmd.args(extra_args); - } + if let Some(extra_args) = ctx.config().home_manager() { + cmd.args(extra_args); + } - cmd.status_checked() + cmd.status_checked() + } + (Err(_), _, Err(_)) => unreachable!("require_one([\"home-manager\", \"nh\"])?; was called, so either tool must be available"), + } } pub fn run_pearl(ctx: &ExecutionContext) -> Result<()> { ++++++ vendor.tar.zst ++++++ /work/SRC/openSUSE:Factory/topgrade/vendor.tar.zst /work/SRC/openSUSE:Factory/.topgrade.new.1995/vendor.tar.zst differ: char 7, line 1
