Compare commits

..

31 Commits

Author SHA1 Message Date
Thomas Schönauer
eb51be0732 10.2.3 release (#272) 2022-12-18 14:20:00 +00:00
Thomas Schönauer
56a717dcc6 Fixes dotnet if dotnet tool is not available (#229)
* Fixes dotnet if dotnet tool si not available

* dotnet: multi-lang support

* Fixes dotnet for non-english terminals
2022-12-18 14:12:36 +00:00
Thomas Schönauer
ee353ccb66 adds fish_update_completions to fish step (#270) 2022-12-18 14:11:36 +00:00
Thomas Schönauer
33cea0e5b6 10.2.3 release (#271)
10.2.3
2022-12-18 14:07:31 +00:00
Thomas Schönauer
78a491a976 Fixes rubygems on .deb distros (#268)
Fixes rubygem on systems with the .deb ruby package
2022-12-15 20:27:27 +00:00
Thomas Schönauer
9553be04e4 Fixes vcpkg when installed as root (#266) 2022-12-15 11:39:25 +00:00
Thomas Schönauer
81928f55a2 Fix notify not available (#257) 2022-12-15 11:34:18 +00:00
Mark Nefedov
4e56bf07f3 Add options to disable Yarn and Pnpm individually. (#260)
* Add options to disable Yarn and Pnpm individualy.

* cargo fmt

Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>
2022-12-14 21:42:48 +00:00
sandal
9f424f03c3 Added a step for fetching and building treesitter grammars for helix (#263) 2022-12-14 08:12:39 +00:00
Thomas Kosiewski
1e14b3bf28 Add helm (#255) (#256)
* Add `helm` (#255)

Signed-off-by: Thomas Kosiewski <thoma471@googlemail.com>

* Sorted steps alphabetically

Signed-off-by: Thomas Kosiewski <thoma471@googlemail.com>

Signed-off-by: Thomas Kosiewski <thoma471@googlemail.com>
2022-12-08 21:47:57 +00:00
Thomas Schönauer
51e7a31f48 10.2.2 (#253) 2022-12-06 19:48:46 +00:00
Thomas Schönauer
9847fd9d4d Merge branch 'master' into dev 2022-12-06 19:23:45 +00:00
Thomas Schönauer
24ef44291f 10.2.2 version bump (#252) 2022-12-06 19:22:06 +00:00
Julien ITARD
ebb0c5a6d8 Fix RubyGems step (#251)
* Bump tokio from 1.5.1 to 1.8.4 (#245)

Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.5.1 to 1.8.4.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.5.1...tokio-1.8.4)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fix RubyGems step

* Fix style

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-06 19:13:07 +00:00
Armel Soro
1dee462175 Fix misleading log message when detecting rbenv (#249) 2022-12-05 17:42:26 +00:00
Armel Soro
dc82b8b766 Fix issue with RubyGems update command (#248) 2022-12-05 13:16:03 +00:00
dependabot[bot]
73888e7669 Bump tokio from 1.5.1 to 1.8.4 (#245)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.5.1 to 1.8.4.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.5.1...tokio-1.8.4)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 21:56:52 +00:00
dependabot[bot]
46a010cc8f Bump tokio from 1.5.1 to 1.8.4 (#147)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.5.1 to 1.8.4.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.5.1...tokio-1.8.4)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>
2022-11-30 21:29:39 +00:00
Thomas Schönauer
96e4de4594 10.2.1 release (#244) 2022-11-30 21:08:15 +00:00
Thomas Schönauer
70616b2ec5 Version bump (#237) 2022-11-29 15:17:20 +00:00
Thomas Schönauer
22ab07d88e Fixes paru/yay -Pw return code error (#228) 2022-11-29 06:49:26 +00:00
Guilherme Silva
70045fca29 CI: Force color support for Rustfmt (#230)
Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>
2022-11-27 00:21:29 +01:00
Marcin Puc
f6ec6c76db Add shell completion and manpage generation (#233) 2022-11-26 19:42:35 +00:00
Jason Stelzer
37b900c56a Add garuda-update (#227) 2022-11-26 19:38:18 +00:00
Guilherme Silva
e26ec4d9e0 Fix clippy warning for DragonFly BSD (#231) 2022-11-26 17:52:14 +00:00
Rebecca Turner
b31778bdd8 Add Sudo type (#221)
* Create `Sudo` type and `SudoKind` enum

* Fix build

* reformat

* Fix choco on windows

* Fix linux

* Fix linux more

* more fix stuff hehe hoho hahaha

* more fix stuff hehe hoho hahaha

Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>
2022-11-25 22:19:32 +00:00
Thomas Schönauer
526c4c9a58 Fixes typo 2022-11-25 18:44:36 +00:00
Julien ITARD
3c1dda0c39 Add RubyGems update (#217) 2022-11-24 19:21:03 +00:00
Ruben Molina
25c5057171 Add support for juliaup (#208)
* Add support for juliaup

* Update config.rs

* Change the position for Juliaup Step.

* Update generic.rs
2022-11-24 19:17:58 +00:00
Rebecca Turner
e456155562 Add pre_sudo option (#219)
* Add `pre_sudo` option
2022-11-24 19:15:43 +00:00
Guilherme Silva
f2c7e4848e CI: Install only necessary components (#218)
* CI: Install only necessary components
2022-11-24 19:15:13 +00:00
20 changed files with 464 additions and 274 deletions

View File

@@ -23,10 +23,11 @@ jobs:
uses: dtolnay/rust-toolchain@master
with:
toolchain: '${{ env.RUST_VER }}'
targets: ${{ matrix.target }}
components: clippy, rustfmt
components: rustfmt
- name: Run cargo fmt
env:
TERM: xterm-256color
run: |
cargo fmt --all -- --check
@@ -72,8 +73,7 @@ jobs:
uses: dtolnay/rust-toolchain@master
with:
toolchain: '${{ env.RUST_VER }}'
targets: ${{ matrix.target }}
components: clippy, rustfmt
components: clippy
- name: Setup Rust Cache
uses: Swatinem/rust-cache@v2

167
Cargo.lock generated
View File

@@ -59,11 +59,11 @@ dependencies = [
[[package]]
name = "async-channel"
version = "1.7.1"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
dependencies = [
"concurrent-queue 1.2.4",
"concurrent-queue",
"event-listener",
"futures-core",
]
@@ -76,7 +76,7 @@ checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
dependencies = [
"async-lock",
"async-task",
"concurrent-queue 2.0.0",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
@@ -84,13 +84,13 @@ dependencies = [
[[package]]
name = "async-io"
version = "1.10.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794"
dependencies = [
"async-lock",
"autocfg",
"concurrent-queue 1.2.4",
"concurrent-queue",
"futures-lite",
"libc",
"log",
@@ -99,7 +99,7 @@ dependencies = [
"slab",
"socket2",
"waker-fn",
"winapi",
"windows-sys",
]
[[package]]
@@ -131,9 +131,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
[[package]]
name = "async-trait"
version = "0.1.58"
version = "0.1.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c"
checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364"
dependencies = [
"proc-macro2",
"quote",
@@ -167,7 +167,7 @@ dependencies = [
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"miniz_oxide 0.5.4",
"object",
"rustc-demangle",
]
@@ -208,12 +208,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
[[package]]
name = "cache-padded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
[[package]]
name = "cc"
version = "1.0.77"
@@ -236,7 +230,7 @@ dependencies = [
"js-sys",
"num-integer",
"num-traits",
"time 0.1.44",
"time 0.1.45",
"wasm-bindgen",
"winapi",
]
@@ -258,6 +252,15 @@ dependencies = [
"textwrap",
]
[[package]]
name = "clap_complete"
version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da92e6facd8d73c22745a5d3cbb59bdf8e46e3235c923e516527d8e81eec14a4"
dependencies = [
"clap",
]
[[package]]
name = "clap_derive"
version = "3.1.18"
@@ -280,6 +283,16 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "clap_mangen"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121b598d1b9d63d4ff3b7dae8defd88cc23e41850ee89fd2feec2e7d992e6ec8"
dependencies = [
"clap",
"roff",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
@@ -317,15 +330,6 @@ dependencies = [
"tracing-error",
]
[[package]]
name = "concurrent-queue"
version = "1.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
dependencies = [
"cache-padded",
]
[[package]]
name = "concurrent-queue"
version = "2.0.0"
@@ -375,9 +379,9 @@ dependencies = [
[[package]]
name = "cxx"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -387,9 +391,9 @@ dependencies = [
[[package]]
name = "cxx-build"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
dependencies = [
"cc",
"codespan-reporting",
@@ -402,15 +406,15 @@ dependencies = [
[[package]]
name = "cxxbridge-flags"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
[[package]]
name = "cxxbridge-macro"
version = "1.0.82"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
dependencies = [
"proc-macro2",
"quote",
@@ -565,12 +569,12 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
dependencies = [
"crc32fast",
"miniz_oxide",
"miniz_oxide 0.6.2",
]
[[package]]
@@ -717,9 +721,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "h2"
version = "0.3.12"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
dependencies = [
"bytes",
"fnv",
@@ -953,9 +957,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.137"
version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "link-cplusplus"
@@ -1046,6 +1050,15 @@ dependencies = [
"adler",
]
[[package]]
name = "miniz_oxide"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
"adler",
]
[[package]]
name = "mio"
version = "0.7.14"
@@ -1070,9 +1083,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.23.1"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
dependencies = [
"bitflags",
"cc",
@@ -1083,9 +1096,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.24.2"
version = "0.24.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc"
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
dependencies = [
"bitflags",
"cfg-if",
@@ -1261,9 +1274,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.4"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
dependencies = [
"cfg-if",
"libc",
@@ -1305,16 +1318,16 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polling"
version = "2.4.0"
version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2"
checksum = "166ca89eb77fd403230b9c156612965a81e094ec6ec3aa13663d4c8b113fa748"
dependencies = [
"autocfg",
"cfg-if",
"libc",
"log",
"wepoll-ffi",
"winapi",
"windows-sys",
]
[[package]]
@@ -1533,6 +1546,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "roff"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
[[package]]
name = "rust-ini"
version = "0.18.0"
@@ -1642,18 +1661,18 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
[[package]]
name = "serde"
version = "1.0.147"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.147"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
dependencies = [
"proc-macro2",
"quote",
@@ -1830,9 +1849,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.103"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
@@ -1931,9 +1950,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.1.44"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
@@ -1984,9 +2003,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.5.1"
version = "1.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd3b82e6e823a9ee7d7f64b08f8ac3d5f08ac988f23157194bd32af3f2f92767"
checksum = "cdc46ca74dd45faeaaf96a8fbe2406f425829705ee62100ccaa9b34a2145cff8"
dependencies = [
"autocfg",
"bytes",
@@ -2013,16 +2032,16 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.6.9"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
"tracing",
]
[[package]]
@@ -2036,11 +2055,13 @@ dependencies = [
[[package]]
name = "topgrade"
version = "10.2.0"
version = "10.2.3"
dependencies = [
"cfg-if",
"chrono",
"clap",
"clap_complete",
"clap_mangen",
"color-eyre",
"console",
"directories",
@@ -2049,7 +2070,7 @@ dependencies = [
"home",
"lazy_static",
"libc",
"nix 0.24.2",
"nix 0.24.3",
"notify-rust",
"parselnk",
"regex",
@@ -2561,7 +2582,7 @@ dependencies = [
"futures-util",
"hex",
"lazy_static",
"nix 0.23.1",
"nix 0.23.2",
"once_cell",
"ordered-stream",
"rand",
@@ -2592,9 +2613,9 @@ dependencies = [
[[package]]
name = "zbus_names"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d69bb79b44e1901ed8b217e485d0f01991aec574479b68cb03415f142bc7ae67"
checksum = "6c737644108627748a660d038974160e0cbb62605536091bdfa28fd7f64d43c8"
dependencies = [
"serde",
"static_assertions",
@@ -2616,9 +2637,9 @@ dependencies = [
[[package]]
name = "zvariant"
version = "3.8.0"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c817f416f05fcbc833902f1e6064b72b1778573978cfeac54731451ccc9e207"
checksum = "56f8c89c183461e11867ded456db252eae90874bc6769b7adbea464caa777e51"
dependencies = [
"byteorder",
"enumflags2",
@@ -2630,9 +2651,9 @@ dependencies = [
[[package]]
name = "zvariant_derive"
version = "3.8.0"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdd24fffd02794a76eb10109de463444064c88f5adb9e9d1a78488adc332bfef"
checksum = "155247a5d1ab55e335421c104ccd95d64f17cebbd02f50cdbc1c33385f9c4d81"
dependencies = [
"proc-macro-crate",
"proc-macro2",

View File

@@ -6,7 +6,7 @@ keywords = ["upgrade", "update"]
license = "GPL-3.0"
# license-file = "LICENSE"
repository = "https://github.com/topgrade-rs/topgrade"
version = "10.2.0"
version = "10.2.3"
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
exclude = ["doc/screenshot.gif"]
edition = "2021"
@@ -28,6 +28,8 @@ toml = "0.5"
which_crate = { version = "~4.1", package = "which" }
shellexpand = "~2.1"
clap = { version = "~3.1", features = ["cargo", "derive"] }
clap_complete = "~3.1"
clap_mangen = "~0.1"
walkdir = "~2.3"
console = "~0.15"
lazy_static = "~1.4"
@@ -37,14 +39,14 @@ strum = { version = "~0.24", features = ["derive"] }
thiserror = "~1.0"
tempfile = "~3.2"
cfg-if = "~1.0"
tokio = { version = "~1.5", features = ["process", "rt-multi-thread"] }
tokio = { version = "~1.8", features = ["process", "rt-multi-thread"] }
futures = "~0.3"
regex = "~1.5"
semver = "~1.0"
shell-words = "~1.1"
color-eyre = "0.6.2"
tracing = { version = "0.1.37", features = ["attributes", "log"] }
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "time"] }
color-eyre = "~0.6"
tracing = { version = "~0.1", features = ["attributes", "log"] }
tracing-subscriber = { version = "~0.3", features = ["env-filter", "time"] }
[target.'cfg(target_os = "macos")'.dependencies]
notify-rust = "~4.5"

View File

@@ -13,6 +13,10 @@
# Do not ask to retry failed steps (default: false)
#no_retry = true
# Run `sudo -v` to cache credentials at the start of the run; this avoids a
# blocking password prompt in the middle of a possibly-unattended run.
#pre_sudo = false
# Run inside tmux
#run_in_tmux = true

View File

@@ -6,6 +6,7 @@ use std::process::Command;
use std::{env, fs};
use clap::{ArgEnum, Parser};
use clap_complete::Shell;
use color_eyre::eyre;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
@@ -72,10 +73,10 @@ type Commands = BTreeMap<String, String>;
pub enum Step {
Asdf,
Atom,
Bin,
BrewCask,
BrewFormula,
Bun,
Bin,
Cargo,
Chezmoi,
Chocolatey,
@@ -86,8 +87,8 @@ pub enum Step {
Containers,
CustomCommands,
DebGet,
Distrobox,
Deno,
Distrobox,
Dotnet,
Emacs,
Firmware,
@@ -99,14 +100,17 @@ pub enum Step {
Ghcup,
GithubCliExtensions,
GitRepos,
GnomeShellExtensions,
Go,
Guix,
Haxelib,
GnomeShellExtensions,
Helm,
HomeManager,
Jetpack,
Julia,
Juliaup,
Kakoune,
Helix,
Krew,
Macports,
Mas,
@@ -118,10 +122,11 @@ pub enum Step {
Pacdef,
Pacstall,
Pearl,
Pipx,
Pip3,
Pipx,
Pkg,
Pkgin,
Pnpm,
Powershell,
Protonup,
Raco,
@@ -129,6 +134,7 @@ pub enum Step {
Remotes,
Restarts,
Rtcl,
RubyGems,
Rustup,
Scoop,
Sdkman,
@@ -149,6 +155,7 @@ pub enum Step {
Winget,
Wsl,
Yadm,
Yarn,
}
#[derive(Deserialize, Default, Debug)]
@@ -223,6 +230,7 @@ pub struct Brew {
#[derive(Debug, Deserialize, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum ArchPackageManager {
GarudaUpdate,
Autodetect,
Trizen,
Paru,
@@ -269,6 +277,7 @@ pub struct Vim {
#[serde(deny_unknown_fields)]
/// Configuration file
pub struct ConfigFile {
pre_sudo: Option<bool>,
pre_commands: Option<Commands>,
post_commands: Option<Commands>,
commands: Option<Commands>,
@@ -485,6 +494,14 @@ pub struct CommandLineArgs {
/// See: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/struct.EnvFilter.html
#[clap(long, default_value = "info")]
pub log_filter: String,
/// Print completion script for the given shell and exit
#[clap(long, arg_enum, hide = true)]
pub gen_completion: Option<Shell>,
/// Print roff manpage and exit
#[clap(long, hide = true)]
pub gen_manpage: bool,
}
impl CommandLineArgs {
@@ -947,6 +964,12 @@ impl Config {
.unwrap_or(false)
}
/// If `true`, `sudo` should be called after `pre_commands` in order to elevate at the
/// start of the session (and not in the middle).
pub fn pre_sudo(&self) -> bool {
self.config_file.pre_sudo.unwrap_or(false)
}
#[cfg(target_os = "linux")]
pub fn npm_use_sudo(&self) -> bool {
self.config_file

View File

@@ -1,16 +1,17 @@
#![allow(dead_code)]
use crate::executor::RunType;
use crate::git::Git;
use crate::sudo::Sudo;
use crate::utils::require_option;
use crate::{config::Config, executor::Executor};
use color_eyre::eyre::Result;
use directories::BaseDirs;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::sync::Mutex;
pub struct ExecutionContext<'a> {
run_type: RunType,
sudo: &'a Option<PathBuf>,
sudo: Option<Sudo>,
git: &'a Git,
config: &'a Config,
base_dirs: &'a BaseDirs,
@@ -23,7 +24,7 @@ pub struct ExecutionContext<'a> {
impl<'a> ExecutionContext<'a> {
pub fn new(
run_type: RunType,
sudo: &'a Option<PathBuf>,
sudo: Option<Sudo>,
git: &'a Git,
config: &'a Config,
base_dirs: &'a BaseDirs,
@@ -40,18 +41,7 @@ impl<'a> ExecutionContext<'a> {
pub fn execute_elevated(&self, command: &Path, interactive: bool) -> Result<Executor> {
let sudo = require_option(self.sudo.clone(), "Sudo is required for this operation".into())?;
let mut cmd = self.run_type.execute(&sudo);
if sudo.ends_with("sudo") {
cmd.arg("--preserve-env=DIFFPROG");
}
if interactive {
cmd.arg("-i");
}
cmd.arg(command);
Ok(cmd)
Ok(sudo.execute_elevated(self, command, interactive))
}
pub fn run_type(&self) -> RunType {
@@ -62,8 +52,8 @@ impl<'a> ExecutionContext<'a> {
self.git
}
pub fn sudo(&self) -> &Option<PathBuf> {
self.sudo
pub fn sudo(&self) -> &Option<Sudo> {
&self.sudo
}
pub fn config(&self) -> &Config {

View File

@@ -176,7 +176,7 @@ impl Executor {
/// An extension of `status_checked` that allows you to set a sequence of codes
/// that can indicate success of a script
#[cfg_attr(windows, allow(dead_code))]
#[allow(dead_code)]
pub fn status_checked_with_codes(&mut self, codes: &[i32]) -> Result<()> {
match self {
Executor::Wet(c) => c.status_checked_with(|status| {

View File

@@ -4,6 +4,7 @@ use std::env;
use std::io;
use std::process::exit;
use clap::CommandFactory;
use clap::{crate_version, Parser};
use color_eyre::eyre::Context;
use color_eyre::eyre::{eyre, Result};
@@ -30,6 +31,7 @@ mod self_renamer;
#[cfg(feature = "self-update")]
mod self_update;
mod steps;
mod sudo;
mod terminal;
mod utils;
@@ -41,6 +43,18 @@ fn run() -> Result<()> {
let opt = CommandLineArgs::parse();
if let Some(shell) = opt.gen_completion {
let cmd = &mut CommandLineArgs::command();
clap_complete::generate(shell, cmd, clap::crate_name!(), &mut std::io::stdout());
return Ok(());
}
if opt.gen_manpage {
let man = clap_mangen::Man::new(CommandLineArgs::command());
man.render(&mut std::io::stdout())?;
return Ok(());
}
install_tracing(&opt.tracing_filter_directives())?;
for env in opt.env_variables() {
@@ -82,10 +96,10 @@ fn run() -> Result<()> {
let git = git::Git::new();
let mut git_repos = git::Repositories::new(&git);
let sudo = utils::sudo();
let sudo = sudo::Sudo::detect();
let run_type = executor::RunType::new(config.dry_run());
let ctx = execution_context::ExecutionContext::new(run_type, &sudo, &git, &config, &base_dirs);
let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config, &base_dirs);
let mut runner = runner::Runner::new(&ctx);
@@ -119,6 +133,12 @@ fn run() -> Result<()> {
}
}
if config.pre_sudo() {
if let Some(sudo) = ctx.sudo() {
sudo.elevate(&ctx)?;
}
}
let powershell = powershell::Powershell::new();
let should_run_powershell = powershell.profile().is_some() && config.should_run(Step::Powershell);
@@ -197,17 +217,17 @@ fn run() -> Result<()> {
#[cfg(target_os = "dragonfly")]
runner.execute(Step::Pkg, "DragonFly BSD Packages", || {
dragonfly::upgrade_packages(sudo.as_ref(), run_type)
dragonfly::upgrade_packages(ctx.sudo().as_ref(), run_type)
})?;
#[cfg(target_os = "freebsd")]
runner.execute(Step::Pkg, "FreeBSD Packages", || {
freebsd::upgrade_packages(&ctx, sudo.as_ref(), run_type)
freebsd::upgrade_packages(&ctx, ctx.sudo().as_ref(), run_type)
})?;
#[cfg(target_os = "openbsd")]
runner.execute(Step::Pkg, "OpenBSD Packages", || {
openbsd::upgrade_packages(sudo.as_ref(), run_type)
openbsd::upgrade_packages(ctx.sudo().as_ref(), run_type)
})?;
#[cfg(target_os = "android")]
@@ -319,6 +339,7 @@ fn run() -> Result<()> {
runner.execute(Step::Atom, "apm", || generic::run_apm(run_type))?;
runner.execute(Step::Fossil, "fossil", || generic::run_fossil(run_type))?;
runner.execute(Step::Rustup, "rustup", || generic::run_rustup(&base_dirs, run_type))?;
runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(&base_dirs, run_type))?;
runner.execute(Step::Dotnet, ".NET", || generic::run_dotnet_upgrade(&ctx))?;
runner.execute(Step::Choosenim, "choosenim", || generic::run_choosenim(&ctx))?;
runner.execute(Step::Cargo, "cargo", || generic::run_cargo_update(&ctx))?;
@@ -327,7 +348,7 @@ fn run() -> Result<()> {
runner.execute(Step::Go, "gup", || go::run_go_gup(run_type))?;
runner.execute(Step::Emacs, "Emacs", || emacs.upgrade(&ctx))?;
runner.execute(Step::Opam, "opam", || generic::run_opam_update(&ctx))?;
runner.execute(Step::Vcpkg, "vcpkg", || generic::run_vcpkg_update(run_type))?;
runner.execute(Step::Vcpkg, "vcpkg", || generic::run_vcpkg_update(&ctx))?;
runner.execute(Step::Pipx, "pipx", || generic::run_pipx_update(run_type))?;
runner.execute(Step::Conda, "conda", || generic::run_conda_update(&ctx))?;
runner.execute(Step::Pip3, "pip3", || generic::run_pip3_update(run_type))?;
@@ -346,14 +367,19 @@ fn run() -> Result<()> {
runner.execute(Step::Vim, "The Ultimate vimrc", || vim::upgrade_ultimate_vimrc(&ctx))?;
runner.execute(Step::Vim, "voom", || vim::run_voom(&base_dirs, run_type))?;
runner.execute(Step::Kakoune, "Kakoune", || kakoune::upgrade_kak_plug(&ctx))?;
runner.execute(Step::Helix, "helix", || generic::run_helix_grammars(&ctx))?;
runner.execute(Step::Node, "npm", || node::run_npm_upgrade(&ctx))?;
runner.execute(Step::Node, "yarn", || node::run_yarn_upgrade(&ctx))?;
runner.execute(Step::Node, "pnpm", || node::run_pnpm_upgrade(&ctx))?;
runner.execute(Step::Yarn, "yarn", || node::run_yarn_upgrade(&ctx))?;
runner.execute(Step::Pnpm, "pnpm", || node::run_pnpm_upgrade(&ctx))?;
runner.execute(Step::Containers, "Containers", || containers::run_containers(&ctx))?;
runner.execute(Step::Deno, "deno", || node::deno_upgrade(&ctx))?;
runner.execute(Step::Composer, "composer", || generic::run_composer_update(&ctx))?;
runner.execute(Step::Krew, "krew", || generic::run_krew_upgrade(run_type))?;
runner.execute(Step::Helm, "helm", || generic::run_helm_repo_update(run_type))?;
runner.execute(Step::Gem, "gem", || generic::run_gem(&base_dirs, run_type))?;
runner.execute(Step::RubyGems, "rubygems", || {
generic::run_rubygems(&base_dirs, run_type)
})?;
runner.execute(Step::Julia, "julia", || generic::update_julia_packages(&ctx))?;
runner.execute(Step::Haxelib, "haxelib", || generic::run_haxelib_update(&ctx))?;
runner.execute(Step::Sheldon, "sheldon", || generic::run_sheldon(&ctx))?;
@@ -374,7 +400,7 @@ fn run() -> Result<()> {
runner.execute(Step::DebGet, "deb-get", || linux::run_deb_get(&ctx))?;
runner.execute(Step::Toolbx, "toolbx", || toolbx::run_toolbx(&ctx))?;
runner.execute(Step::Flatpak, "Flatpak", || linux::flatpak_update(&ctx))?;
runner.execute(Step::Snap, "snap", || linux::run_snap(sudo.as_ref(), run_type))?;
runner.execute(Step::Snap, "snap", || linux::run_snap(ctx.sudo().as_ref(), run_type))?;
runner.execute(Step::Pacstall, "pacstall", || linux::run_pacstall(&ctx))?;
runner.execute(Step::Pacdef, "pacdef", || linux::run_pacdef(&ctx))?;
runner.execute(Step::Protonup, "protonup", || linux::run_protonup_update(&ctx))?;
@@ -394,11 +420,11 @@ fn run() -> Result<()> {
#[cfg(target_os = "linux")]
{
runner.execute(Step::System, "pihole", || {
linux::run_pihole_update(sudo.as_ref(), run_type)
linux::run_pihole_update(ctx.sudo().as_ref(), run_type)
})?;
runner.execute(Step::Firmware, "Firmware upgrades", || linux::run_fwupdmgr(&ctx))?;
runner.execute(Step::Restarts, "Restarts", || {
linux::run_needrestart(sudo.as_ref(), run_type)
linux::run_needrestart(ctx.sudo().as_ref(), run_type)
})?;
}
@@ -411,12 +437,12 @@ fn run() -> Result<()> {
#[cfg(target_os = "freebsd")]
runner.execute(Step::System, "FreeBSD Upgrade", || {
freebsd::upgrade_freebsd(sudo.as_ref(), run_type)
freebsd::upgrade_freebsd(ctx.sudo().as_ref(), run_type)
})?;
#[cfg(target_os = "openbsd")]
runner.execute(Step::System, "OpenBSD Upgrade", || {
openbsd::upgrade_openbsd(sudo.as_ref(), run_type)
openbsd::upgrade_openbsd(ctx.sudo().as_ref(), run_type)
})?;
#[cfg(windows)]
@@ -448,10 +474,10 @@ fn run() -> Result<()> {
}
#[cfg(target_os = "freebsd")]
freebsd::audit_packages(&sudo).ok();
freebsd::audit_packages(ctx.sudo().as_ref()).ok();
#[cfg(target_os = "dragonfly")]
dragonfly::audit_packages(&sudo).ok();
dragonfly::audit_packages(ctx.sudo().as_ref()).ok();
}
let mut post_command_failed = false;

View File

@@ -70,7 +70,7 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let gem = utils::require("gem")?;
base_dirs.home_dir().join(".gem").require()?;
print_separator("RubyGems");
print_separator("Gems");
let mut command = run_type.execute(gem);
command.arg("update");
@@ -83,6 +83,19 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
command.status_checked()
}
pub fn run_rubygems(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let gem = utils::require("gem")?;
base_dirs.home_dir().join(".gem").require()?;
print_separator("RubyGems");
if !std::path::Path::new("/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb").exists() {
run_type.execute(gem).args(["update", "--system"]).status_checked()
} else {
Ok(())
}
}
pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
let haxelib = utils::require("haxelib")?;
@@ -175,6 +188,18 @@ pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
run_type.execute(&rustup).arg("update").status_checked()
}
pub fn run_juliaup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
let juliaup = utils::require("juliaup")?;
print_separator("juliaup");
if juliaup.canonicalize()?.is_descendant_of(base_dirs.home_dir()) {
run_type.execute(&juliaup).args(["self", "update"]).status_checked()?;
}
run_type.execute(&juliaup).arg("update").status_checked()
}
pub fn run_choosenim(ctx: &ExecutionContext) -> Result<()> {
let choosenim = utils::require("choosenim")?;
@@ -239,14 +264,27 @@ pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
Ok(())
}
pub fn run_vcpkg_update(run_type: RunType) -> Result<()> {
pub fn run_vcpkg_update(ctx: &ExecutionContext) -> Result<()> {
let vcpkg = utils::require("vcpkg")?;
print_separator("vcpkg");
run_type
.execute(vcpkg)
.args(["upgrade", "--no-dry-run"])
.status_checked()
#[cfg(unix)]
let is_root_install = !&vcpkg.starts_with("/home");
#[cfg(not(unix))]
let is_root_install = false;
let mut command = if is_root_install {
ctx.run_type().execute(&vcpkg)
} else {
let mut c = ctx
.run_type()
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?);
c.arg(&vcpkg);
c
};
command.args(["upgrade", "--no-dry-run"]).status_checked()
}
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
@@ -450,30 +488,53 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
let dotnet = utils::require("dotnet")?;
let output = Command::new(dotnet)
.args(["tool", "list", "--global"])
.output_checked_utf8()?;
let dotnet_help_output = ctx.run_type().execute(&dotnet).arg("-h").output().err().unwrap();
if !output.stdout.starts_with("Package Id") {
return Err(SkipStep(String::from("dotnet did not output packages")).into());
if dotnet_help_output.to_string().contains("tool") {
let output = Command::new(dotnet)
.args(["tool", "list", "--global"])
.output_checked_utf8()?;
if !output.stdout.starts_with("Package Id") {
return Err(SkipStep(String::from("dotnet did not output packages")).into());
}
let mut packages = output.stdout.lines().skip(2).filter(|line| !line.is_empty()).peekable();
if packages.peek().is_none() {
return Err(SkipStep(String::from("No dotnet global tools installed")).into());
}
print_separator(".NET");
for package in packages {
let package_name = package.split_whitespace().next().unwrap();
ctx.run_type()
.execute("dotnet")
.args(["tool", "update", package_name, "--global"])
.status_checked()
.with_context(|| format!("Failed to update .NET package {package_name}"))?;
}
}
Ok(())
}
let mut packages = output.stdout.lines().skip(2).filter(|line| !line.is_empty()).peekable();
pub fn run_helix_grammars(ctx: &ExecutionContext) -> Result<()> {
utils::require("helix")?;
if packages.peek().is_none() {
return Err(SkipStep(String::from("No dotnet global tools installed")).into());
}
print_separator("Helix");
print_separator(".NET");
ctx.run_type()
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?)
.args(["helix", "--grammar", "fetch"])
.status_checked()
.with_context(|| "Failed to download helix grammars!")?;
for package in packages {
let package_name = package.split_whitespace().next().unwrap();
ctx.run_type()
.execute("dotnet")
.args(["tool", "update", package_name, "--global"])
.status_checked()
.with_context(|| format!("Failed to update .NET package {package_name}"))?;
}
ctx.run_type()
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?)
.args(["helix", "--grammar", "build"])
.status_checked()
.with_context(|| "Failed to build helix grammars!")?;
Ok(())
}
@@ -525,3 +586,10 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
.args(["-e", "using Pkg; Pkg.update()"])
.status_checked()
}
pub fn run_helm_repo_update(run_type: RunType) -> Result<()> {
let helm = utils::require("helm")?;
print_separator("Helm");
run_type.execute(helm).arg("repo").arg("update").status_checked()
}

View File

@@ -12,9 +12,7 @@ use semver::Version;
use tracing::debug;
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::terminal::print_separator;
use crate::utils::sudo;
use crate::utils::{require, PathExt};
use crate::{error::SkipStep, execution_context::ExecutionContext};
@@ -90,14 +88,17 @@ impl NPM {
Version::parse(&version_str?).map_err(|err| err.into())
}
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
fn upgrade(&self, ctx: &ExecutionContext, use_sudo: bool) -> Result<()> {
let args = ["update", self.global_location_arg()];
if use_sudo {
let sudo_option = sudo();
let sudo = require_option(sudo_option, String::from("sudo is not installed"))?;
run_type.execute(sudo).arg(&self.command).args(args).status_checked()?;
let sudo = require_option(ctx.sudo().clone(), String::from("sudo is not installed"))?;
ctx.run_type()
.execute(sudo)
.arg(&self.command)
.args(args)
.status_checked()?;
} else {
run_type.execute(&self.command).args(args).status_checked()?;
ctx.run_type().execute(&self.command).args(args).status_checked()?;
}
Ok(())
@@ -150,17 +151,18 @@ impl Yarn {
.map(|s| PathBuf::from(s.stdout.trim()))
}
fn upgrade(&self, run_type: RunType, use_sudo: bool) -> Result<()> {
fn upgrade(&self, ctx: &ExecutionContext, use_sudo: bool) -> Result<()> {
let args = ["global", "upgrade"];
if use_sudo {
run_type
.execute("sudo")
let sudo = require_option(ctx.sudo().clone(), String::from("sudo is not installed"))?;
ctx.run_type()
.execute(sudo)
.arg(self.yarn.as_ref().unwrap_or(&self.command))
.args(args)
.status_checked()?;
} else {
run_type.execute(&self.command).args(args).status_checked()?;
ctx.run_type().execute(&self.command).args(args).status_checked()?;
}
Ok(())
@@ -215,12 +217,12 @@ pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
#[cfg(target_os = "linux")]
{
npm.upgrade(ctx.run_type(), should_use_sudo(&npm, ctx)?)
npm.upgrade(ctx, should_use_sudo(&npm, ctx)?)
}
#[cfg(not(target_os = "linux"))]
{
npm.upgrade(ctx.run_type(), false)
npm.upgrade(ctx, false)
}
}
@@ -231,12 +233,12 @@ pub fn run_pnpm_upgrade(ctx: &ExecutionContext) -> Result<()> {
#[cfg(target_os = "linux")]
{
pnpm.upgrade(ctx.run_type(), should_use_sudo(&pnpm, ctx)?)
pnpm.upgrade(ctx, should_use_sudo(&pnpm, ctx)?)
}
#[cfg(not(target_os = "linux"))]
{
pnpm.upgrade(ctx.run_type(), false)
pnpm.upgrade(ctx, false)
}
}
@@ -252,12 +254,12 @@ pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> {
#[cfg(target_os = "linux")]
{
yarn.upgrade(ctx.run_type(), should_use_sudo_yarn(&yarn, ctx)?)
yarn.upgrade(ctx, should_use_sudo_yarn(&yarn, ctx)?)
}
#[cfg(not(target_os = "linux"))]
{
yarn.upgrade(ctx.run_type(), false)
yarn.upgrade(ctx, false)
}
}

View File

@@ -1,7 +1,6 @@
use std::env::var_os;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::process::Command;
use color_eyre::eyre;
use color_eyre::eyre::Result;
@@ -10,6 +9,7 @@ use walkdir::WalkDir;
use crate::command::CommandExt;
use crate::error::TopgradeError;
use crate::execution_context::ExecutionContext;
use crate::sudo::Sudo;
use crate::utils::which;
use crate::{config, Step};
@@ -31,7 +31,10 @@ pub struct YayParu {
impl ArchPackageManager for YayParu {
fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
if ctx.config().show_arch_news() {
Command::new(&self.executable).arg("-Pw").status_checked()?;
ctx.run_type()
.execute(&self.executable)
.arg("-Pw")
.status_checked_with_codes(&[1, 0])?;
}
let mut command = ctx.run_type().execute(&self.executable);
@@ -70,6 +73,27 @@ impl YayParu {
}
}
pub struct GarudaUpdate {
executable: PathBuf,
}
impl ArchPackageManager for GarudaUpdate {
fn upgrade(&self, ctx: &ExecutionContext) -> Result<()> {
let mut command = ctx.run_type().execute(&self.executable);
command.env("PATH", get_execution_path());
command.status_checked()?;
Ok(())
}
}
impl GarudaUpdate {
fn get() -> Option<Self> {
Some(Self {
executable: which("garuda-update")?,
})
}
}
pub struct Trizen {
executable: PathBuf,
}
@@ -110,7 +134,7 @@ impl Trizen {
}
pub struct Pacman {
sudo: PathBuf,
sudo: Sudo,
executable: PathBuf,
}
@@ -229,7 +253,7 @@ impl ArchPackageManager for Pamac {
pub struct Aura {
executable: PathBuf,
sudo: PathBuf,
sudo: Sudo,
}
impl Aura {
@@ -282,14 +306,16 @@ pub fn get_arch_package_manager(ctx: &ExecutionContext) -> Option<Box<dyn ArchPa
let pacman = which("powerpill").unwrap_or_else(|| PathBuf::from("pacman"));
match ctx.config().arch_package_manager() {
config::ArchPackageManager::Autodetect => YayParu::get("paru", &pacman)
config::ArchPackageManager::Autodetect => GarudaUpdate::get()
.map(box_package_manager)
.or_else(|| YayParu::get("paru", &pacman).map(box_package_manager))
.or_else(|| YayParu::get("yay", &pacman).map(box_package_manager))
.or_else(|| Trizen::get().map(box_package_manager))
.or_else(|| Pikaur::get().map(box_package_manager))
.or_else(|| Pamac::get().map(box_package_manager))
.or_else(|| Pacman::get(ctx).map(box_package_manager))
.or_else(|| Aura::get(ctx).map(box_package_manager)),
config::ArchPackageManager::GarudaUpdate => GarudaUpdate::get().map(box_package_manager),
config::ArchPackageManager::Trizen => Trizen::get().map(box_package_manager),
config::ArchPackageManager::Paru => YayParu::get("paru", &pacman).map(box_package_manager),
config::ArchPackageManager::Yay => YayParu::get("yay", &pacman).map(box_package_manager),

View File

@@ -1,12 +1,12 @@
use crate::command::CommandExt;
use crate::executor::RunType;
use crate::sudo::Sudo;
use crate::terminal::print_separator;
use crate::utils::require_option;
use color_eyre::eyre::Result;
use std::path::PathBuf;
use std::process::Command;
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn upgrade_packages(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("DragonFly BSD Packages");
run_type
@@ -15,7 +15,7 @@ pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()>
.status_checked()
}
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
pub fn audit_packages(sudo: Option<&Sudo>) -> Result<()> {
if let Some(sudo) = sudo {
println!();
Command::new(sudo)

View File

@@ -1,14 +1,14 @@
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::sudo::Sudo;
use crate::terminal::print_separator;
use crate::utils::require_option;
use crate::Step;
use color_eyre::eyre::Result;
use std::path::PathBuf;
use std::process::Command;
pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn upgrade_freebsd(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("FreeBSD Update");
run_type
@@ -17,7 +17,7 @@ pub fn upgrade_freebsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()>
.status_checked()
}
pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("No sudo detected"))?;
print_separator("FreeBSD Packages");
@@ -30,7 +30,7 @@ pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&PathBuf>, run_type
command.status_checked()
}
pub fn audit_packages(sudo: &Option<PathBuf>) -> Result<()> {
pub fn audit_packages(sudo: Option<&Sudo>) -> Result<()> {
if let Some(sudo) = sudo {
println!();
Command::new(sudo)

View File

@@ -10,6 +10,7 @@ use crate::error::{SkipStep, TopgradeError};
use crate::execution_context::ExecutionContext;
use crate::executor::RunType;
use crate::steps::os::archlinux;
use crate::sudo::Sudo;
use crate::terminal::{print_separator, print_warning};
use crate::utils::{require, require_option, which, PathExt};
use crate::Step;
@@ -498,7 +499,7 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
Ok(())
}
pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn run_needrestart(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
let needrestart = require("needrestart")?;
let distribution = Distribution::detect()?;
@@ -603,7 +604,7 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
Ok(())
}
pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn run_snap(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
let snap = require("snap")?;
@@ -615,7 +616,7 @@ pub fn run_snap(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
run_type.execute(sudo).arg(snap).arg("refresh").status_checked()
}
pub fn run_pihole_update(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
pub fn run_pihole_update(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
let pihole = require("pihole")?;
Path::new("/opt/pihole/update.sh").require()?;

View File

@@ -102,6 +102,12 @@ pub fn run_fisher(run_type: RunType) -> Result<()> {
.and_then(|output| Path::new(&output.stdout.trim()).require().map(|_| ()))
.map_err(|err| SkipStep(format!("`fish_plugins` path doesn't exist: {err}")))?;
Command::new(&fish)
.args(["-c", "fish_update_completions"])
.output_checked_utf8()
.map(|_| ())
.map_err(|_| SkipStep("`fish_update_completions` is not available".to_owned()))?;
print_separator("Fisher");
let version_str = run_type

View File

@@ -19,17 +19,16 @@ pub fn run_chocolatey(ctx: &ExecutionContext) -> Result<()> {
print_separator("Chocolatey");
let mut cmd = &choco;
let mut args = vec!["upgrade", "all"];
let mut command = match ctx.sudo() {
Some(sudo) => {
let mut command = ctx.run_type().execute(sudo);
command.arg(choco);
command
}
None => ctx.run_type().execute(choco),
};
if let Some(sudo) = ctx.sudo() {
cmd = sudo;
args.insert(0, "choco");
}
let mut command = ctx.run_type().execute(cmd);
command.args(&args);
command.args(["upgrade", "all"]);
if yes {
command.arg("--yes");

108
src/sudo.rs Normal file
View File

@@ -0,0 +1,108 @@
use std::ffi::OsStr;
use std::path::Path;
use std::path::PathBuf;
use color_eyre::eyre::Context;
use color_eyre::eyre::Result;
use crate::command::CommandExt;
use crate::execution_context::ExecutionContext;
use crate::executor::Executor;
use crate::terminal::print_separator;
use crate::utils::which;
#[derive(Clone, Debug)]
pub struct Sudo {
/// The path to the `sudo` binary.
path: PathBuf,
/// The type of program being used as `sudo`.
kind: SudoKind,
}
impl Sudo {
/// Get the `sudo` binary for this platform.
pub fn detect() -> Option<Self> {
which("doas")
.map(|p| (p, SudoKind::Doas))
.or_else(|| which("sudo").map(|p| (p, SudoKind::Sudo)))
.or_else(|| which("gsudo").map(|p| (p, SudoKind::Gsudo)))
.or_else(|| which("pkexec").map(|p| (p, SudoKind::Pkexec)))
.map(|(path, kind)| Self { path, kind })
}
/// Elevate permissions with `sudo`.
///
/// This helps prevent blocking `sudo` prompts from stopping the run in the middle of a
/// step.
///
/// See: https://github.com/topgrade-rs/topgrade/issues/205
pub fn elevate(&self, ctx: &ExecutionContext) -> Result<()> {
print_separator("Sudo");
let mut cmd = ctx.run_type().execute(self);
match self.kind {
SudoKind::Doas => {
// `doas` doesn't have anything like `sudo -v` to cache credentials,
// so we just execute a dummy `echo` command so we have something
// unobtrusive to run.
// See: https://man.openbsd.org/doas
cmd.arg("echo");
}
SudoKind::Sudo => {
// From `man sudo` on macOS:
// -v, --validate
// Update the user's cached credentials, authenticating the user
// if necessary. For the sudoers plugin, this extends the sudo
// timeout for another 5 minutes by default, but does not run a
// command. Not all security policies support cached credentials.
cmd.arg("-v");
}
SudoKind::Gsudo => {
// Shows current user, cache and console status.
// See: https://gerardog.github.io/gsudo/docs/usage
cmd.arg("status");
}
SudoKind::Pkexec => {
// I don't think this does anything; `pkexec` usually asks for
// authentication every time, although it can be configured
// differently.
//
// See the note for `doas` above.
//
// See: https://linux.die.net/man/1/pkexec
cmd.arg("echo");
}
}
cmd.status_checked().wrap_err("Failed to elevate permissions")
}
/// Execute a command with `sudo`.
pub fn execute_elevated(&self, ctx: &ExecutionContext, command: &Path, interactive: bool) -> Executor {
let mut cmd = ctx.run_type().execute(self);
if let SudoKind::Sudo = self.kind {
cmd.arg("--preserve-env=DIFFPROG");
}
if interactive {
cmd.arg("-i");
}
cmd.arg(command);
cmd
}
}
#[derive(Clone, Copy, Debug)]
enum SudoKind {
Doas,
Sudo,
Gsudo,
Pkexec,
}
impl AsRef<OsStr> for Sudo {
fn as_ref(&self) -> &OsStr {
self.path.as_ref()
}
}

View File

@@ -21,8 +21,9 @@ use which_crate::which;
use crate::command::CommandExt;
use crate::report::StepResult;
#[cfg(target_os = "linux")]
use crate::terminal;
#[cfg(target_os = "linux")]
use crate::utils::which;
lazy_static! {
static ref TERMINAL: Mutex<Terminal> = Mutex::new(Terminal::new());
}
@@ -105,7 +106,7 @@ impl Terminal {
command.args(["-a", "Topgrade", "Topgrade"]);
command.arg(message.as_ref());
if let Err(err) = command.output_checked() {
tracing::error!("{err:?}");
terminal::print_warning("Senfing notification failed with {err:?}");
}
}
}

View File

@@ -67,13 +67,6 @@ pub fn which<T: AsRef<OsStr> + Debug>(binary_name: T) -> Option<PathBuf> {
}
}
pub fn sudo() -> Option<PathBuf> {
which("doas")
.or_else(|| which("sudo"))
.or_else(|| which("gsudo"))
.or_else(|| which("pkexec"))
}
pub fn editor() -> Vec<String> {
env::var("EDITOR")
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))

View File

@@ -1,80 +0,0 @@
.hy
.TH "topgrade" "8"
.SH NAME
.PP
Topgrade \- Upgrade everything
.SH SYNOPSIS
.PP
topgrade [\fIoptions\f[]]
.SH DESCRIPTION
.PP
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, \fBTopgrade\fR detects which tools you use and runs the appropriate commands to update them.
.SH OPTIONS
.TP
.B \-\-only <only>
Run only specific steps
.RS
.RE
.TP
.B \-\-disable <disable>
Disable specific steps
.RS
.RE
.TP
.B \-c, \-\-cleanup
Cleanup temporary or old files
.RS
.RE
.TP
.B \-n, \-\-dry\-run
List the commands that would be run
.RS
.RE
.TP
.B \-\-edit\-config
Edit the configuration file
.RS
.RE
.TP
.B \-h, \-\-help
Print help information
.RS
.RE
.TP
.B \-k, \-\-keep
Prompt for a key before exiting
.RS
.RE
.TP
.B \-\-no\-retry
Do not ask to retry failed steps
.RS
.RE
.TP
.B \-t, \-\-tmux
Run inside tmux
.RS
.RE
.TP
.B \-V, \-\-version
Print version information
.RS
.RE
.TP
.B \-v, \-\-verbose
Output logs
.RS
.RE
.B \-y, \-\-yes
Skip package manager's prompts (experimental)
.SH ARGUMENT FORMAT
Options can be given in any order.
A list of steps must be provided as a list of separate arguments, i.e. 'topgrade --only system shell'.
.SH BUGS
For a list of bugs see <\fIhttps://github.com/r-darwish/topgrade/issues\fR>.
.SH AUTHOR
\fBTopgrade\fR is maintained by Roey Dror (\[aq]r\-darwish\[aq]) and many other contributors.
You can view the full list at
<\fIhttps://github.com/r-darwish/topgrade/graphs/contributors\fR>