Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b974938a33 | ||
|
|
06cb88a1a1 | ||
|
|
a6195d284c | ||
|
|
5b8850e8a3 | ||
|
|
57546a07fc | ||
|
|
d7709490ce | ||
|
|
3e6c6e513b | ||
|
|
30858780cf | ||
|
|
a7ddf4575a | ||
|
|
470231c9d1 | ||
|
|
282e336ac4 | ||
|
|
658829e4ff | ||
|
|
a0ff565220 | ||
|
|
7e48c5dedc | ||
|
|
03436b7f8f | ||
|
|
3f5eedb83d | ||
|
|
234ad4bdd7 | ||
|
|
c7923393be | ||
|
|
d4548b2f9a | ||
|
|
f6e8af186c | ||
|
|
58153635da | ||
|
|
5358509825 | ||
|
|
1ab0232d96 | ||
|
|
66860f1848 | ||
|
|
625f823f46 | ||
|
|
6263ab7e10 | ||
|
|
7db991db9d | ||
|
|
d75782892e | ||
|
|
cb7adc8ced | ||
|
|
7c3ba80270 | ||
|
|
76c39edc8b | ||
|
|
c20a300eea | ||
|
|
de3902a9c9 | ||
|
|
8bca671e9f | ||
|
|
54301a6a17 | ||
|
|
f06b7c0807 | ||
|
|
43c02cf7a7 | ||
|
|
3a1568e884 | ||
|
|
14753a14e7 | ||
|
|
227e8dcc8d | ||
|
|
97fd2b2718 | ||
|
|
f30e36d7bb | ||
|
|
d640bc66f5 | ||
|
|
a2331a2575 |
71
.github/ISSUE_TEMPLATE/bug_report.md
vendored
71
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -2,32 +2,79 @@
|
||||
name: Bug report
|
||||
about: Topgrade is misbehaving
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- If you're here to report about a "No asset found" error, please make sure that an hour has been passed since the last release was made. -->
|
||||
<!--
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
Please make sure to
|
||||
[search for existing issues](https://github.com/topgrade-rs/topgrade/issues)
|
||||
before filing a new one!
|
||||
|
||||
## What did you expect to happen?
|
||||
Questions labeled with `Optional` can be skipped.
|
||||
-->
|
||||
|
||||
<!--
|
||||
If you're here to report about a "No asset found" error, please make sure that
|
||||
an hour has been passed since the last release was made.
|
||||
-->
|
||||
|
||||
## What actually happened?
|
||||
## Erroneous Behavior
|
||||
<!--
|
||||
What actually happened?
|
||||
-->
|
||||
|
||||
## Expected Behavior
|
||||
<!--
|
||||
Describe the expected behavior
|
||||
-->
|
||||
|
||||
## Steps to reproduce
|
||||
<!--
|
||||
A minimal example to reproduce the issue
|
||||
-->
|
||||
|
||||
## Possible Cause (Optional)
|
||||
<!--
|
||||
If you know the possible cause of the issue, please tell us.
|
||||
-->
|
||||
|
||||
## Problem persists without calling from topgrade
|
||||
<!--
|
||||
Execute the erroneous command directly to see if the problem persists
|
||||
-->
|
||||
- [ ] Yes
|
||||
|
||||
## Configuration file (Optional)
|
||||
<!--
|
||||
Paste your configuration file inside the code block if you think this issue is
|
||||
related to configuration.
|
||||
-->
|
||||
|
||||
```toml
|
||||
|
||||
```
|
||||
|
||||
## Additional Details
|
||||
- Which operating system or Linux distribution are you using?
|
||||
- How did you install Topgrade?
|
||||
- Which version are you running? <!-- Check with `topgrade -V` -->
|
||||
- Operation System/Version
|
||||
<!-- For example, Fedora Linux 38 -->
|
||||
|
||||
<!--
|
||||
Run `topgrade --dry-run` to see which commands Topgrade is running.
|
||||
If the command seems wrong and you know why please tell us so.
|
||||
If the command seems fine try to run it yourself and tell us if you got a different result from Topgrade.
|
||||
- Installation
|
||||
<!--
|
||||
How did you install topgrade: build from repo / crates.io (cargo install topgrade)
|
||||
/ package manager (which one) / other (describe)
|
||||
-->
|
||||
|
||||
- Topgrade version (`topgrade -V`)
|
||||
|
||||
## Verbose Output (`topgrade -v`)
|
||||
<!--
|
||||
Paste the verbose output into the pre-tags
|
||||
-->
|
||||
|
||||
<details>
|
||||
<!-- Paste the output of the problematic command with `-v` into the pre-tags -->
|
||||
<pre>
|
||||
|
||||
</pre>
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,7 @@
|
||||
## Standards checklist:
|
||||
|
||||
- [ ] The PR title is descriptive.
|
||||
- [ ] I have read `CONTRIBUTING.md`
|
||||
- [ ] The code compiles (`cargo build`)
|
||||
- [ ] The code passes rustfmt (`cargo fmt`)
|
||||
- [ ] The code passes clippy (`cargo clippy`)
|
||||
|
||||
7
.github/workflows/test.yaml
vendored
7
.github/workflows/test.yaml
vendored
@@ -57,3 +57,10 @@ jobs:
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./lcov.info
|
||||
fail_ci_if_error: true
|
||||
- name: Test creation of config file
|
||||
run: |
|
||||
CONFIG_PATH=~/.config/topgrade.toml;
|
||||
if [ -f "$CONFIG_PATH" ]; then rm $CONFIG_PATH; fi
|
||||
cargo build;
|
||||
./target/debug/topgrade --dry-run --only system;
|
||||
stat $CONFIG_PATH;
|
||||
|
||||
134
CONTRIBUTING.md
Normal file
134
CONTRIBUTING.md
Normal file
@@ -0,0 +1,134 @@
|
||||
## Contributing to `topgrade`
|
||||
|
||||
Thank you for your interest in contributing to `topgrade`! We welcome and encourage
|
||||
contributions of all kinds, such as:
|
||||
|
||||
1. Issue reports or feature requests
|
||||
2. Documentation improvements
|
||||
3. Code (PR or PR Review)
|
||||
|
||||
## Adding a new `step`
|
||||
|
||||
In `topgrade`'s term, package manager is called `step`. To add a new `step` to
|
||||
`topgrade`:
|
||||
|
||||
1. Add a new variant to
|
||||
[`enum Step`](https://github.com/topgrade-rs/topgrade/blob/cb7adc8ced8a77addf2cb051d18bba9f202ab866/src/config.rs#L100)
|
||||
|
||||
```rust
|
||||
pub enum Step {
|
||||
// Existed steps
|
||||
// ...
|
||||
|
||||
// Your new step here!
|
||||
// You may want it to be sorted alphabetically because that looks great:)
|
||||
Xxx,
|
||||
}
|
||||
```
|
||||
|
||||
2. Implement the update function
|
||||
|
||||
You need to find the appropriate location where this update function goes, it should be
|
||||
a file under [`src/steps`](https://github.com/topgrade-rs/topgrade/tree/master/src/steps),
|
||||
the file names are self-explanatory, for example, `step`s related to `zsh` are
|
||||
placed in [`steps/zsh.rs`](https://github.com/topgrade-rs/topgrade/blob/master/src/steps/zsh.rs).
|
||||
|
||||
Then you implement the update function, and put it in the file where it belongs.
|
||||
|
||||
```rust
|
||||
pub fn run_xxx(ctx: &ExecutionContext) -> Result<()> {
|
||||
// Check if this step is installed, if not, then this update will be skipped.
|
||||
let xxx = require("xxx")?;
|
||||
|
||||
// Print the separator
|
||||
print_separator("xxx");
|
||||
|
||||
// Invoke the new step to get things updated!
|
||||
ctx.run_type()
|
||||
.execute("xxx")
|
||||
.arg(/* args required by this step */)
|
||||
.status_checked()
|
||||
}
|
||||
```
|
||||
|
||||
Such a update function would be conventionally named `run_xxx()`, where `xxx`
|
||||
is the name of the new step, and it should take a argument of type
|
||||
`&ExecutionContext`, this is adequate for most cases unless some extra stuff is
|
||||
needed (You can find some examples where extra arguments are needed
|
||||
[here](https://github.com/topgrade-rs/topgrade/blob/7e48c5dedcfd5d0124bb9f39079a03e27ed23886/src/main.rs#L201-L219)).
|
||||
|
||||
Update function would usually do 3 things:
|
||||
1. Check if the step is installed
|
||||
2. Output the Separator
|
||||
3. Invoke the step
|
||||
|
||||
Still, this is sufficient for most tools, but you may need some extra stuff
|
||||
with complicated `step`.
|
||||
|
||||
3. Finally, invoke that update function in `main.rs`
|
||||
|
||||
```rust
|
||||
runner.execute(Step::Xxx, "xxx", || ItsModule::run_xxx(&ctx))?;
|
||||
```
|
||||
|
||||
We use [conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html)
|
||||
to separate the steps, for example, for steps that are Linux-only, it goes
|
||||
like this:
|
||||
|
||||
```
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
// Xxx is Linux-only
|
||||
runner.execute(Step::Xxx, "xxx", || ItsModule::run_xxx(&ctx))?;
|
||||
}
|
||||
```
|
||||
|
||||
Congrats, you just added a new `step`:)
|
||||
|
||||
## Modification to the configuration entries
|
||||
|
||||
If your PR has the configuration options
|
||||
(in [`src/config.rs`](https://github.com/topgrade-rs/topgrade/blob/master/src/config.rs))
|
||||
modified:
|
||||
|
||||
1. Adding new options
|
||||
2. Changing the existing options
|
||||
|
||||
Be sure to apply your changes to
|
||||
[`config.example.toml`](https://github.com/topgrade-rs/topgrade/blob/master/config.example.toml),
|
||||
and have some basic documentations guiding user how to use these options.
|
||||
|
||||
## Before you submit your PR
|
||||
|
||||
Make sure your patch passes the following tests on your host:
|
||||
|
||||
```shell
|
||||
$ cargo build
|
||||
$ cargo fmt
|
||||
$ cargo clippy
|
||||
$ cargo test
|
||||
```
|
||||
|
||||
Don't worry about other platforms, we have most of them covered in our CI.
|
||||
|
||||
## Some tips
|
||||
|
||||
1. Locale
|
||||
|
||||
Some `step` respects locale, which means their output can be in language other
|
||||
than English, we should not do check on it.
|
||||
|
||||
For example, one may want to check if a tool works by doing this:
|
||||
|
||||
```rust
|
||||
let output = Command::new("xxx").arg("--help").output().unwrap();
|
||||
let stdout = from_utf8(output.stdout).expect("Assume it is UTF-8 encoded");
|
||||
|
||||
if stdout.contains("help") {
|
||||
// xxx works
|
||||
}
|
||||
```
|
||||
|
||||
If `xxx` respects locale, then the above code should work on English system,
|
||||
on a system that does not use English, e.g., it uses Chinese, that `"help"` may be
|
||||
translated to `"帮助"`, and the above code won't work.
|
||||
724
Cargo.lock
generated
724
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
@@ -5,7 +5,7 @@ categories = ["os"]
|
||||
keywords = ["upgrade", "update"]
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/topgrade-rs/topgrade"
|
||||
version = "11.0.2"
|
||||
version = "12.0.0"
|
||||
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
|
||||
exclude = ["doc/screenshot.gif"]
|
||||
edition = "2021"
|
||||
@@ -41,15 +41,15 @@ tempfile = "~3.2"
|
||||
cfg-if = "~1.0"
|
||||
tokio = { version = "~1.18", features = ["process", "rt-multi-thread"] }
|
||||
futures = "~0.3"
|
||||
regex = "~1.5"
|
||||
regex = "~1.7"
|
||||
semver = "~1.0"
|
||||
shell-words = "~1.1"
|
||||
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"
|
||||
merge = "~0.1"
|
||||
regex-split = "~0.1"
|
||||
notify-rust = "~4.8"
|
||||
|
||||
[package.metadata.generate-rpm]
|
||||
assets = [{source = "target/release/topgrade", dest="/usr/bin/topgrade"}]
|
||||
|
||||
18
README.md
18
README.md
@@ -55,10 +55,18 @@ See `config.example.toml` for an example configuration file.
|
||||
|
||||
### Configuration Path
|
||||
|
||||
The configuration should be placed in the following paths depending on the operating system:
|
||||
#### `CONFIG_DIR` on each platform
|
||||
- **Windows**: `%APPDATA%`
|
||||
- **macOS** and **other Unix systems**: `${XDG_CONFIG_HOME:-~/.config}`
|
||||
|
||||
- **Windows** - `%APPDATA%/topgrade.toml`
|
||||
- **macOS** and **other Unix systems** - `${XDG_CONFIG_HOME:-~/.config}/topgrade.toml`
|
||||
`topgrade` will look for the configuration file in the following places, in order of priority:
|
||||
|
||||
1. `CONFIG_DIR/topgrade.toml`
|
||||
2. `CONFIG_DIR/topgrade/topgrade.toml`
|
||||
|
||||
If the file with higher priority is present, no matter it is valid or not, the other configuration files will be ignored.
|
||||
|
||||
On the first run(no configuration file exists), `topgrade` will create a configuration file at `CONFIG_DIR/topgrade.toml` for you.
|
||||
|
||||
### Custom Commands
|
||||
|
||||
@@ -92,8 +100,8 @@ Just fork the repository and start coding.
|
||||
|
||||
### Contribution Guidelines
|
||||
|
||||
- Check if your code passes `cargo fmt` and `cargo clippy`.
|
||||
- Check if your code is self explanatory, if not it should be documented by comments.
|
||||
See [CONTRIBUTING.md](https://github.com/topgrade-rs/topgrade/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [ ] Add a proper testing framework to the code base.
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# Include any additional configuration file(s)
|
||||
# [include] sections are processed in the order you write them
|
||||
# Files in $CONFIG_DIR/topgrade/topgrade.d/ are automatically included at the beginning of this file
|
||||
[include]
|
||||
#paths = ["/etc/topgrade.toml"]
|
||||
|
||||
[misc]
|
||||
# Don't ask for confirmations
|
||||
#assume_yes = true
|
||||
|
||||
@@ -47,9 +54,6 @@
|
||||
# Skip sending a notification at the end of a run
|
||||
#skip_notify = true
|
||||
|
||||
# Skip the preamble displayed when topgrade is run
|
||||
#display_preamble = false
|
||||
|
||||
# Whether to self update (this is ignored if the binary has been built without self update support, available also via setting the environment variable TOPGRADE_NO_SELF_UPGRADE)
|
||||
#no_self_update = true
|
||||
|
||||
@@ -101,12 +105,15 @@
|
||||
#emerge_sync_flags = "-q"
|
||||
#emerge_update_flags = "-uDNa --with-bdeps=y world"
|
||||
#redhat_distro_sync = false
|
||||
#suse_dup = false
|
||||
#rpm_ostree = false
|
||||
#nix_arguments = "--flake"
|
||||
|
||||
[python]
|
||||
#enable_pip_review = true ###disabled by default
|
||||
#enable_pipupgrade = true ###disabled by default
|
||||
#enable_pip_review = true ###disabled by default
|
||||
#enable_pip_review_local = true ###disabled by default
|
||||
#enable_pipupgrade = true ###disabled by default
|
||||
#pipupgrade_arguments = "-y -u --pip-path pip" ###disabled by default
|
||||
|
||||
[windows]
|
||||
# Manually select Windows updates
|
||||
|
||||
636
src/config.rs
636
src/config.rs
File diff suppressed because it is too large
Load Diff
@@ -10,10 +10,6 @@ pub enum TopgradeError {
|
||||
#[error("`{0}` failed: {1}")]
|
||||
ProcessFailedWithOutput(String, ExitStatus, String),
|
||||
|
||||
#[error("Sudo is required for this step")]
|
||||
#[allow(dead_code)]
|
||||
SudoRequired,
|
||||
|
||||
#[error("Unknown Linux Distribution")]
|
||||
#[cfg(target_os = "linux")]
|
||||
UnknownLinuxDistribution,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use crate::executor::RunType;
|
||||
use crate::git::Git;
|
||||
use crate::sudo::Sudo;
|
||||
use crate::utils::require_option;
|
||||
use crate::utils::{require_option, REQUIRE_SUDO};
|
||||
use crate::{config::Config, executor::Executor};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::path::Path;
|
||||
@@ -31,7 +31,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 sudo = require_option(self.sudo.as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
Ok(sudo.execute_elevated(self, command, interactive))
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
use std::process::{Child, Command, ExitStatus, Output};
|
||||
|
||||
use color_eyre::eyre;
|
||||
use color_eyre::eyre::Result;
|
||||
use tracing::debug;
|
||||
|
||||
@@ -238,7 +237,7 @@ impl CommandExt for Executor {
|
||||
// TODO: It might be nice to make `output_checked_with` return something that has a
|
||||
// variant for wet/dry runs.
|
||||
|
||||
fn output_checked_with(&mut self, succeeded: impl Fn(&Output) -> Result<(), ()>) -> eyre::Result<Output> {
|
||||
fn output_checked_with(&mut self, succeeded: impl Fn(&Output) -> Result<(), ()>) -> Result<Output> {
|
||||
match self {
|
||||
Executor::Wet(c) => c.output_checked_with(succeeded),
|
||||
Executor::Dry(c) => {
|
||||
@@ -248,7 +247,7 @@ impl CommandExt for Executor {
|
||||
}
|
||||
}
|
||||
|
||||
fn status_checked_with(&mut self, succeeded: impl Fn(ExitStatus) -> Result<(), ()>) -> eyre::Result<()> {
|
||||
fn status_checked_with(&mut self, succeeded: impl Fn(ExitStatus) -> Result<(), ()>) -> Result<()> {
|
||||
match self {
|
||||
Executor::Wet(c) => c.status_checked_with(succeeded),
|
||||
Executor::Dry(c) => {
|
||||
@@ -258,7 +257,7 @@ impl CommandExt for Executor {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_checked(&mut self) -> eyre::Result<Self::Child> {
|
||||
fn spawn_checked(&mut self) -> Result<Self::Child> {
|
||||
self.spawn()
|
||||
}
|
||||
}
|
||||
|
||||
366
src/main.rs
366
src/main.rs
@@ -54,13 +54,13 @@ fn run() -> Result<()> {
|
||||
|
||||
if let Some(shell) = opt.gen_completion {
|
||||
let cmd = &mut CommandLineArgs::command();
|
||||
clap_complete::generate(shell, cmd, clap::crate_name!(), &mut std::io::stdout());
|
||||
clap_complete::generate(shell, cmd, clap::crate_name!(), &mut io::stdout());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if opt.gen_manpage {
|
||||
let man = clap_mangen::Man::new(CommandLineArgs::command());
|
||||
man.render(&mut std::io::stdout())?;
|
||||
man.render(&mut io::stdout())?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -79,14 +79,14 @@ fn run() -> Result<()> {
|
||||
};
|
||||
|
||||
if opt.show_config_reference() {
|
||||
print!("{}", crate::config::EXAMPLE_CONFIG);
|
||||
print!("{}", config::EXAMPLE_CONFIG);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config = Config::load(opt)?;
|
||||
terminal::set_title(config.set_title());
|
||||
terminal::display_time(config.display_time());
|
||||
terminal::set_desktop_notifications(config.notify_each_step());
|
||||
set_title(config.set_title());
|
||||
display_time(config.display_time());
|
||||
set_desktop_notifications(config.notify_each_step());
|
||||
|
||||
debug!("Version: {}", crate_version!());
|
||||
debug!("OS: {}", env!("TARGET"));
|
||||
@@ -94,16 +94,6 @@ fn run() -> Result<()> {
|
||||
debug!("Binary path: {:?}", std::env::current_exe());
|
||||
debug!("Self Update: {:?}", cfg!(feature = "self-update"));
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if config.display_preamble() && terminal::supports_notify_send() && !config.skip_notify() {
|
||||
print_warning("Due to a design issue with notify-send it could be that topgrade hangs when it's finished.
|
||||
If this is the case on your system add the --skip-notify flag to the topgrade command or set skip_notify = true in the config file.
|
||||
If you don't want this message to appear any longer set display_preamble = false in the config file.
|
||||
For more information about this issue see https://askubuntu.com/questions/110969/notify-send-ignores-timeout and https://github.com/topgrade-rs/topgrade/issues/288.");
|
||||
}
|
||||
}
|
||||
|
||||
if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
@@ -114,12 +104,15 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
|
||||
let git = git::Git::new();
|
||||
let mut git_repos = git::Repositories::new(&git);
|
||||
let powershell = powershell::Powershell::new();
|
||||
let should_run_powershell = powershell.profile().is_some() && config.should_run(Step::Powershell);
|
||||
let emacs = emacs::Emacs::new();
|
||||
#[cfg(target_os = "linux")]
|
||||
let distribution = linux::Distribution::detect();
|
||||
|
||||
let sudo = config.sudo_command().map_or_else(sudo::Sudo::detect, sudo::Sudo::new);
|
||||
let run_type = executor::RunType::new(config.dry_run());
|
||||
|
||||
let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config);
|
||||
|
||||
let mut runner = runner::Runner::new(&ctx);
|
||||
|
||||
#[cfg(feature = "self-update")]
|
||||
@@ -160,28 +153,30 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
}
|
||||
}
|
||||
|
||||
let powershell = powershell::Powershell::new();
|
||||
let should_run_powershell = powershell.profile().is_some() && config.should_run(Step::Powershell);
|
||||
|
||||
#[cfg(windows)]
|
||||
runner.execute(Step::Wsl, "WSL", || windows::run_wsl_topgrade(&ctx))?;
|
||||
|
||||
#[cfg(windows)]
|
||||
runner.execute(Step::WslUpdate, "WSL", || windows::update_wsl(&ctx))?;
|
||||
|
||||
if let Some(topgrades) = config.remote_topgrades() {
|
||||
for remote_topgrade in topgrades.iter().filter(|t| config.should_execute_remote(t)) {
|
||||
runner.execute(Step::Remotes, format!("Remote ({remote_topgrade})"), || {
|
||||
remote::ssh::ssh_step(&ctx, remote_topgrade)
|
||||
ssh::ssh_step(&ctx, remote_topgrade)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let distribution = linux::Distribution::detect();
|
||||
|
||||
#[cfg(target_os = r#"linux"#)]
|
||||
#[cfg(windows)]
|
||||
{
|
||||
runner.execute(Step::Wsl, "WSL", || windows::run_wsl_topgrade(&ctx))?;
|
||||
runner.execute(Step::WslUpdate, "WSL", || windows::update_wsl(&ctx))?;
|
||||
runner.execute(Step::Chocolatey, "Chocolatey", || windows::run_chocolatey(&ctx))?;
|
||||
runner.execute(Step::Scoop, "Scoop", || windows::run_scoop(&ctx))?;
|
||||
runner.execute(Step::Winget, "Winget", || windows::run_winget(&ctx))?;
|
||||
runner.execute(Step::System, "Windows update", || windows::windows_update(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
// NOTE: Due to breaking `nu` updates, `packer.nu` needs to be updated before `nu` get updated
|
||||
// by other package managers.
|
||||
runner.execute(Step::Shell, "packer.nu", || linux::run_packer_nu(&ctx))?;
|
||||
|
||||
match &distribution {
|
||||
Ok(distribution) => {
|
||||
runner.execute(Step::System, "System update", || distribution.upgrade(&ctx))?;
|
||||
@@ -195,13 +190,21 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
runner.execute(Step::BrewFormula, "Brew", || {
|
||||
unix::run_brew_formula(&ctx, unix::BrewVariant::Path)
|
||||
})?;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
runner.execute(Step::Chocolatey, "Chocolatey", || windows::run_chocolatey(&ctx))?;
|
||||
runner.execute(Step::Scoop, "Scoop", || windows::run_scoop(config.cleanup(), run_type))?;
|
||||
runner.execute(Step::Winget, "Winget", || windows::run_winget(&ctx))?;
|
||||
runner.execute(Step::AM, "am", || linux::run_am(&ctx))?;
|
||||
runner.execute(Step::AppMan, "appman", || linux::run_appman(&ctx))?;
|
||||
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::run_flatpak(&ctx))?;
|
||||
runner.execute(Step::Snap, "snap", || linux::run_snap(&ctx))?;
|
||||
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))?;
|
||||
runner.execute(Step::Distrobox, "distrobox", || linux::run_distrobox_update(&ctx))?;
|
||||
runner.execute(Step::DkpPacman, "dkp-pacman", || linux::run_dkp_pacman_update(&ctx))?;
|
||||
runner.execute(Step::System, "pihole", || linux::run_pihole_update(&ctx))?;
|
||||
runner.execute(Step::Firmware, "Firmware upgrades", || linux::run_fwupdmgr(&ctx))?;
|
||||
runner.execute(Step::Restarts, "Restarts", || linux::run_needrestart(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -225,6 +228,35 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
unix::run_brew_cask(&ctx, unix::BrewVariant::Path)
|
||||
})?;
|
||||
runner.execute(Step::Macports, "MacPorts", || macos::run_macports(&ctx))?;
|
||||
runner.execute(Step::Sparkle, "Sparkle", || macos::run_sparkle(&ctx))?;
|
||||
runner.execute(Step::Mas, "App Store", || macos::run_mas(&ctx))?;
|
||||
runner.execute(Step::System, "System upgrade", || macos::upgrade_macos(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
{
|
||||
runner.execute(Step::Pkg, "DragonFly BSD Packages", || {
|
||||
dragonfly::upgrade_packages(&ctx)
|
||||
})?;
|
||||
dragonfly::audit_packages(&ctx)?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
{
|
||||
runner.execute(Step::Pkg, "FreeBSD Packages", || freebsd::upgrade_packages(&ctx))?;
|
||||
runner.execute(Step::System, "FreeBSD Upgrade", || freebsd::upgrade_freebsd(&ctx))?;
|
||||
freebsd::audit_packages(&ctx)?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
{
|
||||
runner.execute(Step::Pkg, "OpenBSD Packages", || openbsd::upgrade_packages(&ctx))?;
|
||||
runner.execute(Step::System, "OpenBSD Upgrade", || openbsd::upgrade_openbsd(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
runner.execute(Step::Pkg, "Termux Packages", || android::upgrade_packages(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -232,32 +264,107 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
runner.execute(Step::Yadm, "yadm", || unix::run_yadm(&ctx))?;
|
||||
runner.execute(Step::Nix, "nix", || unix::run_nix(&ctx))?;
|
||||
runner.execute(Step::Guix, "guix", || unix::run_guix(&ctx))?;
|
||||
|
||||
runner.execute(Step::HomeManager, "home-manager", || unix::run_home_manager(run_type))?;
|
||||
runner.execute(Step::Asdf, "asdf", || unix::run_asdf(run_type))?;
|
||||
runner.execute(Step::HomeManager, "home-manager", || unix::run_home_manager(&ctx))?;
|
||||
runner.execute(Step::Asdf, "asdf", || unix::run_asdf(&ctx))?;
|
||||
runner.execute(Step::Pkgin, "pkgin", || unix::run_pkgin(&ctx))?;
|
||||
runner.execute(Step::Bun, "bun", || unix::run_bun(&ctx))?;
|
||||
runner.execute(Step::Shell, "zr", || zsh::run_zr(&ctx))?;
|
||||
runner.execute(Step::Shell, "antibody", || zsh::run_antibody(&ctx))?;
|
||||
runner.execute(Step::Shell, "antidote", || zsh::run_antidote(&ctx))?;
|
||||
runner.execute(Step::Shell, "antigen", || zsh::run_antigen(&ctx))?;
|
||||
runner.execute(Step::Shell, "zgenom", || zsh::run_zgenom(&ctx))?;
|
||||
runner.execute(Step::Shell, "zplug", || zsh::run_zplug(&ctx))?;
|
||||
runner.execute(Step::Shell, "zinit", || zsh::run_zinit(&ctx))?;
|
||||
runner.execute(Step::Shell, "zi", || zsh::run_zi(&ctx))?;
|
||||
runner.execute(Step::Shell, "zim", || zsh::run_zim(&ctx))?;
|
||||
runner.execute(Step::Shell, "oh-my-zsh", || zsh::run_oh_my_zsh(&ctx))?;
|
||||
runner.execute(Step::Shell, "oh-my-bash", || unix::run_oh_my_bash(&ctx))?;
|
||||
runner.execute(Step::Shell, "fisher", || unix::run_fisher(&ctx))?;
|
||||
runner.execute(Step::Shell, "bash-it", || unix::run_bashit(&ctx))?;
|
||||
runner.execute(Step::Shell, "oh-my-fish", || unix::run_oh_my_fish(&ctx))?;
|
||||
runner.execute(Step::Shell, "fish-plug", || unix::run_fish_plug(&ctx))?;
|
||||
runner.execute(Step::Shell, "fundle", || unix::run_fundle(&ctx))?;
|
||||
runner.execute(Step::Tmux, "tmux", || tmux::run_tpm(&ctx))?;
|
||||
runner.execute(Step::Tldr, "TLDR", || unix::run_tldr(&ctx))?;
|
||||
runner.execute(Step::Pearl, "pearl", || unix::run_pearl(&ctx))?;
|
||||
#[cfg(not(any(target_os = "macos", target_os = "android")))]
|
||||
runner.execute(Step::GnomeShellExtensions, "Gnome Shell Extensions", || {
|
||||
unix::upgrade_gnome_extensions(&ctx)
|
||||
})?;
|
||||
runner.execute(Step::Sdkman, "SDKMAN!", || unix::run_sdkman(&ctx))?;
|
||||
runner.execute(Step::Rcm, "rcm", || unix::run_rcm(&ctx))?;
|
||||
runner.execute(Step::Maza, "maza", || unix::run_maza(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
runner.execute(Step::Pkg, "DragonFly BSD Packages", || {
|
||||
dragonfly::upgrade_packages(ctx.sudo().as_ref(), run_type)
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
)))]
|
||||
{
|
||||
runner.execute(Step::Atom, "apm", || generic::run_apm(&ctx))?;
|
||||
}
|
||||
|
||||
// The following update function should be executed on all OSes.
|
||||
runner.execute(Step::Fossil, "fossil", || generic::run_fossil(&ctx))?;
|
||||
runner.execute(Step::Rustup, "rustup", || generic::run_rustup(&ctx))?;
|
||||
runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(&ctx))?;
|
||||
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))?;
|
||||
runner.execute(Step::Flutter, "Flutter", || generic::run_flutter_upgrade(&ctx))?;
|
||||
runner.execute(Step::Go, "go-global-update", || go::run_go_global_update(&ctx))?;
|
||||
runner.execute(Step::Go, "gup", || go::run_go_gup(&ctx))?;
|
||||
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(&ctx))?;
|
||||
runner.execute(Step::Pipx, "pipx", || generic::run_pipx_update(&ctx))?;
|
||||
runner.execute(Step::Conda, "conda", || generic::run_conda_update(&ctx))?;
|
||||
runner.execute(Step::Mamba, "mamba", || generic::run_mamba_update(&ctx))?;
|
||||
runner.execute(Step::Pip3, "pip3", || generic::run_pip3_update(&ctx))?;
|
||||
runner.execute(Step::PipReview, "pip-review", || generic::run_pip_review_update(&ctx))?;
|
||||
runner.execute(Step::PipReviewLocal, "pip-review (local)", || {
|
||||
generic::run_pip_review_local_update(&ctx)
|
||||
})?;
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
runner.execute(Step::Pkg, "FreeBSD Packages", || {
|
||||
freebsd::upgrade_packages(&ctx, ctx.sudo().as_ref(), run_type)
|
||||
runner.execute(Step::Pipupgrade, "pipupgrade", || generic::run_pipupgrade_update(&ctx))?;
|
||||
runner.execute(Step::Ghcup, "ghcup", || generic::run_ghcup_update(&ctx))?;
|
||||
runner.execute(Step::Stack, "stack", || generic::run_stack_update(&ctx))?;
|
||||
runner.execute(Step::Tlmgr, "tlmgr", || generic::run_tlmgr_update(&ctx))?;
|
||||
runner.execute(Step::Myrepos, "myrepos", || generic::run_myrepos_update(&ctx))?;
|
||||
runner.execute(Step::Chezmoi, "chezmoi", || generic::run_chezmoi_update(&ctx))?;
|
||||
runner.execute(Step::Jetpack, "jetpack", || generic::run_jetpack(&ctx))?;
|
||||
runner.execute(Step::Vim, "vim", || vim::upgrade_vim(&ctx))?;
|
||||
runner.execute(Step::Vim, "Neovim", || vim::upgrade_neovim(&ctx))?;
|
||||
runner.execute(Step::Vim, "The Ultimate vimrc", || vim::upgrade_ultimate_vimrc(&ctx))?;
|
||||
runner.execute(Step::Vim, "voom", || vim::run_voom(&ctx))?;
|
||||
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::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(&ctx))?;
|
||||
runner.execute(Step::Helm, "helm", || generic::run_helm_repo_update(&ctx))?;
|
||||
runner.execute(Step::Gem, "gem", || generic::run_gem(&ctx))?;
|
||||
runner.execute(Step::RubyGems, "rubygems", || generic::run_rubygems(&ctx))?;
|
||||
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))?;
|
||||
runner.execute(Step::Stew, "stew", || generic::run_stew(&ctx))?;
|
||||
runner.execute(Step::Rtcl, "rtcl", || generic::run_rtcl(&ctx))?;
|
||||
runner.execute(Step::Bin, "bin", || generic::bin_update(&ctx))?;
|
||||
runner.execute(Step::Gcloud, "gcloud", || generic::run_gcloud_components_update(&ctx))?;
|
||||
runner.execute(Step::Micro, "micro", || generic::run_micro(&ctx))?;
|
||||
runner.execute(Step::Raco, "raco", || generic::run_raco_update(&ctx))?;
|
||||
runner.execute(Step::Spicetify, "spicetify", || generic::spicetify_upgrade(&ctx))?;
|
||||
runner.execute(Step::GithubCliExtensions, "GitHub CLI Extensions", || {
|
||||
generic::run_ghcli_extensions_upgrade(&ctx)
|
||||
})?;
|
||||
runner.execute(Step::Bob, "Bob", || generic::run_bob(&ctx))?;
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
runner.execute(Step::Pkg, "OpenBSD Packages", || {
|
||||
openbsd::upgrade_packages(ctx.sudo().as_ref(), run_type)
|
||||
})?;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
runner.execute(Step::Pkg, "Termux Packages", || android::upgrade_packages(&ctx))?;
|
||||
|
||||
let emacs = emacs::Emacs::new();
|
||||
if config.use_predefined_git_repos() {
|
||||
if config.should_run(Step::Emacs) {
|
||||
if !emacs.is_doom() {
|
||||
@@ -325,110 +432,6 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
})?;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
runner.execute(Step::Shell, "zr", || zsh::run_zr(run_type))?;
|
||||
runner.execute(Step::Shell, "antibody", || zsh::run_antibody(run_type))?;
|
||||
runner.execute(Step::Shell, "antidote", || zsh::run_antidote(&ctx))?;
|
||||
runner.execute(Step::Shell, "antigen", || zsh::run_antigen(run_type))?;
|
||||
runner.execute(Step::Shell, "zgenom", || zsh::run_zgenom(run_type))?;
|
||||
runner.execute(Step::Shell, "zplug", || zsh::run_zplug(run_type))?;
|
||||
runner.execute(Step::Shell, "zinit", || zsh::run_zinit(run_type))?;
|
||||
runner.execute(Step::Shell, "zi", || zsh::run_zi(run_type))?;
|
||||
runner.execute(Step::Shell, "zim", || zsh::run_zim(run_type))?;
|
||||
runner.execute(Step::Shell, "oh-my-zsh", || zsh::run_oh_my_zsh(&ctx))?;
|
||||
runner.execute(Step::Shell, "fisher", || unix::run_fisher(run_type))?;
|
||||
runner.execute(Step::Shell, "bash-it", || unix::run_bashit(&ctx))?;
|
||||
runner.execute(Step::Shell, "oh-my-fish", || unix::run_oh_my_fish(&ctx))?;
|
||||
runner.execute(Step::Shell, "fish-plug", || unix::run_fish_plug(&ctx))?;
|
||||
runner.execute(Step::Shell, "fundle", || unix::run_fundle(&ctx))?;
|
||||
runner.execute(Step::Tmux, "tmux", || tmux::run_tpm(run_type))?;
|
||||
runner.execute(Step::Tldr, "TLDR", || unix::run_tldr(run_type))?;
|
||||
runner.execute(Step::Pearl, "pearl", || unix::run_pearl(run_type))?;
|
||||
#[cfg(not(any(target_os = "macos", target_os = "android")))]
|
||||
runner.execute(Step::GnomeShellExtensions, "Gnome Shell Extensions", || {
|
||||
unix::upgrade_gnome_extensions(&ctx)
|
||||
})?;
|
||||
runner.execute(Step::Sdkman, "SDKMAN!", || unix::run_sdkman(config.cleanup(), run_type))?;
|
||||
runner.execute(Step::Rcm, "rcm", || unix::run_rcm(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
)))]
|
||||
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(&ctx))?;
|
||||
runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(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))?;
|
||||
runner.execute(Step::Flutter, "Flutter", || generic::run_flutter_upgrade(run_type))?;
|
||||
runner.execute(Step::Go, "go-global-update", || go::run_go_global_update(run_type))?;
|
||||
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(&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::Mamba, "mamba", || generic::run_mamba_update(&ctx))?;
|
||||
runner.execute(Step::Pip3, "pip3", || generic::run_pip3_update(run_type))?;
|
||||
runner.execute(Step::PipReview, "pip-review", || generic::run_pip_review_update(&ctx))?;
|
||||
runner.execute(Step::Pipupgrade, "pipupgrade", || generic::run_pipupgrade_update(&ctx))?;
|
||||
runner.execute(Step::Ghcup, "ghcup", || generic::run_ghcup_update(run_type))?;
|
||||
runner.execute(Step::Stack, "stack", || generic::run_stack_update(run_type))?;
|
||||
runner.execute(Step::Tlmgr, "tlmgr", || generic::run_tlmgr_update(&ctx))?;
|
||||
runner.execute(Step::Myrepos, "myrepos", || generic::run_myrepos_update(run_type))?;
|
||||
runner.execute(Step::Chezmoi, "chezmoi", || generic::run_chezmoi_update(run_type))?;
|
||||
runner.execute(Step::Jetpack, "jetpack", || generic::run_jetpack(run_type))?;
|
||||
runner.execute(Step::Vim, "vim", || vim::upgrade_vim(&ctx))?;
|
||||
runner.execute(Step::Vim, "Neovim", || vim::upgrade_neovim(&ctx))?;
|
||||
runner.execute(Step::Vim, "The Ultimate vimrc", || vim::upgrade_ultimate_vimrc(&ctx))?;
|
||||
runner.execute(Step::Vim, "voom", || vim::run_voom(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::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(run_type))?;
|
||||
runner.execute(Step::RubyGems, "rubygems", || generic::run_rubygems(&ctx))?;
|
||||
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))?;
|
||||
runner.execute(Step::Rtcl, "rtcl", || generic::run_rtcl(&ctx))?;
|
||||
runner.execute(Step::Bin, "bin", || generic::bin_update(&ctx))?;
|
||||
runner.execute(Step::Gcloud, "gcloud", || {
|
||||
generic::run_gcloud_components_update(run_type)
|
||||
})?;
|
||||
runner.execute(Step::Micro, "micro", || generic::run_micro(run_type))?;
|
||||
runner.execute(Step::Raco, "raco", || generic::run_raco_update(run_type))?;
|
||||
runner.execute(Step::Spicetify, "spicetify", || generic::spicetify_upgrade(&ctx))?;
|
||||
runner.execute(Step::GithubCliExtensions, "GitHub CLI Extensions", || {
|
||||
generic::run_ghcli_extensions_upgrade(&ctx)
|
||||
})?;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
runner.execute(Step::AM, "am", || linux::update_am(&ctx))?;
|
||||
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(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))?;
|
||||
runner.execute(Step::Distrobox, "distrobox", || linux::run_distrobox_update(&ctx))?;
|
||||
runner.execute(Step::DkpPacman, "dkp-pacman", || linux::run_dkp_pacman_update(&ctx))?;
|
||||
}
|
||||
|
||||
if let Some(commands) = config.commands() {
|
||||
for (name, command) in commands {
|
||||
if config.should_run_custom_command(name) {
|
||||
@@ -439,37 +442,6 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
runner.execute(Step::System, "pihole", || {
|
||||
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(ctx.sudo().as_ref(), run_type)
|
||||
})?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
runner.execute(Step::Sparkle, "Sparkle", || macos::run_sparkle(&ctx))?;
|
||||
runner.execute(Step::Mas, "App Store", || macos::run_mas(run_type))?;
|
||||
runner.execute(Step::System, "System upgrade", || macos::upgrade_macos(&ctx))?;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
runner.execute(Step::System, "FreeBSD Upgrade", || {
|
||||
freebsd::upgrade_freebsd(ctx.sudo().as_ref(), run_type)
|
||||
})?;
|
||||
|
||||
#[cfg(target_os = "openbsd")]
|
||||
runner.execute(Step::System, "OpenBSD Upgrade", || {
|
||||
openbsd::upgrade_openbsd(ctx.sudo().as_ref(), run_type)
|
||||
})?;
|
||||
|
||||
#[cfg(windows)]
|
||||
runner.execute(Step::System, "Windows update", || windows::windows_update(&ctx))?;
|
||||
|
||||
if config.should_run(Step::Vagrant) {
|
||||
if let Ok(boxes) = vagrant::collect_boxes(&ctx) {
|
||||
for vagrant_box in boxes {
|
||||
@@ -494,12 +466,6 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
distribution.show_summary();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
freebsd::audit_packages(ctx.sudo().as_ref()).ok();
|
||||
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
dragonfly::audit_packages(ctx.sudo().as_ref()).ok();
|
||||
}
|
||||
|
||||
let mut post_command_failed = false;
|
||||
@@ -533,7 +499,7 @@ For more information about this issue see https://askubuntu.com/questions/110969
|
||||
let failed = post_command_failed || runner.report().data().iter().any(|(_, result)| result.failed());
|
||||
|
||||
if !config.skip_notify() {
|
||||
terminal::notify_desktop(
|
||||
notify_desktop(
|
||||
format!(
|
||||
"Topgrade finished {}",
|
||||
if failed { "with errors" } else { "successfully" }
|
||||
@@ -579,7 +545,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_tracing(filter_directives: &str) -> Result<()> {
|
||||
fn install_tracing(filter_directives: &str) -> Result<()> {
|
||||
use tracing_subscriber::fmt;
|
||||
use tracing_subscriber::fmt::format::FmtSpan;
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
@@ -18,15 +19,42 @@ use crate::{execution_context::ExecutionContext, utils::require};
|
||||
// themselves or when using docker-compose.
|
||||
const NONEXISTENT_REPO: &str = "repository does not exist";
|
||||
|
||||
/// Uniquely identifies a `Container`.
|
||||
#[derive(Debug)]
|
||||
struct Container {
|
||||
/// `Repository` and `Tag`
|
||||
///
|
||||
/// format: `Repository:Tag`, e.g., `nixos/nix:latest`.
|
||||
repo_tag: String,
|
||||
/// Platform
|
||||
///
|
||||
/// format: `OS/Architecture`, e.g., `linux/amd64`.
|
||||
platform: String,
|
||||
}
|
||||
|
||||
impl Container {
|
||||
/// Construct a new `Container`.
|
||||
fn new(repo_tag: String, platform: String) -> Self {
|
||||
Self { repo_tag, platform }
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Container {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
// e.g., "`fedora:latest` for `linux/amd64`"
|
||||
write!(f, "`{}` for `{}`", self.repo_tag, self.platform)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a Vector of all containers, with Strings in the format
|
||||
/// "REGISTRY/[PATH/]CONTAINER_NAME:TAG"
|
||||
fn list_containers(crt: &Path) -> Result<Vec<String>> {
|
||||
fn list_containers(crt: &Path) -> Result<Vec<Container>> {
|
||||
debug!(
|
||||
"Querying '{} image ls --format \"{{{{.Repository}}}}:{{{{.Tag}}}}\"' for containers",
|
||||
"Querying '{} image ls --format \"{{{{.Repository}}}}:{{{{.Tag}}}}/{{{{.ID}}}}\"' for containers",
|
||||
crt.display()
|
||||
);
|
||||
let output = Command::new(crt)
|
||||
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"])
|
||||
.args(["image", "ls", "--format", "{{.Repository}}:{{.Tag}} {{.ID}}"])
|
||||
.output_checked_with_utf8(|_| Ok(()))?;
|
||||
|
||||
let mut retval = vec![];
|
||||
@@ -49,7 +77,26 @@ fn list_containers(crt: &Path) -> Result<Vec<String>> {
|
||||
}
|
||||
|
||||
debug!("Using container '{}'", line);
|
||||
retval.push(String::from(line));
|
||||
|
||||
// line is of format: `Repository:Tag ImageID`, e.g., `nixos/nix:latest d80fea9c32b4`
|
||||
let split_res = line.split(' ').collect::<Vec<&str>>();
|
||||
assert_eq!(split_res.len(), 2);
|
||||
let (repo_tag, image_id) = (split_res[0], split_res[1]);
|
||||
|
||||
debug!(
|
||||
"Querying '{} image inspect --format \"{{{{.Os}}}}/{{{{.Architecture}}}}\"' for container {}",
|
||||
crt.display(),
|
||||
image_id
|
||||
);
|
||||
let inspect_output = Command::new(crt)
|
||||
.args(["image", "inspect", image_id, "--format", "{{.Os}}/{{.Architecture}}"])
|
||||
.output_checked_with_utf8(|_| Ok(()))?;
|
||||
let mut platform = inspect_output.stdout;
|
||||
// truncate the tailing new line character
|
||||
platform.truncate(platform.len() - 1);
|
||||
assert!(platform.contains('/'));
|
||||
|
||||
retval.push(Container::new(repo_tag.to_string(), platform));
|
||||
}
|
||||
|
||||
Ok(retval)
|
||||
@@ -67,7 +114,12 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
for container in containers.iter() {
|
||||
debug!("Pulling container '{}'", container);
|
||||
let args = vec!["pull", &container[..]];
|
||||
let args = vec![
|
||||
"pull",
|
||||
container.repo_tag.as_str(),
|
||||
"--platform",
|
||||
container.platform.as_str(),
|
||||
];
|
||||
let mut exec = ctx.run_type().execute(&crt);
|
||||
|
||||
if let Err(e) = exec.args(&args).status_checked() {
|
||||
|
||||
@@ -13,9 +13,9 @@ use tracing::{debug, error};
|
||||
|
||||
use crate::command::{CommandExt, Utf8Output};
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::executor::{ExecutorOutput, RunType};
|
||||
use crate::executor::ExecutorOutput;
|
||||
use crate::terminal::{print_separator, shell};
|
||||
use crate::utils::{self, require, require_option, which, PathExt};
|
||||
use crate::utils::{self, check_is_python_2_or_shim, require, require_option, which, PathExt, REQUIRE_SUDO};
|
||||
use crate::Step;
|
||||
use crate::HOME_DIR;
|
||||
use crate::{
|
||||
@@ -28,7 +28,7 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| HOME_DIR.join(".cargo"))
|
||||
.require()?;
|
||||
utils::require("cargo").or_else(|_| {
|
||||
require("cargo").or_else(|_| {
|
||||
require_option(
|
||||
cargo_dir.join("bin/cargo").if_exists(),
|
||||
String::from("No cargo detected"),
|
||||
@@ -42,7 +42,7 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
print_separator("Cargo");
|
||||
let cargo_update = utils::require("cargo-install-update")
|
||||
let cargo_update = require("cargo-install-update")
|
||||
.ok()
|
||||
.or_else(|| cargo_dir.join("bin/cargo-install-update").if_exists());
|
||||
let cargo_update = match cargo_update {
|
||||
@@ -60,7 +60,7 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
let cargo_cache = utils::require("cargo-cache")
|
||||
let cargo_cache = require("cargo-cache")
|
||||
.ok()
|
||||
.or_else(|| cargo_dir.join("bin/cargo-cache").if_exists());
|
||||
match cargo_cache {
|
||||
@@ -77,20 +77,20 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
|
||||
let flutter = utils::require("flutter")?;
|
||||
pub fn run_flutter_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let flutter = require("flutter")?;
|
||||
|
||||
print_separator("Flutter");
|
||||
run_type.execute(flutter).arg("upgrade").status_checked()
|
||||
ctx.run_type().execute(flutter).arg("upgrade").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_gem(run_type: RunType) -> Result<()> {
|
||||
let gem = utils::require("gem")?;
|
||||
pub fn run_gem(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gem = require("gem")?;
|
||||
HOME_DIR.join(".gem").require()?;
|
||||
|
||||
print_separator("Gems");
|
||||
|
||||
let mut command = run_type.execute(gem);
|
||||
let mut command = ctx.run_type().execute(gem);
|
||||
command.arg("update");
|
||||
|
||||
if env::var_os("RBENV_SHELL").is_none() {
|
||||
@@ -112,8 +112,9 @@ pub fn run_rubygems(ctx: &ExecutionContext) -> Result<()> {
|
||||
.execute(gem)
|
||||
.args(["update", "--system"])
|
||||
.status_checked()?;
|
||||
} else if let Some(sudo) = &ctx.sudo() {
|
||||
if !std::path::Path::new("/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb").exists() {
|
||||
} else {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
if !Path::new("/usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb").exists() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg("-EH")
|
||||
@@ -121,14 +122,13 @@ pub fn run_rubygems(ctx: &ExecutionContext) -> Result<()> {
|
||||
.args(["update", "--system"])
|
||||
.status_checked()?;
|
||||
}
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let haxelib = utils::require("haxelib")?;
|
||||
let haxelib = require("haxelib")?;
|
||||
|
||||
let haxelib_dir =
|
||||
PathBuf::from(std::str::from_utf8(&Command::new(&haxelib).arg("config").output_checked()?.stdout)?.trim())
|
||||
@@ -142,9 +142,8 @@ pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let mut command = if directory_writable {
|
||||
ctx.run_type().execute(&haxelib)
|
||||
} else {
|
||||
let mut c = ctx
|
||||
.run_type()
|
||||
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut c = ctx.run_type().execute(sudo);
|
||||
c.arg(&haxelib);
|
||||
c
|
||||
};
|
||||
@@ -153,7 +152,7 @@ pub fn run_haxelib_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sheldon = utils::require("sheldon")?;
|
||||
let sheldon = require("sheldon")?;
|
||||
|
||||
print_separator("Sheldon");
|
||||
|
||||
@@ -163,20 +162,21 @@ pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_fossil(run_type: RunType) -> Result<()> {
|
||||
let fossil = utils::require("fossil")?;
|
||||
pub fn run_fossil(ctx: &ExecutionContext) -> Result<()> {
|
||||
let fossil = require("fossil")?;
|
||||
|
||||
print_separator("Fossil");
|
||||
|
||||
run_type.execute(fossil).args(["all", "sync"]).status_checked()
|
||||
ctx.run_type().execute(fossil).args(["all", "sync"]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_micro(run_type: RunType) -> Result<()> {
|
||||
let micro = utils::require("micro")?;
|
||||
pub fn run_micro(ctx: &ExecutionContext) -> Result<()> {
|
||||
let micro = require("micro")?;
|
||||
|
||||
print_separator("micro");
|
||||
|
||||
let stdout = run_type
|
||||
let stdout = ctx
|
||||
.run_type()
|
||||
.execute(micro)
|
||||
.args(["-plugin", "update"])
|
||||
.output_checked_utf8()?
|
||||
@@ -196,38 +196,41 @@ pub fn run_micro(run_type: RunType) -> Result<()> {
|
||||
target_os = "netbsd",
|
||||
target_os = "dragonfly"
|
||||
)))]
|
||||
pub fn run_apm(run_type: RunType) -> Result<()> {
|
||||
let apm = utils::require("apm")?;
|
||||
pub fn run_apm(ctx: &ExecutionContext) -> Result<()> {
|
||||
let apm = require("apm")?;
|
||||
|
||||
print_separator("Atom Package Manager");
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(apm)
|
||||
.args(["upgrade", "--confirm=false"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_rustup(ctx: &ExecutionContext) -> Result<()> {
|
||||
let rustup = utils::require("rustup")?;
|
||||
let rustup = require("rustup")?;
|
||||
|
||||
print_separator("rustup");
|
||||
ctx.run_type().execute(rustup).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_juliaup(run_type: RunType) -> Result<()> {
|
||||
let juliaup = utils::require("juliaup")?;
|
||||
pub fn run_juliaup(ctx: &ExecutionContext) -> Result<()> {
|
||||
let juliaup = require("juliaup")?;
|
||||
|
||||
print_separator("juliaup");
|
||||
|
||||
if juliaup.canonicalize()?.is_descendant_of(&HOME_DIR) {
|
||||
run_type.execute(&juliaup).args(["self", "update"]).status_checked()?;
|
||||
ctx.run_type()
|
||||
.execute(&juliaup)
|
||||
.args(["self", "update"])
|
||||
.status_checked()?;
|
||||
}
|
||||
|
||||
run_type.execute(&juliaup).arg("update").status_checked()
|
||||
ctx.run_type().execute(&juliaup).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_choosenim(ctx: &ExecutionContext) -> Result<()> {
|
||||
let choosenim = utils::require("choosenim")?;
|
||||
let choosenim = require("choosenim")?;
|
||||
|
||||
print_separator("choosenim");
|
||||
let run_type = ctx.run_type();
|
||||
@@ -236,39 +239,42 @@ pub fn run_choosenim(ctx: &ExecutionContext) -> Result<()> {
|
||||
run_type.execute(&choosenim).args(["update", "stable"]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_krew_upgrade(run_type: RunType) -> Result<()> {
|
||||
let krew = utils::require("kubectl-krew")?;
|
||||
pub fn run_krew_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let krew = require("kubectl-krew")?;
|
||||
|
||||
print_separator("Krew");
|
||||
|
||||
run_type.execute(krew).args(["upgrade"]).status_checked()
|
||||
ctx.run_type().execute(krew).args(["upgrade"]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
|
||||
let gcloud = utils::require("gcloud")?;
|
||||
pub fn run_gcloud_components_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gcloud = require("gcloud")?;
|
||||
|
||||
if gcloud.starts_with("/snap") {
|
||||
Ok(())
|
||||
} else {
|
||||
print_separator("gcloud");
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(gcloud)
|
||||
.args(["components", "update", "--quiet"])
|
||||
.status_checked()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_jetpack(run_type: RunType) -> Result<()> {
|
||||
let jetpack = utils::require("jetpack")?;
|
||||
pub fn run_jetpack(ctx: &ExecutionContext) -> Result<()> {
|
||||
let jetpack = require("jetpack")?;
|
||||
|
||||
print_separator("Jetpack");
|
||||
|
||||
run_type.execute(jetpack).args(["global", "update"]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(jetpack)
|
||||
.args(["global", "update"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
||||
let rupdate = utils::require("rupdate")?;
|
||||
let rupdate = require("rupdate")?;
|
||||
|
||||
print_separator("rtcl");
|
||||
|
||||
@@ -276,7 +282,7 @@ pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let opam = utils::require("opam")?;
|
||||
let opam = require("opam")?;
|
||||
|
||||
print_separator("OCaml Package Manager");
|
||||
|
||||
@@ -291,7 +297,7 @@ pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_vcpkg_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let vcpkg = utils::require("vcpkg")?;
|
||||
let vcpkg = require("vcpkg")?;
|
||||
print_separator("vcpkg");
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -303,9 +309,8 @@ pub fn run_vcpkg_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
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)?);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut c = ctx.run_type().execute(sudo);
|
||||
c.arg(&vcpkg);
|
||||
c
|
||||
};
|
||||
@@ -313,15 +318,15 @@ pub fn run_vcpkg_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
command.args(["upgrade", "--no-dry-run"]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
|
||||
let pipx = utils::require("pipx")?;
|
||||
pub fn run_pipx_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pipx = require("pipx")?;
|
||||
print_separator("pipx");
|
||||
|
||||
run_type.execute(pipx).arg("upgrade-all").status_checked()
|
||||
ctx.run_type().execute(pipx).arg("upgrade-all").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let conda = utils::require("conda")?;
|
||||
let conda = require("conda")?;
|
||||
|
||||
let output = Command::new("conda")
|
||||
.args(["config", "--show", "auto_activate_base"])
|
||||
@@ -342,7 +347,7 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_mamba_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let mamba = utils::require("mamba")?;
|
||||
let mamba = require("mamba")?;
|
||||
|
||||
let output = Command::new("mamba")
|
||||
.args(["config", "--show", "auto_activate_base"])
|
||||
@@ -362,8 +367,19 @@ pub fn run_mamba_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
command.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_pip3_update(run_type: RunType) -> Result<()> {
|
||||
let python3 = utils::require("python3")?;
|
||||
pub fn run_pip3_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let py = require("python").and_then(check_is_python_2_or_shim);
|
||||
let py3 = require("python3").and_then(check_is_python_2_or_shim);
|
||||
|
||||
let python3 = match (py, py3) {
|
||||
// prefer `python` if it is available and is a valid Python 3.
|
||||
(Ok(py), _) => py,
|
||||
(Err(_), Ok(py3)) => py3,
|
||||
(Err(py_err), Err(py3_err)) => {
|
||||
return Err(SkipStep(format!("Skip due to following reasons: {} {}", py_err, py3_err)).into());
|
||||
}
|
||||
};
|
||||
|
||||
Command::new(&python3)
|
||||
.args(["-m", "pip"])
|
||||
.output_checked_utf8()
|
||||
@@ -385,12 +401,12 @@ pub fn run_pip3_update(run_type: RunType) -> Result<()> {
|
||||
})?;
|
||||
|
||||
print_separator("pip3");
|
||||
if std::env::var("VIRTUAL_ENV").is_ok() {
|
||||
if env::var("VIRTUAL_ENV").is_ok() {
|
||||
print_warning("This step is will be skipped when running inside a virtual environment");
|
||||
return Err(SkipStep("Does not run inside a virtual environment".to_string()).into());
|
||||
}
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&python3)
|
||||
.args(["-m", "pip", "install", "--upgrade", "--user", "pip"])
|
||||
.status_checked()
|
||||
@@ -414,40 +430,61 @@ pub fn run_pip_review_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn run_pip_review_local_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pip_review = require("pip-review")?;
|
||||
|
||||
print_separator("pip-review (local)");
|
||||
|
||||
if !ctx.config().enable_pip_review_local() {
|
||||
print_warning(
|
||||
"Pip-review (local) is disabled by default. Enable it by setting enable_pip_review_local=true in the configuration.",
|
||||
);
|
||||
return Err(SkipStep(String::from("Pip-review (local) is disabled by default")).into());
|
||||
}
|
||||
ctx.run_type()
|
||||
.execute(pip_review)
|
||||
.arg("--local")
|
||||
.arg("--auto")
|
||||
.status_checked_with_codes(&[1])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn run_pipupgrade_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pipupgrade = require("pipupgrade")?;
|
||||
|
||||
print_separator("Pipupgrade");
|
||||
if !ctx.config().enable_pip_review() {
|
||||
if !ctx.config().enable_pipupgrade() {
|
||||
print_warning(
|
||||
"Pipupgrade is disabled by default. Enable it by setting enable_pipupgrade=true in the configuration.",
|
||||
);
|
||||
return Err(SkipStep(String::from("Pipupgrade is disabled by default")).into());
|
||||
}
|
||||
ctx.run_type().execute(pipupgrade).status_checked()?;
|
||||
ctx.run_type()
|
||||
.execute(pipupgrade)
|
||||
.args(ctx.config().pipupgrade_arguments().split_whitespace())
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_stack_update(run_type: RunType) -> Result<()> {
|
||||
if utils::require("ghcup").is_ok() {
|
||||
pub fn run_stack_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
if require("ghcup").is_ok() {
|
||||
// `ghcup` is present and probably(?) being used to install `stack`.
|
||||
// Don't upgrade `stack`, let `ghcup` handle it. Per `ghcup install stack`:
|
||||
// !!! Additionally, you should upgrade stack only through ghcup and not use 'stack upgrade' !!!
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let stack = utils::require("stack")?;
|
||||
let stack = require("stack")?;
|
||||
print_separator("stack");
|
||||
|
||||
run_type.execute(stack).arg("upgrade").status_checked()
|
||||
ctx.run_type().execute(stack).arg("upgrade").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_ghcup_update(run_type: RunType) -> Result<()> {
|
||||
let ghcup = utils::require("ghcup")?;
|
||||
pub fn run_ghcup_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let ghcup = require("ghcup")?;
|
||||
print_separator("ghcup");
|
||||
|
||||
run_type.execute(ghcup).arg("upgrade").status_checked()
|
||||
ctx.run_type().execute(ghcup).arg("upgrade").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
@@ -459,8 +496,8 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let tlmgr = utils::require("tlmgr")?;
|
||||
let kpsewhich = utils::require("kpsewhich")?;
|
||||
let tlmgr = require("tlmgr")?;
|
||||
let kpsewhich = require("kpsewhich")?;
|
||||
let tlmgr_directory = {
|
||||
let mut d = PathBuf::from(
|
||||
&Command::new(kpsewhich)
|
||||
@@ -482,9 +519,8 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let mut command = if directory_writable {
|
||||
ctx.run_type().execute(&tlmgr)
|
||||
} else {
|
||||
let mut c = ctx
|
||||
.run_type()
|
||||
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut c = ctx.run_type().execute(sudo);
|
||||
c.arg(&tlmgr);
|
||||
c
|
||||
};
|
||||
@@ -493,28 +529,28 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
command.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_chezmoi_update(run_type: RunType) -> Result<()> {
|
||||
let chezmoi = utils::require("chezmoi")?;
|
||||
pub fn run_chezmoi_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let chezmoi = require("chezmoi")?;
|
||||
HOME_DIR.join(".local/share/chezmoi").require()?;
|
||||
|
||||
print_separator("chezmoi");
|
||||
|
||||
run_type.execute(chezmoi).arg("update").status_checked()
|
||||
ctx.run_type().execute(chezmoi).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_myrepos_update(run_type: RunType) -> Result<()> {
|
||||
let myrepos = utils::require("mr")?;
|
||||
pub fn run_myrepos_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let myrepos = require("mr")?;
|
||||
HOME_DIR.join(".mrconfig").require()?;
|
||||
|
||||
print_separator("myrepos");
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&myrepos)
|
||||
.arg("--directory")
|
||||
.arg(&*HOME_DIR)
|
||||
.arg("checkout")
|
||||
.status_checked()?;
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&myrepos)
|
||||
.arg("--directory")
|
||||
.arg(&*HOME_DIR)
|
||||
@@ -536,7 +572,7 @@ pub fn run_custom_command(name: &str, command: &str, ctx: &ExecutionContext) ->
|
||||
}
|
||||
|
||||
pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let composer = utils::require("composer")?;
|
||||
let composer = require("composer")?;
|
||||
let composer_home = Command::new(&composer)
|
||||
.args(["global", "config", "--absolute", "--quiet", "home"])
|
||||
.output_checked_utf8()
|
||||
@@ -564,8 +600,9 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
};
|
||||
|
||||
if has_update {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(ctx.sudo().as_ref().unwrap())
|
||||
.execute(sudo)
|
||||
.arg(&composer)
|
||||
.arg("self-update")
|
||||
.status_checked()?;
|
||||
@@ -581,7 +618,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let output: Utf8Output = output.try_into()?;
|
||||
print!("{}\n{}", output.stdout, output.stderr);
|
||||
if output.stdout.contains("valet") || output.stderr.contains("valet") {
|
||||
if let Some(valet) = utils::which("valet") {
|
||||
if let Some(valet) = which("valet") {
|
||||
ctx.run_type().execute(valet).arg("install").status_checked()?;
|
||||
}
|
||||
}
|
||||
@@ -591,9 +628,10 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let dotnet = utils::require("dotnet")?;
|
||||
let dotnet = require("dotnet")?;
|
||||
|
||||
//Skip when the `dotnet tool list` subcommand fails. (This is expected when a dotnet runtime is installed but no SDK.)
|
||||
// Skip when the `dotnet tool list` subcommand fails.
|
||||
// (This is expected when a dotnet runtime is installed but no SDK.)
|
||||
let output = match ctx
|
||||
.run_type()
|
||||
.execute(&dotnet)
|
||||
@@ -609,11 +647,20 @@ pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
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();
|
||||
let mut packages = output
|
||||
.stdout
|
||||
.lines()
|
||||
// Skip the header:
|
||||
//
|
||||
// Package Id Version Commands
|
||||
// -------------------------------------
|
||||
//
|
||||
// One thing to note is that .NET SDK respect locale, which means this
|
||||
// header can be printed in languages other than English, do NOT use it
|
||||
// to do any check.
|
||||
.skip(2)
|
||||
.filter(|line| !line.is_empty())
|
||||
.peekable();
|
||||
|
||||
if packages.peek().is_none() {
|
||||
return Err(SkipStep(String::from("No dotnet global tools installed")).into());
|
||||
@@ -634,18 +681,19 @@ pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_helix_grammars(ctx: &ExecutionContext) -> Result<()> {
|
||||
utils::require("helix")?;
|
||||
require("helix")?;
|
||||
|
||||
print_separator("Helix");
|
||||
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?)
|
||||
.execute(sudo)
|
||||
.args(["helix", "--grammar", "fetch"])
|
||||
.status_checked()
|
||||
.with_context(|| "Failed to download helix grammars!")?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(ctx.sudo().as_ref().ok_or(TopgradeError::SudoRequired)?)
|
||||
.execute(sudo)
|
||||
.args(["helix", "--grammar", "build"])
|
||||
.status_checked()
|
||||
.with_context(|| "Failed to build helix grammars!")?;
|
||||
@@ -653,30 +701,33 @@ pub fn run_helix_grammars(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_raco_update(run_type: RunType) -> Result<()> {
|
||||
let raco = utils::require("raco")?;
|
||||
pub fn run_raco_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let raco = require("raco")?;
|
||||
|
||||
print_separator("Racket Package Manager");
|
||||
|
||||
run_type.execute(raco).args(["pkg", "update", "--all"]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(raco)
|
||||
.args(["pkg", "update", "--all"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn bin_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let bin = utils::require("bin")?;
|
||||
let bin = require("bin")?;
|
||||
|
||||
print_separator("Bin");
|
||||
ctx.run_type().execute(bin).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let spicetify = utils::require("spicetify")?;
|
||||
let spicetify = require("spicetify")?;
|
||||
|
||||
print_separator("Spicetify");
|
||||
ctx.run_type().execute(spicetify).arg("upgrade").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gh = utils::require("gh")?;
|
||||
let gh = require("gh")?;
|
||||
let result = Command::new(&gh).args(["extensions", "list"]).output_checked_utf8();
|
||||
if result.is_err() {
|
||||
debug!("GH result {:?}", result);
|
||||
@@ -691,7 +742,7 @@ pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let julia = utils::require("julia")?;
|
||||
let julia = require("julia")?;
|
||||
|
||||
print_separator("Julia Packages");
|
||||
|
||||
@@ -701,14 +752,14 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_helm_repo_update(run_type: RunType) -> Result<()> {
|
||||
let helm = utils::require("helm")?;
|
||||
pub fn run_helm_repo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let helm = require("helm")?;
|
||||
|
||||
print_separator("Helm");
|
||||
|
||||
let no_repo = "no repositories found";
|
||||
let mut success = true;
|
||||
let mut exec = run_type.execute(helm);
|
||||
let mut exec = ctx.run_type().execute(helm);
|
||||
if let Err(e) = exec.arg("repo").arg("update").status_checked() {
|
||||
error!("Updating repositories failed: {}", e);
|
||||
success = match exec.output_checked_utf8() {
|
||||
@@ -726,3 +777,18 @@ pub fn run_helm_repo_update(run_type: RunType) -> Result<()> {
|
||||
Err(eyre!(StepFailed))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_stew(ctx: &ExecutionContext) -> Result<()> {
|
||||
let stew = require("stew")?;
|
||||
|
||||
print_separator("stew");
|
||||
ctx.run_type().execute(stew).args(["upgrade", "--all"]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_bob(ctx: &ExecutionContext) -> Result<()> {
|
||||
let bob = require("bob")?;
|
||||
|
||||
print_separator("Bob");
|
||||
|
||||
ctx.run_type().execute(bob).args(["update", "--all"]).status_checked()
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ use tracing::{debug, error};
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{which, PathExt};
|
||||
use crate::{error::SkipStep, terminal::print_warning};
|
||||
@@ -179,22 +178,28 @@ impl Git {
|
||||
None
|
||||
}
|
||||
pub fn multi_pull_step(&self, repositories: &Repositories, ctx: &ExecutionContext) -> Result<()> {
|
||||
// Warn the user about the bad patterns.
|
||||
//
|
||||
// NOTE: this should be executed **before** skipping the Git step or the
|
||||
// user won't receive this warning in the cases where all the paths configured
|
||||
// are bad patterns.
|
||||
repositories
|
||||
.bad_patterns
|
||||
.iter()
|
||||
.for_each(|pattern| print_warning(format!("Path {pattern} did not contain any git repositories")));
|
||||
|
||||
if repositories.repositories.is_empty() {
|
||||
return Err(SkipStep(String::from("No repositories to pull")).into());
|
||||
}
|
||||
|
||||
print_separator("Git repositories");
|
||||
repositories
|
||||
.bad_patterns
|
||||
.iter()
|
||||
.for_each(|pattern| print_warning(format!("Path {pattern} did not contain any git repositories")));
|
||||
self.multi_pull(repositories, ctx)
|
||||
}
|
||||
|
||||
pub fn multi_pull(&self, repositories: &Repositories, ctx: &ExecutionContext) -> Result<()> {
|
||||
let git = self.git.as_ref().unwrap();
|
||||
|
||||
if let RunType::Dry = ctx.run_type() {
|
||||
if ctx.run_type().dry() {
|
||||
repositories
|
||||
.repositories
|
||||
.iter()
|
||||
|
||||
@@ -4,27 +4,27 @@ use std::process::Command;
|
||||
use color_eyre::eyre::Result;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::executor::RunType;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils;
|
||||
use crate::utils::PathExt;
|
||||
|
||||
/// <https://github.com/Gelio/go-global-update>
|
||||
pub fn run_go_global_update(run_type: RunType) -> Result<()> {
|
||||
pub fn run_go_global_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let go_global_update = require_go_bin("go-global-update")?;
|
||||
|
||||
print_separator("go-global-update");
|
||||
|
||||
run_type.execute(go_global_update).status_checked()
|
||||
ctx.run_type().execute(go_global_update).status_checked()
|
||||
}
|
||||
|
||||
/// <https://github.com/nao1215/gup>
|
||||
pub fn run_go_gup(run_type: RunType) -> Result<()> {
|
||||
pub fn run_go_gup(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gup = require_go_bin("gup")?;
|
||||
|
||||
print_separator("gup");
|
||||
|
||||
run_type.execute(gup).arg("update").status_checked()
|
||||
ctx.run_type().execute(gup).arg("update").status_checked()
|
||||
}
|
||||
|
||||
/// Get the path of a Go binary.
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::utils::require_option;
|
||||
use crate::utils::{require_option, REQUIRE_SUDO};
|
||||
use crate::HOME_DIR;
|
||||
use color_eyre::eyre::Result;
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -92,7 +92,7 @@ impl NPM {
|
||||
fn upgrade(&self, ctx: &ExecutionContext, use_sudo: bool) -> Result<()> {
|
||||
let args = ["update", self.global_location_arg()];
|
||||
if use_sudo {
|
||||
let sudo = require_option(ctx.sudo().clone(), String::from("sudo is not installed"))?;
|
||||
let sudo = require_option(ctx.sudo().clone(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&self.command)
|
||||
@@ -156,7 +156,7 @@ impl Yarn {
|
||||
let args = ["global", "upgrade"];
|
||||
|
||||
if use_sudo {
|
||||
let sudo = require_option(ctx.sudo().clone(), String::from("sudo is not installed"))?;
|
||||
let sudo = require_option(ctx.sudo().clone(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(self.yarn.as_ref().unwrap_or(&self.command))
|
||||
@@ -230,7 +230,7 @@ pub fn run_npm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
pub fn run_pnpm_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pnpm = require("pnpm").map(|b| NPM::new(b, NPMVariant::Pnpm))?;
|
||||
|
||||
print_separator("Node Package Manager");
|
||||
print_separator("Performant Node Package Manager");
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
use crate::command::CommandExt;
|
||||
use crate::executor::RunType;
|
||||
use crate::sudo::Sudo;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::require_option;
|
||||
use crate::utils::{require_option, REQUIRE_SUDO};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn upgrade_packages(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("No sudo detected"))?;
|
||||
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
print_separator("DragonFly BSD Packages");
|
||||
run_type
|
||||
.execute(sudo)
|
||||
ctx.execute(sudo)
|
||||
.args(["/usr/local/sbin/pkg", "upgrade"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn audit_packages(sudo: Option<&Sudo>) -> Result<()> {
|
||||
if let Some(sudo) = sudo {
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
.args(["/usr/local/sbin/pkg", "audit", "-Fr"])
|
||||
.status_checked()?;
|
||||
}
|
||||
pub fn audit_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
.args(["/usr/local/sbin/pkg", "audit", "-Fr"])
|
||||
.status_checked()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
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::utils::{require_option, REQUIRE_SUDO};
|
||||
use crate::Step;
|
||||
use color_eyre::eyre::Result;
|
||||
use std::process::Command;
|
||||
|
||||
pub fn upgrade_freebsd(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("No sudo detected"))?;
|
||||
pub fn upgrade_freebsd(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
print_separator("FreeBSD Update");
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["/usr/sbin/freebsd-update", "fetch", "install"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("No sudo detected"))?;
|
||||
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
print_separator("FreeBSD Packages");
|
||||
|
||||
let mut command = run_type.execute(sudo);
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
|
||||
command.args(["/usr/sbin/pkg", "upgrade"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
@@ -30,12 +28,11 @@ pub fn upgrade_packages(ctx: &ExecutionContext, sudo: Option<&Sudo>, run_type: R
|
||||
command.status_checked()
|
||||
}
|
||||
|
||||
pub fn audit_packages(sudo: Option<&Sudo>) -> Result<()> {
|
||||
if let Some(sudo) = sudo {
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
.args(["/usr/sbin/pkg", "audit", "-Fr"])
|
||||
.status_checked()?;
|
||||
}
|
||||
pub fn audit_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
println!();
|
||||
Command::new(sudo)
|
||||
.args(["/usr/sbin/pkg", "audit", "-Fr"])
|
||||
.status_checked()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,12 +8,10 @@ use tracing::{debug, warn};
|
||||
use crate::command::CommandExt;
|
||||
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;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, require_option, which, PathExt, REQUIRE_SUDO};
|
||||
use crate::{Step, HOME_DIR};
|
||||
|
||||
static OS_RELEASE_PATH: &str = "/etc/os-release";
|
||||
|
||||
@@ -30,9 +28,11 @@ pub enum Distribution {
|
||||
Debian,
|
||||
Gentoo,
|
||||
OpenMandriva,
|
||||
OpenSuseTumbleweed,
|
||||
PCLinuxOS,
|
||||
Suse,
|
||||
SuseMicro,
|
||||
Vanilla,
|
||||
Void,
|
||||
Solus,
|
||||
Exherbo,
|
||||
@@ -41,9 +41,10 @@ pub enum Distribution {
|
||||
}
|
||||
|
||||
impl Distribution {
|
||||
fn parse_os_release(os_release: &ini::Ini) -> Result<Self> {
|
||||
fn parse_os_release(os_release: &Ini) -> Result<Self> {
|
||||
let section = os_release.general_section();
|
||||
let id = section.get("ID");
|
||||
let name = section.get("NAME");
|
||||
let variant: Option<Vec<&str>> = section.get("VARIANT").map(|s| s.split_whitespace().collect());
|
||||
let id_like: Option<Vec<&str>> = section.get("ID_LIKE").map(|s| s.split_whitespace().collect());
|
||||
|
||||
@@ -52,20 +53,20 @@ impl Distribution {
|
||||
Some("centos") | Some("rhel") | Some("ol") => Distribution::CentOS,
|
||||
Some("clear-linux-os") => Distribution::ClearLinux,
|
||||
Some("fedora") | Some("nobara") => {
|
||||
if let Some(variant) = variant {
|
||||
return if let Some(variant) = variant {
|
||||
if variant.contains(&"Silverblue") {
|
||||
return Ok(Distribution::FedoraSilverblue);
|
||||
Ok(Distribution::FedoraSilverblue)
|
||||
} else {
|
||||
return Ok(Distribution::Fedora);
|
||||
};
|
||||
Ok(Distribution::Fedora)
|
||||
}
|
||||
} else {
|
||||
return Ok(Distribution::Fedora);
|
||||
Ok(Distribution::Fedora)
|
||||
}
|
||||
}
|
||||
|
||||
Some("void") => Distribution::Void,
|
||||
Some("debian") | Some("pureos") => Distribution::Debian,
|
||||
Some("arch") | Some("anarchy") | Some("manjaro-arm") | Some("garuda") | Some("artix") => Distribution::Arch,
|
||||
Some("debian") | Some("pureos") | Some("Deepin") => Distribution::Debian,
|
||||
Some("arch") | Some("manjaro-arm") | Some("garuda") | Some("artix") => Distribution::Arch,
|
||||
Some("solus") => Distribution::Solus,
|
||||
Some("gentoo") => Distribution::Gentoo,
|
||||
Some("exherbo") => Distribution::Exherbo,
|
||||
@@ -75,13 +76,23 @@ impl Distribution {
|
||||
Some("openmandriva") => Distribution::OpenMandriva,
|
||||
Some("pclinuxos") => Distribution::PCLinuxOS,
|
||||
_ => {
|
||||
if let Some(name) = name {
|
||||
if name.contains("Vanilla") {
|
||||
return Ok(Distribution::Vanilla);
|
||||
}
|
||||
}
|
||||
if let Some(id_like) = id_like {
|
||||
if id_like.contains(&"debian") || id_like.contains(&"ubuntu") {
|
||||
return Ok(Distribution::Debian);
|
||||
} else if id_like.contains(&"centos") {
|
||||
return Ok(Distribution::CentOS);
|
||||
} else if id_like.contains(&"suse") {
|
||||
return Ok(Distribution::Suse);
|
||||
let id_variant = id.unwrap_or_default();
|
||||
return if id_variant.contains("tumbleweed") {
|
||||
Ok(Distribution::OpenSuseTumbleweed)
|
||||
} else {
|
||||
Ok(Distribution::Suse)
|
||||
};
|
||||
} else if id_like.contains(&"arch") || id_like.contains(&"archlinux") {
|
||||
return Ok(Distribution::Arch);
|
||||
} else if id_like.contains(&"alpine") {
|
||||
@@ -122,6 +133,8 @@ impl Distribution {
|
||||
Distribution::Gentoo => upgrade_gentoo(ctx),
|
||||
Distribution::Suse => upgrade_suse(ctx),
|
||||
Distribution::SuseMicro => upgrade_suse_micro(ctx),
|
||||
Distribution::OpenSuseTumbleweed => upgrade_opensuse_tumbleweed(ctx),
|
||||
Distribution::Vanilla => upgrade_vanilla(ctx),
|
||||
Distribution::Void => upgrade_void(ctx),
|
||||
Distribution::Solus => upgrade_solus(ctx),
|
||||
Distribution::Exherbo => upgrade_exherbo(ctx),
|
||||
@@ -145,7 +158,7 @@ impl Distribution {
|
||||
}
|
||||
|
||||
fn update_bedrock(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("Sudo required"))?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
|
||||
ctx.run_type().execute(sudo).args(["brl", "update"]);
|
||||
|
||||
@@ -176,7 +189,7 @@ fn is_wsl() -> Result<bool> {
|
||||
|
||||
fn upgrade_alpine_linux(ctx: &ExecutionContext) -> Result<()> {
|
||||
let apk = require("apk")?;
|
||||
let sudo = ctx.sudo().as_ref().unwrap();
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
|
||||
ctx.run_type().execute(sudo).arg(&apk).arg("update").status_checked()?;
|
||||
ctx.run_type().execute(sudo).arg(&apk).arg("upgrade").status_checked()
|
||||
@@ -191,28 +204,25 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command
|
||||
.arg(which("dnf").unwrap_or_else(|| Path::new("yum").to_path_buf()))
|
||||
.arg(if ctx.config().redhat_distro_sync() {
|
||||
"distro-sync"
|
||||
} else {
|
||||
"upgrade"
|
||||
});
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command
|
||||
.arg(which("dnf").unwrap_or_else(|| Path::new("yum").to_path_buf()))
|
||||
.arg(if ctx.config().redhat_distro_sync() {
|
||||
"distro-sync"
|
||||
} else {
|
||||
"upgrade"
|
||||
});
|
||||
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
|
||||
command.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
|
||||
command.status_checked()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -225,112 +235,136 @@ fn upgrade_fedora_silverblue(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
fn upgrade_bedrock_strata(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(sudo).args(["brl", "update"]).status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type().execute(sudo).args(["brl", "update"]).status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_suse(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["zypper", "refresh"])
|
||||
.status_checked()?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["zypper", "refresh"])
|
||||
.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["zypper", "dist-upgrade"])
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg("zypper")
|
||||
.arg(if ctx.config().suse_dup() {
|
||||
"dist-upgrade"
|
||||
} else {
|
||||
"update"
|
||||
})
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_opensuse_tumbleweed(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["zypper", "refresh"])
|
||||
.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg("zypper")
|
||||
.arg("dist-upgrade")
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_suse_micro(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["transactional-update", "dup"])
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["transactional-update", "dup"])
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_openmandriva(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
|
||||
command.arg(&which("dnf").unwrap()).arg("upgrade");
|
||||
command.arg(&which("dnf").unwrap()).arg("upgrade");
|
||||
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
|
||||
command.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
|
||||
command.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn upgrade_pclinuxos(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let mut command_update = ctx.run_type().execute(sudo);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut command_update = ctx.run_type().execute(sudo);
|
||||
|
||||
command_update.arg(&which("apt-get").unwrap()).arg("update");
|
||||
command_update.arg(&which("apt-get").unwrap()).arg("update");
|
||||
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command_update.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command_update.arg("-y");
|
||||
}
|
||||
|
||||
command_update.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&which("apt-get").unwrap())
|
||||
.arg("dist-upgrade")
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
if let Some(args) = ctx.config().dnf_arguments() {
|
||||
command_update.args(args.split_whitespace());
|
||||
}
|
||||
|
||||
if ctx.config().yes(Step::System) {
|
||||
command_update.arg("-y");
|
||||
}
|
||||
|
||||
command_update.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&which("apt-get").unwrap())
|
||||
.arg("dist-upgrade")
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_vanilla(ctx: &ExecutionContext) -> Result<()> {
|
||||
let apx = require("apx")?;
|
||||
|
||||
let mut update = ctx.run_type().execute(&apx);
|
||||
update.args(["update", "--all"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
update.arg("-y");
|
||||
}
|
||||
update.status_checked()?;
|
||||
|
||||
let mut upgrade = ctx.run_type().execute(&apx);
|
||||
update.args(["upgrade", "--all"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
upgrade.arg("-y");
|
||||
}
|
||||
upgrade.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-Su", "xbps"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-u"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-Su", "xbps"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["xbps-install", "-u"]);
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -338,99 +372,109 @@ fn upgrade_void(ctx: &ExecutionContext) -> Result<()> {
|
||||
fn upgrade_gentoo(ctx: &ExecutionContext) -> Result<()> {
|
||||
let run_type = ctx.run_type();
|
||||
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
if let Some(layman) = which("layman") {
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.arg(layman)
|
||||
.args(["-s", "ALL"])
|
||||
.status_checked()?;
|
||||
}
|
||||
|
||||
println!("Syncing portage");
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
if let Some(layman) = which("layman") {
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.args(["emerge", "--sync"])
|
||||
.args(
|
||||
ctx.config()
|
||||
.emerge_sync_flags()
|
||||
.map(|s| s.split_whitespace().collect())
|
||||
.unwrap_or_else(|| vec!["-q"]),
|
||||
)
|
||||
.arg(layman)
|
||||
.args(["-s", "ALL"])
|
||||
.status_checked()?;
|
||||
|
||||
if let Some(eix_update) = which("eix-update") {
|
||||
run_type.execute(sudo).arg(eix_update).status_checked()?;
|
||||
}
|
||||
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.arg("emerge")
|
||||
.args(
|
||||
ctx.config()
|
||||
.emerge_update_flags()
|
||||
.map(|s| s.split_whitespace().collect())
|
||||
.unwrap_or_else(|| vec!["-uDNa", "--with-bdeps=y", "world"]),
|
||||
)
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
println!("Syncing portage");
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.args(["emerge", "--sync"])
|
||||
.args(
|
||||
ctx.config()
|
||||
.emerge_sync_flags()
|
||||
.map(|s| s.split_whitespace().collect())
|
||||
.unwrap_or_else(|| vec!["-q"]),
|
||||
)
|
||||
.status_checked()?;
|
||||
|
||||
if let Some(eix_update) = which("eix-update") {
|
||||
run_type.execute(sudo).arg(eix_update).status_checked()?;
|
||||
}
|
||||
|
||||
run_type
|
||||
.execute(sudo)
|
||||
.arg("emerge")
|
||||
.args(
|
||||
ctx.config()
|
||||
.emerge_update_flags()
|
||||
.map(|s| s.split_whitespace().collect())
|
||||
.unwrap_or_else(|| vec!["-uDNa", "--with-bdeps=y", "world"]),
|
||||
)
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_debian(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let apt = which("apt-fast")
|
||||
.or_else(|| {
|
||||
if which("mist").is_some() {
|
||||
Some(PathBuf::from("mist"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
if Path::new("/usr/bin/nala").exists() {
|
||||
Some(Path::new("/usr/bin/nala").to_path_buf())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| PathBuf::from("apt-get"));
|
||||
let apt = which("apt-fast")
|
||||
.or_else(|| {
|
||||
if which("mist").is_some() {
|
||||
Some(PathBuf::from("mist"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
if Path::new("/usr/bin/nala").exists() {
|
||||
Some(Path::new("/usr/bin/nala").to_path_buf())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|| PathBuf::from("apt-get"));
|
||||
|
||||
let is_nala = apt.ends_with("nala");
|
||||
if !is_nala {
|
||||
ctx.run_type().execute(sudo).arg(&apt).arg("update").status_checked()?;
|
||||
}
|
||||
let is_mist = apt.ends_with("mist");
|
||||
let is_nala = apt.ends_with("nala");
|
||||
|
||||
// MIST does not require `sudo`
|
||||
if is_mist {
|
||||
ctx.run_type().execute(&apt).arg("update").status_checked()?;
|
||||
ctx.run_type().execute(&apt).arg("upgrade").status_checked()?;
|
||||
|
||||
// Simply return as MIST does not have `clean` and `autoremove`
|
||||
// subcommands, neither the `-y` option (for now maybe?).
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
if !is_nala {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&apt)
|
||||
.arg("update")
|
||||
.status_checked_with_codes(&[0, 100])?;
|
||||
}
|
||||
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&apt);
|
||||
if is_nala {
|
||||
command.arg("upgrade");
|
||||
} else {
|
||||
command.arg("dist-upgrade");
|
||||
};
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
if let Some(args) = ctx.config().apt_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type().execute(sudo).arg(&apt).arg("clean").status_checked()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&apt);
|
||||
if is_nala {
|
||||
command.arg("upgrade");
|
||||
} else {
|
||||
command.arg("dist-upgrade");
|
||||
};
|
||||
command.arg(&apt).arg("autoremove");
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
if let Some(args) = ctx.config().apt_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type().execute(sudo).arg(&apt).arg("clean").status_checked()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&apt).arg("autoremove");
|
||||
if ctx.config().yes(Step::System) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
}
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -441,38 +485,48 @@ pub fn run_deb_get(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
print_separator("deb-get");
|
||||
|
||||
ctx.execute_elevated(&deb_get, false)?.arg("update").status_checked()?;
|
||||
ctx.execute_elevated(&deb_get, false)?.arg("upgrade").status_checked()?;
|
||||
ctx.run_type().execute(&deb_get).arg("update").status_checked()?;
|
||||
ctx.run_type().execute(&deb_get).arg("upgrade").status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.execute_elevated(&deb_get, false)?.arg("clean").status_checked()?;
|
||||
ctx.run_type().execute(&deb_get).arg("clean").status_checked()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_solus(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["eopkg", "upgrade"])
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["eopkg", "upgrade"])
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_am(ctx: &ExecutionContext) -> Result<()> {
|
||||
pub fn run_am(ctx: &ExecutionContext) -> Result<()> {
|
||||
let am = require("am")?;
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(sudo).arg(am).arg("-u").status_checked()?;
|
||||
|
||||
print_separator("AM");
|
||||
|
||||
let mut am = ctx.run_type().execute(am);
|
||||
|
||||
if ctx.config().yes(Step::AM) {
|
||||
am.arg("-U");
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping AM Step");
|
||||
am.arg("-u");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
am.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_appman(ctx: &ExecutionContext) -> Result<()> {
|
||||
let appman = require("appman")?;
|
||||
|
||||
print_separator("appman");
|
||||
|
||||
ctx.run_type().execute(appman).arg("-u").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_pacdef(ctx: &ExecutionContext) -> Result<()> {
|
||||
@@ -521,69 +575,79 @@ pub fn run_pacstall(ctx: &ExecutionContext) -> Result<()> {
|
||||
upgrade_cmd.arg("-Up").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_packer_nu(ctx: &ExecutionContext) -> Result<()> {
|
||||
let nu = require("nu")?;
|
||||
let packer_home = HOME_DIR.join(".local/share/nushell/packer");
|
||||
|
||||
packer_home.clone().require()?;
|
||||
|
||||
print_separator("packer.nu");
|
||||
|
||||
ctx.run_type()
|
||||
.execute(nu)
|
||||
.env("PWD", "/")
|
||||
.env("NU_PACKER_HOME", packer_home)
|
||||
.args([
|
||||
"-c",
|
||||
"use ~/.local/share/nushell/packer/start/packer.nu/api_layer/packer.nu; packer update",
|
||||
])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
fn upgrade_clearlinux(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["swupd", "update"])
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["swupd", "update"])
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_exherbo(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
ctx.run_type().execute(sudo).args(["cave", "sync"]).status_checked()?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
ctx.run_type().execute(sudo).args(["cave", "sync"]).status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["cave", "resolve", "world", "-c1", "-Cs", "-km", "-Km", "-x"])
|
||||
.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["cave", "resolve", "world", "-c1", "-Cs", "-km", "-Km", "-x"])
|
||||
.args(["cave", "purge", "-x"])
|
||||
.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["cave", "purge", "-x"])
|
||||
.status_checked()?;
|
||||
}
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["cave", "fix-linkage", "-x", "--", "-Cs"])
|
||||
.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["eclectic", "config", "interactive"])
|
||||
.status_checked()?;
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
}
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["cave", "fix-linkage", "-x", "--", "-Cs"])
|
||||
.status_checked()?;
|
||||
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["eclectic", "config", "interactive"])
|
||||
.status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn upgrade_nixos(ctx: &ExecutionContext) -> Result<()> {
|
||||
if let Some(sudo) = ctx.sudo() {
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"]);
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.args(["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"]);
|
||||
|
||||
if let Some(args) = ctx.config().nix_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
command.status_checked()?;
|
||||
if let Some(args) = ctx.config().nix_arguments() {
|
||||
command.args(args.split_whitespace());
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["/run/current-system/sw/bin/nix-collect-garbage", "-d"])
|
||||
.status_checked()?;
|
||||
}
|
||||
} else {
|
||||
print_warning("No sudo detected. Skipping system upgrade");
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(["/run/current-system/sw/bin/nix-collect-garbage", "-d"])
|
||||
.status_checked()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -595,31 +659,31 @@ fn upgrade_neon(ctx: &ExecutionContext) -> Result<()> {
|
||||
// in theory rpm based distributions use pkcon as well, though that
|
||||
// seems rare
|
||||
// if that comes up we need to create a Distribution::PackageKit or some such
|
||||
if let Some(sudo) = &ctx.sudo() {
|
||||
let pkcon = which("pkcon").unwrap();
|
||||
// pkcon ignores update with update and refresh provided together
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&pkcon)
|
||||
.arg("refresh")
|
||||
.status_checked()?;
|
||||
let mut exe = ctx.run_type().execute(sudo);
|
||||
let cmd = exe.arg(&pkcon).arg("update");
|
||||
if ctx.config().yes(Step::System) {
|
||||
cmd.arg("-y");
|
||||
}
|
||||
if ctx.config().cleanup() {
|
||||
cmd.arg("--autoremove");
|
||||
}
|
||||
// from pkcon man, exit code 5 is 'Nothing useful was done.'
|
||||
cmd.status_checked_with_codes(&[5])?;
|
||||
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let pkcon = which("pkcon").unwrap();
|
||||
// pkcon ignores update with update and refresh provided together
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.arg(&pkcon)
|
||||
.arg("refresh")
|
||||
.status_checked()?;
|
||||
let mut exe = ctx.run_type().execute(sudo);
|
||||
let cmd = exe.arg(&pkcon).arg("update");
|
||||
if ctx.config().yes(Step::System) {
|
||||
cmd.arg("-y");
|
||||
}
|
||||
if ctx.config().cleanup() {
|
||||
cmd.arg("--autoremove");
|
||||
}
|
||||
// from pkcon man, exit code 5 is 'Nothing useful was done.'
|
||||
cmd.status_checked_with_codes(&[5])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_needrestart(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
|
||||
pub fn run_needrestart(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let needrestart = require("needrestart")?;
|
||||
let distribution = Distribution::detect()?;
|
||||
|
||||
@@ -629,7 +693,7 @@ pub fn run_needrestart(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("Check for needed restarts");
|
||||
|
||||
run_type.execute(sudo).arg(needrestart).status_checked()?;
|
||||
ctx.run_type().execute(sudo).arg(needrestart).status_checked()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -661,9 +725,9 @@ pub fn run_fwupdmgr(ctx: &ExecutionContext) -> Result<()> {
|
||||
updmgr.status_checked_with_codes(&[2])
|
||||
}
|
||||
|
||||
pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
pub fn run_flatpak(ctx: &ExecutionContext) -> Result<()> {
|
||||
let flatpak = require("flatpak")?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("sudo is not installed"))?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let cleanup = ctx.config().cleanup();
|
||||
let yes = ctx.config().yes(Step::Flatpak);
|
||||
let run_type = ctx.run_type();
|
||||
@@ -723,8 +787,8 @@ pub fn flatpak_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_snap(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
|
||||
pub fn run_snap(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let snap = require("snap")?;
|
||||
|
||||
if !PathBuf::from("/var/snapd.socket").exists() && !PathBuf::from("/run/snapd.socket").exists() {
|
||||
@@ -732,17 +796,17 @@ pub fn run_snap(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
}
|
||||
print_separator("snap");
|
||||
|
||||
run_type.execute(sudo).arg(snap).arg("refresh").status_checked()
|
||||
ctx.run_type().execute(sudo).arg(snap).arg("refresh").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_pihole_update(sudo: Option<&Sudo>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("sudo is not installed"))?;
|
||||
pub fn run_pihole_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let pihole = require("pihole")?;
|
||||
Path::new("/opt/pihole/update.sh").require()?;
|
||||
|
||||
print_separator("pihole");
|
||||
|
||||
run_type.execute(sudo).arg(pihole).arg("-up").status_checked()
|
||||
ctx.run_type().execute(sudo).arg(pihole).arg("-up").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_protonup_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
@@ -780,7 +844,7 @@ pub fn run_distrobox_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_dkp_pacman_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("sudo is not installed"))?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
let dkp_pacman = require("dkp-pacman")?;
|
||||
|
||||
print_separator("Devkitpro pacman");
|
||||
@@ -803,7 +867,7 @@ pub fn run_dkp_pacman_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn run_config_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), String::from("sudo is not installed"))?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
if ctx.config().yes(Step::ConfigUpdate) {
|
||||
return Err(SkipStep("Skipped in --yes".to_string()).into());
|
||||
}
|
||||
@@ -886,11 +950,6 @@ mod tests {
|
||||
test_template(include_str!("os_release/fedora"), Distribution::Fedora);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_antergos() {
|
||||
test_template(include_str!("os_release/antergos"), Distribution::Arch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manjaro() {
|
||||
test_template(include_str!("os_release/manjaro"), Distribution::Arch);
|
||||
@@ -901,11 +960,6 @@ mod tests {
|
||||
test_template(include_str!("os_release/manjaro-arm"), Distribution::Arch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anarchy() {
|
||||
test_template(include_str!("os_release/anarchy"), Distribution::Arch);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gentoo() {
|
||||
test_template(include_str!("os_release/gentoo"), Distribution::Gentoo);
|
||||
@@ -950,4 +1004,14 @@ mod tests {
|
||||
fn test_pureos() {
|
||||
test_template(include_str!("os_release/pureos"), Distribution::Debian);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deepin() {
|
||||
test_template(include_str!("os_release/deepin"), Distribution::Debian);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vanilla() {
|
||||
test_template(include_str!("os_release/vanilla"), Distribution::Vanilla);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::{print_separator, prompt_yesno};
|
||||
use crate::utils::{require_option, REQUIRE_SUDO};
|
||||
use crate::{utils::require, Step};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::fs;
|
||||
@@ -10,7 +10,8 @@ use tracing::debug;
|
||||
|
||||
pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
|
||||
require("port")?;
|
||||
let sudo = ctx.sudo().as_ref().unwrap();
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
|
||||
print_separator("MacPorts");
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
@@ -30,11 +31,11 @@ pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_mas(run_type: RunType) -> Result<()> {
|
||||
pub fn run_mas(ctx: &ExecutionContext) -> Result<()> {
|
||||
let mas = require("mas")?;
|
||||
print_separator("macOS App Store");
|
||||
|
||||
run_type.execute(mas).arg("upgrade").status_checked()
|
||||
ctx.run_type().execute(mas).arg("upgrade").status_checked()
|
||||
}
|
||||
|
||||
pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
use crate::executor::RunType;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::require_option;
|
||||
use crate::utils::{require_option, REQUIRE_SUDO};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn upgrade_openbsd(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("No sudo detected"))?;
|
||||
pub fn upgrade_openbsd(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
print_separator("OpenBSD Update");
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(&["/usr/sbin/sysupgrade", "-n"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn upgrade_packages(sudo: Option<&PathBuf>, run_type: RunType) -> Result<()> {
|
||||
let sudo = require_option(sudo, String::from("No sudo detected"))?;
|
||||
pub fn upgrade_packages(ctx: &ExecutionContext) -> Result<()> {
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
print_separator("OpenBSD Packages");
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(sudo)
|
||||
.args(&["/usr/sbin/pkg_add", "-u"])
|
||||
.status_checked()
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
NAME="Anarchy Linux"
|
||||
PRETTY_NAME="Anarchy Linux"
|
||||
ID=anarchy
|
||||
ID_LIKE=anarchylinux
|
||||
ANSI_COLOR="0;36"
|
||||
HOME_URL="https://anarchylinux.org/"
|
||||
@@ -1,10 +0,0 @@
|
||||
NAME="Antergos Linux"
|
||||
VERSION="18.7-ISO-Rolling"
|
||||
ID="antergos"
|
||||
ID_LIKE="arch"
|
||||
PRETTY_NAME="Antergos Linux"
|
||||
CPE_NAME="cpe:/o:antergosproject:antergos:18.7"
|
||||
ANSI_COLOR="1;34;40"
|
||||
HOME_URL="antergos.com"
|
||||
SUPPORT_URL="forum.antergos.com"
|
||||
BUG_REPORT_URL="@antergos"
|
||||
8
src/steps/os/os_release/deepin
Normal file
8
src/steps/os/os_release/deepin
Normal file
@@ -0,0 +1,8 @@
|
||||
PRETTY_NAME="Deepin 20.9"
|
||||
NAME="Deepin"
|
||||
VERSION_ID="20.9"
|
||||
VERSION="20.9"
|
||||
VERSION_CODENAME="apricot"
|
||||
ID=Deepin
|
||||
HOME_URL="https://www.deepin.org/"
|
||||
BUG_REPORT_URL="https://bbs.deepin.org/"
|
||||
12
src/steps/os/os_release/vanilla
Normal file
12
src/steps/os/os_release/vanilla
Normal file
@@ -0,0 +1,12 @@
|
||||
PRETTY_NAME="VanillaOS 22.10 all"
|
||||
NAME="VanillaOS"
|
||||
VERSION_ID="22.10"
|
||||
VERSION="22.10 all"
|
||||
VERSION_CODENAME="kinetic"
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
HOME_URL="https://github.com/vanilla-os"
|
||||
SUPPORT_URL="https://github.com/vanilla-os"
|
||||
BUG_REPORT_URL="https://github.com/vanilla-os"
|
||||
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
|
||||
UBUNTU_CODENAME="kinetic"
|
||||
@@ -2,7 +2,7 @@ use std::fs;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::{env, path::Path};
|
||||
use std::{env::var, path::Path};
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::{Step, HOME_DIR};
|
||||
@@ -15,11 +15,10 @@ use crate::error::SkipStep;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
use crate::executor::Executor;
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
#[cfg(not(any(target_os = "android", target_os = "macos")))]
|
||||
use crate::utils::require_option;
|
||||
use crate::utils::{require, PathExt};
|
||||
use crate::utils::{require, require_option, PathExt, REQUIRE_SUDO};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
const INTEL_BREW: &str = "/usr/local/bin/brew";
|
||||
@@ -86,7 +85,7 @@ impl BrewVariant {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_fisher(run_type: RunType) -> Result<()> {
|
||||
pub fn run_fisher(ctx: &ExecutionContext) -> Result<()> {
|
||||
let fish = require("fish")?;
|
||||
|
||||
Command::new(&fish)
|
||||
@@ -109,7 +108,8 @@ pub fn run_fisher(run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("Fisher");
|
||||
|
||||
let version_str = run_type
|
||||
let version_str = ctx
|
||||
.run_type()
|
||||
.execute(&fish)
|
||||
.args(["-c", "fisher --version"])
|
||||
.output_checked_utf8()?
|
||||
@@ -118,10 +118,13 @@ pub fn run_fisher(run_type: RunType) -> Result<()> {
|
||||
|
||||
if version_str.starts_with("fisher version 3.") {
|
||||
// v3 - see https://github.com/topgrade-rs/topgrade/pull/37#issuecomment-1283844506
|
||||
run_type.execute(&fish).args(["-c", "fisher"]).status_checked()
|
||||
ctx.run_type().execute(&fish).args(["-c", "fisher"]).status_checked()
|
||||
} else {
|
||||
// v4
|
||||
run_type.execute(&fish).args(["-c", "fisher update"]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(&fish)
|
||||
.args(["-c", "fisher update"])
|
||||
.status_checked()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +139,27 @@ pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_oh_my_bash(ctx: &ExecutionContext) -> Result<()> {
|
||||
require("bash")?;
|
||||
let oh_my_bash = var("OSH")
|
||||
// default to `~/.oh-my-bash`
|
||||
.unwrap_or(
|
||||
HOME_DIR
|
||||
.join(".oh-my-bash")
|
||||
.to_str()
|
||||
.expect("should be UTF-8 encoded")
|
||||
.to_string(),
|
||||
)
|
||||
.require()?;
|
||||
|
||||
print_separator("oh-my-bash");
|
||||
|
||||
let mut update_script = oh_my_bash;
|
||||
update_script.push_str("tools/upgrade.sh");
|
||||
|
||||
ctx.run_type().execute("bash").arg(update_script).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
|
||||
let fish = require("fish")?;
|
||||
HOME_DIR.join(".local/share/omf/pkg/omf/functions/omf.fish").require()?;
|
||||
@@ -147,17 +171,18 @@ pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pkgin = require("pkgin")?;
|
||||
let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
|
||||
|
||||
print_separator("Pkgin");
|
||||
|
||||
let mut command = ctx.run_type().execute(ctx.sudo().as_ref().unwrap());
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&pkgin).arg("update");
|
||||
if ctx.config().yes(Step::Pkgin) {
|
||||
command.arg("-y");
|
||||
}
|
||||
command.status_checked()?;
|
||||
|
||||
let mut command = ctx.run_type().execute(ctx.sudo().as_ref().unwrap());
|
||||
let mut command = ctx.run_type().execute(sudo);
|
||||
command.arg(&pkgin).arg("upgrade");
|
||||
if ctx.config().yes(Step::Pkgin) {
|
||||
command.arg("-y");
|
||||
@@ -200,7 +225,7 @@ pub fn run_fundle(ctx: &ExecutionContext) -> Result<()> {
|
||||
pub fn upgrade_gnome_extensions(ctx: &ExecutionContext) -> Result<()> {
|
||||
let gdbus = require("gdbus")?;
|
||||
require_option(
|
||||
env::var("XDG_CURRENT_DESKTOP").ok().filter(|p| p.contains("GNOME")),
|
||||
var("XDG_CURRENT_DESKTOP").ok().filter(|p| p.contains("GNOME")),
|
||||
"Desktop doest not appear to be gnome".to_string(),
|
||||
)?;
|
||||
let output = Command::new("gdbus")
|
||||
@@ -378,7 +403,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
run_type.execute(nix_channel).arg("--update").status_checked()?;
|
||||
|
||||
if std::path::Path::new(&manifest_json_path).exists() {
|
||||
if Path::new(&manifest_json_path).exists() {
|
||||
run_type
|
||||
.execute(&nix)
|
||||
.arg("profile")
|
||||
@@ -398,43 +423,46 @@ pub fn run_yadm(ctx: &ExecutionContext) -> Result<()> {
|
||||
ctx.run_type().execute(yadm).arg("pull").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_asdf(run_type: RunType) -> Result<()> {
|
||||
pub fn run_asdf(ctx: &ExecutionContext) -> Result<()> {
|
||||
let asdf = require("asdf")?;
|
||||
|
||||
print_separator("asdf");
|
||||
run_type.execute(&asdf).arg("update").status_checked_with_codes(&[42])?;
|
||||
ctx.run_type()
|
||||
.execute(&asdf)
|
||||
.arg("update")
|
||||
.status_checked_with_codes(&[42])?;
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&asdf)
|
||||
.args(["plugin", "update", "--all"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_home_manager(run_type: RunType) -> Result<()> {
|
||||
pub fn run_home_manager(ctx: &ExecutionContext) -> Result<()> {
|
||||
let home_manager = require("home-manager")?;
|
||||
|
||||
print_separator("home-manager");
|
||||
run_type.execute(home_manager).arg("switch").status_checked()
|
||||
ctx.run_type().execute(home_manager).arg("switch").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_tldr(run_type: RunType) -> Result<()> {
|
||||
pub fn run_tldr(ctx: &ExecutionContext) -> Result<()> {
|
||||
let tldr = require("tldr")?;
|
||||
|
||||
print_separator("TLDR");
|
||||
run_type.execute(tldr).arg("--update").status_checked()
|
||||
ctx.run_type().execute(tldr).arg("--update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_pearl(run_type: RunType) -> Result<()> {
|
||||
pub fn run_pearl(ctx: &ExecutionContext) -> Result<()> {
|
||||
let pearl = require("pearl")?;
|
||||
print_separator("pearl");
|
||||
|
||||
run_type.execute(pearl).arg("update").status_checked()
|
||||
ctx.run_type().execute(pearl).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_sdkman(cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
pub fn run_sdkman(ctx: &ExecutionContext) -> Result<()> {
|
||||
let bash = require("bash")?;
|
||||
|
||||
let sdkman_init_path = env::var("SDKMAN_DIR")
|
||||
let sdkman_init_path = var("SDKMAN_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|_| HOME_DIR.join(".sdkman"))
|
||||
.join("bin")
|
||||
@@ -444,7 +472,7 @@ pub fn run_sdkman(cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("SDKMAN!");
|
||||
|
||||
let sdkman_config_path = env::var("SDKMAN_DIR")
|
||||
let sdkman_config_path = var("SDKMAN_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|_| HOME_DIR.join(".sdkman"))
|
||||
.join("etc")
|
||||
@@ -459,33 +487,33 @@ pub fn run_sdkman(cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
|
||||
if selfupdate_enabled == "true" {
|
||||
let cmd_selfupdate = format!("source {} && sdk selfupdate", &sdkman_init_path);
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&bash)
|
||||
.args(["-c", cmd_selfupdate.as_str()])
|
||||
.status_checked()?;
|
||||
}
|
||||
|
||||
let cmd_update = format!("source {} && sdk update", &sdkman_init_path);
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&bash)
|
||||
.args(["-c", cmd_update.as_str()])
|
||||
.status_checked()?;
|
||||
|
||||
let cmd_upgrade = format!("source {} && sdk upgrade", &sdkman_init_path);
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&bash)
|
||||
.args(["-c", cmd_upgrade.as_str()])
|
||||
.status_checked()?;
|
||||
|
||||
if cleanup {
|
||||
if ctx.config().cleanup() {
|
||||
let cmd_flush_archives = format!("source {} && sdk flush archives", &sdkman_init_path);
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&bash)
|
||||
.args(["-c", cmd_flush_archives.as_str()])
|
||||
.status_checked()?;
|
||||
|
||||
let cmd_flush_temp = format!("source {} && sdk flush temp", &sdkman_init_path);
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(&bash)
|
||||
.args(["-c", cmd_flush_temp.as_str()])
|
||||
.status_checked()?;
|
||||
@@ -512,6 +540,13 @@ pub fn run_rcm(ctx: &ExecutionContext) -> Result<()> {
|
||||
ctx.run_type().execute(rcup).arg("-v").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_maza(ctx: &ExecutionContext) -> Result<()> {
|
||||
let maza = require("maza")?;
|
||||
|
||||
print_separator("maza");
|
||||
ctx.run_type().execute(maza).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn reboot() -> Result<()> {
|
||||
print!("Rebooting...");
|
||||
Command::new("sudo").arg("reboot").status_checked()
|
||||
|
||||
@@ -8,7 +8,6 @@ use tracing::debug;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::{print_separator, print_warning};
|
||||
use crate::utils::require;
|
||||
use crate::{error::SkipStep, steps::git::Repositories};
|
||||
@@ -54,16 +53,16 @@ pub fn run_winget(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_scoop(cleanup: bool, run_type: RunType) -> Result<()> {
|
||||
pub fn run_scoop(ctx: &ExecutionContext) -> Result<()> {
|
||||
let scoop = require("scoop")?;
|
||||
|
||||
print_separator("Scoop");
|
||||
|
||||
run_type.execute(&scoop).args(["update"]).status_checked()?;
|
||||
run_type.execute(&scoop).args(["update", "*"]).status_checked()?;
|
||||
ctx.run_type().execute(&scoop).args(["update"]).status_checked()?;
|
||||
ctx.run_type().execute(&scoop).args(["update", "*"]).status_checked()?;
|
||||
|
||||
if cleanup {
|
||||
run_type.execute(&scoop).args(["cleanup", "*"]).status_checked()?;
|
||||
if ctx.config().cleanup() {
|
||||
ctx.run_type().execute(&scoop).args(["cleanup", "*"]).status_checked()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -7,7 +7,6 @@ use color_eyre::eyre::Context;
|
||||
use color_eyre::eyre::Result;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::executor::RunType;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::HOME_DIR;
|
||||
use crate::{
|
||||
@@ -18,12 +17,12 @@ use crate::{
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::CommandExt as _;
|
||||
|
||||
pub fn run_tpm(run_type: RunType) -> Result<()> {
|
||||
pub fn run_tpm(ctx: &ExecutionContext) -> Result<()> {
|
||||
let tpm = HOME_DIR.join(".tmux/plugins/tpm/bin/update_plugins").require()?;
|
||||
|
||||
print_separator("tmux plugins");
|
||||
|
||||
run_type.execute(tpm).arg("all").status_checked()
|
||||
ctx.run_type().execute(tpm).arg("all").status_checked()
|
||||
}
|
||||
|
||||
struct Tmux {
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
" AstroUpdate calls a plugin manager - Lazy as of this writing. So we check for it before
|
||||
" others. Add to init.lua:
|
||||
" updater = {
|
||||
" skip_prompts = true,
|
||||
" },
|
||||
if exists(":AstroUpdate")
|
||||
echo "AstroUpdate"
|
||||
AstroUpdate
|
||||
quitall
|
||||
endif
|
||||
|
||||
if exists(":NeoBundleUpdate")
|
||||
echo "NeoBundle"
|
||||
NeoBundleUpdate
|
||||
@@ -38,11 +49,6 @@ if exists(":Lazy")
|
||||
Lazy! sync | qa
|
||||
endif
|
||||
|
||||
if exists(":AstroUpdate")
|
||||
echo "AstroUpdate"
|
||||
AstroUpdate
|
||||
endif
|
||||
|
||||
if exists(':PackerSync')
|
||||
echo "Packer"
|
||||
autocmd User PackerComplete quitall
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::HOME_DIR;
|
||||
use color_eyre::eyre::Result;
|
||||
use etcetera::base_strategy::BaseStrategy;
|
||||
|
||||
use crate::executor::{Executor, ExecutorOutput, RunType};
|
||||
use crate::executor::{Executor, ExecutorOutput};
|
||||
use crate::terminal::print_separator;
|
||||
use crate::{
|
||||
execution_context::ExecutionContext,
|
||||
@@ -141,10 +141,10 @@ pub fn upgrade_neovim(ctx: &ExecutionContext) -> Result<()> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn run_voom(run_type: RunType) -> Result<()> {
|
||||
pub fn run_voom(ctx: &ExecutionContext) -> Result<()> {
|
||||
let voom = require("voom")?;
|
||||
|
||||
print_separator("voom");
|
||||
|
||||
run_type.execute(voom).arg("update").status_checked()
|
||||
ctx.run_type().execute(voom).arg("update").status_checked()
|
||||
}
|
||||
|
||||
@@ -8,13 +8,12 @@ use walkdir::WalkDir;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::executor::RunType;
|
||||
use crate::git::Repositories;
|
||||
use crate::terminal::print_separator;
|
||||
use crate::utils::{require, PathExt};
|
||||
use crate::HOME_DIR;
|
||||
|
||||
pub fn run_zr(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zr(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
|
||||
require("zr")?;
|
||||
@@ -22,7 +21,10 @@ pub fn run_zr(run_type: RunType) -> Result<()> {
|
||||
print_separator("zr");
|
||||
|
||||
let cmd = format!("source {} && zr --update", zshrc().display());
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-l", "-c", cmd.as_str()])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
fn zdotdir() -> PathBuf {
|
||||
@@ -49,16 +51,16 @@ pub fn run_antidote(ctx: &ExecutionContext) -> Result<()> {
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_antibody(run_type: RunType) -> Result<()> {
|
||||
pub fn run_antibody(ctx: &ExecutionContext) -> Result<()> {
|
||||
require("zsh")?;
|
||||
let antibody = require("antibody")?;
|
||||
|
||||
print_separator("antibody");
|
||||
|
||||
run_type.execute(antibody).arg("update").status_checked()
|
||||
ctx.run_type().execute(antibody).arg("update").status_checked()
|
||||
}
|
||||
|
||||
pub fn run_antigen(run_type: RunType) -> Result<()> {
|
||||
pub fn run_antigen(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc().require()?;
|
||||
env::var("ADOTDIR")
|
||||
@@ -69,10 +71,13 @@ pub fn run_antigen(run_type: RunType) -> Result<()> {
|
||||
print_separator("antigen");
|
||||
|
||||
let cmd = format!("source {} && (antigen selfupdate ; antigen update)", zshrc.display());
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-l", "-c", cmd.as_str()])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_zgenom(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zgenom(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc().require()?;
|
||||
env::var("ZGEN_SOURCE")
|
||||
@@ -83,10 +88,13 @@ pub fn run_zgenom(run_type: RunType) -> Result<()> {
|
||||
print_separator("zgenom");
|
||||
|
||||
let cmd = format!("source {} && zgenom selfupdate && zgenom update", zshrc.display());
|
||||
run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-l", "-c", cmd.as_str()])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_zplug(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zplug(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
zshrc().require()?;
|
||||
|
||||
@@ -97,13 +105,13 @@ pub fn run_zplug(run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("zplug");
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-i", "-c", "zplug update"])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_zinit(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zinit(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc().require()?;
|
||||
|
||||
@@ -115,10 +123,13 @@ pub fn run_zinit(run_type: RunType) -> Result<()> {
|
||||
print_separator("zinit");
|
||||
|
||||
let cmd = format!("source {} && zinit self-update && zinit update --all", zshrc.display(),);
|
||||
run_type.execute(zsh).args(["-i", "-c", cmd.as_str()]).status_checked()
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-i", "-c", cmd.as_str()])
|
||||
.status_checked()
|
||||
}
|
||||
|
||||
pub fn run_zi(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zi(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
let zshrc = zshrc().require()?;
|
||||
|
||||
@@ -127,10 +138,10 @@ pub fn run_zi(run_type: RunType) -> Result<()> {
|
||||
print_separator("zi");
|
||||
|
||||
let cmd = format!("source {} && zi self-update && zi update --all", zshrc.display(),);
|
||||
run_type.execute(zsh).args(["-i", "-c", &cmd]).status_checked()
|
||||
ctx.run_type().execute(zsh).args(["-i", "-c", &cmd]).status_checked()
|
||||
}
|
||||
|
||||
pub fn run_zim(run_type: RunType) -> Result<()> {
|
||||
pub fn run_zim(ctx: &ExecutionContext) -> Result<()> {
|
||||
let zsh = require("zsh")?;
|
||||
env::var("ZIM_HOME")
|
||||
.or_else(|_| {
|
||||
@@ -146,7 +157,7 @@ pub fn run_zim(run_type: RunType) -> Result<()> {
|
||||
|
||||
print_separator("zim");
|
||||
|
||||
run_type
|
||||
ctx.run_type()
|
||||
.execute(zsh)
|
||||
.args(["-i", "-c", "zimfw upgrade && zimfw update"])
|
||||
.status_checked()
|
||||
@@ -154,7 +165,11 @@ pub fn run_zim(run_type: RunType) -> Result<()> {
|
||||
|
||||
pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
|
||||
require("zsh")?;
|
||||
let oh_my_zsh = HOME_DIR.join(".oh-my-zsh").require()?;
|
||||
let oh_my_zsh = env::var("ZSH")
|
||||
.map(PathBuf::from)
|
||||
// default to `~/.oh-my-zsh`
|
||||
.unwrap_or(HOME_DIR.join(".oh-my-zsh"))
|
||||
.require()?;
|
||||
|
||||
print_separator("oh-my-zsh");
|
||||
|
||||
@@ -194,7 +209,10 @@ pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
|
||||
|
||||
ctx.run_type()
|
||||
.execute("zsh")
|
||||
.env("ZSH", &oh_my_zsh)
|
||||
.arg(&oh_my_zsh.join("tools/upgrade.sh"))
|
||||
// oh-my-zsh returns 80 when it is already updated and no changes pulled
|
||||
// in this update.
|
||||
// See this comment: https://github.com/r-darwish/topgrade/issues/569#issuecomment-736756731
|
||||
// for more information.
|
||||
.status_checked_with_codes(&[80])
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use std::cmp::{max, min};
|
||||
use std::env;
|
||||
use std::io::{self, Write};
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
@@ -12,7 +10,6 @@ use color_eyre::eyre;
|
||||
use color_eyre::eyre::Context;
|
||||
use console::{style, Key, Term};
|
||||
use lazy_static::lazy_static;
|
||||
#[cfg(target_os = "macos")]
|
||||
use notify_rust::{Notification, Timeout};
|
||||
use tracing::{debug, error};
|
||||
#[cfg(windows)]
|
||||
@@ -20,10 +17,7 @@ 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());
|
||||
}
|
||||
@@ -49,8 +43,6 @@ struct Terminal {
|
||||
set_title: bool,
|
||||
display_time: bool,
|
||||
desktop_notification: bool,
|
||||
#[cfg(target_os = "linux")]
|
||||
notify_send: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Terminal {
|
||||
@@ -65,8 +57,6 @@ impl Terminal {
|
||||
set_title: true,
|
||||
display_time: true,
|
||||
desktop_notification: false,
|
||||
#[cfg(target_os = "linux")]
|
||||
notify_send: which("notify-send"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,35 +72,18 @@ impl Terminal {
|
||||
self.display_time = display_time
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn notify_desktop<P: AsRef<str>>(&self, message: P, timeout: Option<Duration>) {
|
||||
debug!("Desktop notification: {}", message.as_ref());
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "macos")] {
|
||||
let mut notification = Notification::new();
|
||||
notification.summary("Topgrade")
|
||||
.body(message.as_ref())
|
||||
.appname("topgrade");
|
||||
let mut notification = Notification::new();
|
||||
notification
|
||||
.summary("Topgrade")
|
||||
.body(message.as_ref())
|
||||
.appname("topgrade");
|
||||
|
||||
if let Some(timeout) = timeout {
|
||||
notification.timeout(Timeout::Milliseconds(timeout.as_millis() as u32));
|
||||
}
|
||||
notification.show().ok();
|
||||
} else if #[cfg(target_os = "linux")] {
|
||||
if let Some(ns) = self.notify_send.as_ref() {
|
||||
let mut command = Command::new(ns);
|
||||
if let Some(timeout) = timeout {
|
||||
command.arg("-t");
|
||||
command.arg(format!("{}", timeout.as_millis()));
|
||||
}
|
||||
command.args(["-a", "Topgrade", "Topgrade"]);
|
||||
command.arg(message.as_ref());
|
||||
if let Err(err) = command.output_checked() {
|
||||
terminal::print_warning("Sending notification failed with {err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(timeout) = timeout {
|
||||
notification.timeout(Timeout::Milliseconds(timeout.as_millis() as u32));
|
||||
}
|
||||
notification.show().ok();
|
||||
}
|
||||
|
||||
fn print_separator<P: AsRef<str>>(&mut self, message: P) {
|
||||
@@ -345,8 +318,3 @@ pub fn notify_desktop<P: AsRef<str>>(message: P, timeout: Option<Duration>) {
|
||||
pub fn display_time(display_time: bool) {
|
||||
TERMINAL.lock().unwrap().display_time(display_time);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn supports_notify_send() -> bool {
|
||||
TERMINAL.lock().unwrap().notify_send.is_some()
|
||||
}
|
||||
|
||||
111
src/utils.rs
111
src/utils.rs
@@ -1,12 +1,15 @@
|
||||
use crate::error::SkipStep;
|
||||
use color_eyre::eyre::Result;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::Debug;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use color_eyre::eyre::Result;
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::error::SkipStep;
|
||||
|
||||
pub trait PathExt
|
||||
where
|
||||
Self: Sized,
|
||||
@@ -101,6 +104,13 @@ pub fn require_option<T>(option: Option<T>, cause: String) -> Result<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn string_prepend_str(string: &mut String, s: &str) {
|
||||
let mut new_string = String::with_capacity(string.len() + s.len());
|
||||
new_string.push_str(s);
|
||||
new_string.push_str(string);
|
||||
*string = new_string;
|
||||
}
|
||||
|
||||
/* sys-info-rs
|
||||
*
|
||||
* Copyright (c) 2015 Siyu Wang
|
||||
@@ -144,11 +154,100 @@ pub fn hostname() -> Result<String> {
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
pub fn hostname() -> Result<String> {
|
||||
use crate::command::CommandExt;
|
||||
use std::process::Command;
|
||||
|
||||
Command::new("hostname")
|
||||
.output_checked_utf8()
|
||||
.map_err(|err| SkipStep(format!("Failed to get hostname: {err}")).into())
|
||||
.map(|output| output.stdout.trim().to_owned())
|
||||
}
|
||||
|
||||
pub mod merge_strategies {
|
||||
use merge::Merge;
|
||||
|
||||
use crate::config::Commands;
|
||||
|
||||
/// Prepends right to left (both Option<Vec<T>>)
|
||||
pub fn vec_prepend_opt<T>(left: &mut Option<Vec<T>>, right: Option<Vec<T>>) {
|
||||
if let Some(left_vec) = left {
|
||||
if let Some(mut right_vec) = right {
|
||||
right_vec.append(left_vec);
|
||||
let _ = std::mem::replace(left, Some(right_vec));
|
||||
}
|
||||
} else {
|
||||
*left = right;
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends an Option<String> to another Option<String>
|
||||
pub fn string_append_opt(left: &mut Option<String>, right: Option<String>) {
|
||||
if let Some(left_str) = left {
|
||||
if let Some(right_str) = right {
|
||||
left_str.push(' ');
|
||||
left_str.push_str(&right_str);
|
||||
}
|
||||
} else {
|
||||
*left = right;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner_merge_opt<T>(left: &mut Option<T>, right: Option<T>)
|
||||
where
|
||||
T: Merge,
|
||||
{
|
||||
if let Some(ref mut left_inner) = left {
|
||||
if let Some(right_inner) = right {
|
||||
left_inner.merge(right_inner);
|
||||
}
|
||||
} else {
|
||||
*left = right;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn commands_merge_opt(left: &mut Option<Commands>, right: Option<Commands>) {
|
||||
if let Some(ref mut left_inner) = left {
|
||||
if let Some(right_inner) = right {
|
||||
left_inner.extend(right_inner);
|
||||
}
|
||||
} else {
|
||||
*left = right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip causes
|
||||
// TODO: Put them in a better place when we have more of them
|
||||
pub const REQUIRE_SUDO: &str = "Require sudo or counterpart but not found, skip";
|
||||
|
||||
/// Return `Err(SkipStep)` if `python` is a Python 2 or shim.
|
||||
///
|
||||
/// # Shim
|
||||
/// On Windows, if you install `python` through `winget`, an actual `python`
|
||||
/// is installed as well as a `python3` shim. Shim is invokable, but when you
|
||||
/// execute it, the Microsoft App Store will be launched instead of a Python
|
||||
/// shell.
|
||||
///
|
||||
/// We do this check through `python -V`, a shim will just give `Python` with
|
||||
/// no version number.
|
||||
pub fn check_is_python_2_or_shim(python: PathBuf) -> Result<PathBuf> {
|
||||
let output = Command::new(&python).arg("-V").output_checked_utf8()?;
|
||||
// "Python x.x.x\n"
|
||||
let stdout = output.stdout;
|
||||
// ["Python"] or ["Python", "x.x.x"], the newline char is trimmed.
|
||||
let mut split = stdout.split_whitespace();
|
||||
|
||||
if let Some(version) = split.nth(1) {
|
||||
let major_version = version
|
||||
.split('.')
|
||||
.next()
|
||||
.expect("Should have a major version number")
|
||||
.parse::<u32>()
|
||||
.expect("Major version should be a valid number");
|
||||
if major_version == 2 {
|
||||
return Err(SkipStep(format!("{} is a Python 2, skip.", python.display())).into());
|
||||
}
|
||||
} else {
|
||||
// No version number, is a shim
|
||||
return Err(SkipStep(format!("{} is a Python shim, skip.", python.display())).into());
|
||||
}
|
||||
|
||||
Ok(python)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user