Compare commits

..

2 Commits

Author SHA1 Message Date
Thomas Schönauer
6232f5ebca CD pipeline cleanup (#116)
* Update README.md

* Update release-cross.yml

* Update release.yml

* style(self_update): Run cargo fmt (#108)

The commit 9105a8aac is not formatted, which breaks the CI check.

Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>

* Cleanup CI/CD pipeline (#115)

Co-authored-by: pan93412 <pan93412@gmail.com>
2022-11-02 16:29:23 +00:00
Thomas Schönauer
b2b35dcad2 Revert clap version bump (#111)
* Update README.md

* Update release-cross.yml

* Update release.yml

* style(self_update): Run cargo fmt (#108)

The commit 9105a8aac is not formatted, which breaks the CI check.

Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>

* Clap dependencie change

* Revert clap changes

Co-authored-by: pan93412 <pan93412@gmail.com>
2022-11-02 15:28:47 +00:00
14 changed files with 92 additions and 89 deletions

View File

@@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Discussions
url: https://github.com/topgrade-rs/topgrade/discussions
about: Please ask and answer questions here.

20
Cargo.lock generated
View File

@@ -225,24 +225,26 @@ dependencies = [
[[package]]
name = "clap"
version = "4.0.18"
version = "3.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b"
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "4.0.18"
version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
@@ -253,9 +255,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.3.0"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
@@ -1784,6 +1786,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "textwrap"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
[[package]]
name = "thiserror"
version = "1.0.37"

View File

@@ -26,7 +26,7 @@ serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
which_crate = { version = "4.1", package = "which" }
shellexpand = "2.1"
clap = { version = "4.0.18", features = ["cargo", "derive"] }
clap = { version = "3.1", features = ["cargo", "derive"] }
log = "0.4"
walkdir = "2.3"
console = "0.15"

View File

@@ -41,7 +41,7 @@ You can visit the documentation at [topgrade-rs.github.io](https://topgrade-rs.g
## Usage
Just run `topgrade`.
See [the documentation](https://topgrade-rs.github.io/) for the list of things Topgrade supports.
See [the wiki](https://github.com/r-darwish/topgrade/wiki/Step-list) for the list of things Topgrade supports.
## Customization
@@ -84,6 +84,6 @@ To limit the execution only to specific hosts use the `--remote-host-limit` para
## ToDo
- [ ] Add a proper testing framework to the code base.
- [ ] Add unit tests for package managers.
- [ ] Split up code into more maintainable parts, eg. putting every linux package manager in a own submodule of linux.rs.
- Add a proper testing framework to the code base.
- Add unit tests for package managers.
- Split up code into more maintainable parts, eg. putting every linux package manager in a own submodule of linux.rs.

View File

@@ -6,7 +6,7 @@ use std::process::Command;
use std::{env, fs};
use anyhow::Result;
use clap::{Parser, ValueEnum};
use clap::{ArgEnum, Parser};
use directories::BaseDirs;
use log::debug;
use regex::Regex;
@@ -62,7 +62,7 @@ macro_rules! get_deprecated {
type Commands = BTreeMap<String, String>;
#[derive(ValueEnum, EnumString, EnumVariantNames, Debug, Clone, PartialEq, Eq, Deserialize, EnumIter, Copy)]
#[derive(ArgEnum, EnumString, EnumVariantNames, Debug, Clone, PartialEq, Eq, Deserialize, EnumIter, Copy)]
#[clap(rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
@@ -397,78 +397,78 @@ impl ConfigFile {
// Command line arguments
#[derive(Parser, Debug)]
#[command(name = "Topgrade", version)]
#[clap(name = "Topgrade", version)]
pub struct CommandLineArgs {
/// Edit the configuration file
#[arg(long = "edit-config")]
#[clap(long = "edit-config")]
edit_config: bool,
/// Show config reference
#[arg(long = "config-reference")]
#[clap(long = "config-reference")]
show_config_reference: bool,
/// Run inside tmux
#[arg(short = 't', long = "tmux")]
#[clap(short = 't', long = "tmux")]
run_in_tmux: bool,
/// Cleanup temporary or old files
#[arg(short = 'c', long = "cleanup")]
#[clap(short = 'c', long = "cleanup")]
cleanup: bool,
/// Print what would be done
#[arg(short = 'n', long = "dry-run")]
#[clap(short = 'n', long = "dry-run")]
dry_run: bool,
/// Do not ask to retry failed steps
#[arg(long = "no-retry")]
#[clap(long = "no-retry")]
no_retry: bool,
/// Do not perform upgrades for the given steps
#[arg(long = "disable", value_name = "STEP", value_enum, num_args = 1..)]
#[clap(long = "disable", arg_enum, multiple_values = true)]
disable: Vec<Step>,
/// Perform only the specified steps (experimental)
#[arg(long = "only", value_name = "STEP", value_enum, num_args = 1..)]
#[clap(long = "only", arg_enum, multiple_values = true)]
only: Vec<Step>,
/// Run only specific custom commands
#[arg(long = "custom-commands", value_name = "NAME", num_args = 1..)]
#[clap(long = "custom-commands")]
custom_commands: Vec<String>,
/// Set environment variables
#[arg(long = "env", value_name = "NAME=VALUE", num_args = 1..)]
#[clap(long = "env", multiple_values = true)]
env: Vec<String>,
/// Output logs
#[arg(short = 'v', long = "verbose")]
#[clap(short = 'v', long = "verbose")]
pub verbose: bool,
/// Prompt for a key before exiting
#[arg(short = 'k', long = "keep")]
#[clap(short = 'k', long = "keep")]
keep_at_end: bool,
/// Skip sending a notification at the end of a run
#[arg(long = "skip-notify")]
#[clap(long = "skip-notify")]
skip_notify: bool,
/// Say yes to package manager's prompt
#[arg(short = 'y', long = "yes", value_name = "STEP", value_enum, num_args = 0..)]
#[clap(short = 'y', long = "yes", arg_enum, multiple_values = true, min_values = 0)]
yes: Option<Vec<Step>>,
/// Don't pull the predefined git repos
#[arg(long = "disable-predefined-git-repos")]
#[clap(long = "disable-predefined-git-repos")]
disable_predefined_git_repos: bool,
/// Alternative configuration file
#[arg(long = "config", value_name = "PATH")]
#[clap(long = "config")]
config: Option<PathBuf>,
/// A regular expression for restricting remote host execution
#[arg(long = "remote-host-limit", value_name = "REGEX")]
#[clap(long = "remote-host-limit")]
remote_host_limit: Option<Regex>,
/// Show the reason for skipped steps
#[arg(long = "show-skipped")]
#[clap(long = "show-skipped")]
show_skipped: bool,
}

View File

@@ -87,7 +87,7 @@ impl Emacs {
print_separator("Emacs");
let mut command = ctx.run_type().execute(emacs);
let mut command = ctx.run_type().execute(&emacs);
command
.args(["--batch", "--debug-init", "-l"])

View File

@@ -60,12 +60,12 @@ pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> {
let flutter = utils::require("flutter")?;
print_separator("Flutter");
run_type.execute(flutter).arg("upgrade").check_run()
run_type.execute(&flutter).arg("upgrade").check_run()
}
pub fn run_go(run_type: RunType) -> Result<()> {
let go = utils::require("go")?;
let go_output = run_type.execute(go).args(["env", "GOPATH"]).check_output()?;
let go_output = run_type.execute(&go).args(["env", "GOPATH"]).check_output()?;
let gopath = go_output.trim();
let go_global_update = utils::require("go-global-update")
@@ -74,7 +74,7 @@ pub fn run_go(run_type: RunType) -> Result<()> {
print_separator("Go");
run_type.execute(go_global_update).check_run()
run_type.execute(&go_global_update).check_run()
}
pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -83,7 +83,7 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
print_separator("RubyGems");
let mut command = run_type.execute(gem);
let mut command = run_type.execute(&gem);
command.arg("update");
if env::var_os("RBENV_SHELL").is_none() {
@@ -123,7 +123,7 @@ pub fn run_sheldon(ctx: &ExecutionContext) -> Result<()> {
print_separator("Sheldon");
ctx.run_type().execute(sheldon).args(["lock", "--update"]).check_run()
ctx.run_type().execute(&sheldon).args(["lock", "--update"]).check_run()
}
pub fn run_fossil(run_type: RunType) -> Result<()> {
@@ -131,7 +131,7 @@ pub fn run_fossil(run_type: RunType) -> Result<()> {
print_separator("Fossil");
run_type.execute(fossil).args(["all", "sync"]).check_run()
run_type.execute(&fossil).args(["all", "sync"]).check_run()
}
pub fn run_micro(run_type: RunType) -> Result<()> {
@@ -139,7 +139,7 @@ pub fn run_micro(run_type: RunType) -> Result<()> {
print_separator("micro");
let stdout = run_type.execute(micro).args(["-plugin", "update"]).string_output()?;
let stdout = run_type.execute(&micro).args(["-plugin", "update"]).string_output()?;
std::io::stdout().write_all(stdout.as_bytes())?;
if stdout.contains("Nothing to install / update") || stdout.contains("One or more plugins installed") {
@@ -160,7 +160,7 @@ pub fn run_apm(run_type: RunType) -> Result<()> {
print_separator("Atom Package Manager");
run_type.execute(apm).args(["upgrade", "--confirm=false"]).check_run()
run_type.execute(&apm).args(["upgrade", "--confirm=false"]).check_run()
}
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -190,7 +190,7 @@ pub fn run_krew_upgrade(run_type: RunType) -> Result<()> {
print_separator("Krew");
run_type.execute(krew).args(["upgrade"]).check_run()
run_type.execute(&krew).args(["upgrade"]).check_run()
}
pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
@@ -199,7 +199,7 @@ pub fn run_gcloud_components_update(run_type: RunType) -> Result<()> {
print_separator("gcloud");
run_type
.execute(gcloud)
.execute(&gcloud)
.args(["components", "update", "--quiet"])
.check_run()
}
@@ -209,7 +209,7 @@ pub fn run_jetpack(run_type: RunType) -> Result<()> {
print_separator("Jetpack");
run_type.execute(jetpack).args(["global", "update"]).check_run()
run_type.execute(&jetpack).args(["global", "update"]).check_run()
}
pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
@@ -217,7 +217,7 @@ pub fn run_rtcl(ctx: &ExecutionContext) -> Result<()> {
print_separator("rtcl");
ctx.run_type().execute(rupdate).check_run()
ctx.run_type().execute(&rupdate).check_run()
}
pub fn run_opam_update(ctx: &ExecutionContext) -> Result<()> {
@@ -239,14 +239,14 @@ pub fn run_vcpkg_update(run_type: RunType) -> Result<()> {
let vcpkg = utils::require("vcpkg")?;
print_separator("vcpkg");
run_type.execute(vcpkg).args(["upgrade", "--no-dry-run"]).check_run()
run_type.execute(&vcpkg).args(["upgrade", "--no-dry-run"]).check_run()
}
pub fn run_pipx_update(run_type: RunType) -> Result<()> {
let pipx = utils::require("pipx")?;
print_separator("pipx");
run_type.execute(pipx).arg("upgrade-all").check_run()
run_type.execute(&pipx).arg("upgrade-all").check_run()
}
pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
@@ -264,7 +264,7 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("Conda");
ctx.run_type()
.execute(conda)
.execute(&conda)
.args(["update", "--all", "-y"])
.check_run()
}
@@ -289,7 +289,7 @@ pub fn run_pip3_update(run_type: RunType) -> Result<()> {
}
pub fn run_stack_update(run_type: RunType) -> Result<()> {
if utils::require("ghcup").is_ok() {
if let Ok(_) = utils::require("ghcup") {
// `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' !!!
@@ -299,14 +299,14 @@ pub fn run_stack_update(run_type: RunType) -> Result<()> {
let stack = utils::require("stack")?;
print_separator("stack");
run_type.execute(stack).arg("upgrade").check_run()
run_type.execute(&stack).arg("upgrade").check_run()
}
pub fn run_ghcup_update(run_type: RunType) -> Result<()> {
let ghcup = utils::require("ghcup")?;
print_separator("ghcup");
run_type.execute(ghcup).arg("upgrade").check_run()
run_type.execute(&ghcup).arg("upgrade").check_run()
}
pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
@@ -323,7 +323,7 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
let tlmgr_directory = {
let mut d = PathBuf::from(
std::str::from_utf8(
&Command::new(kpsewhich)
&Command::new(&kpsewhich)
.arg("-var-value=SELFAUTOPARENT")
.output()?
.stdout,
@@ -360,7 +360,7 @@ pub fn run_chezmoi_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()>
print_separator("chezmoi");
run_type.execute(chezmoi).arg("update").check_run()
run_type.execute(&chezmoi).arg("update").check_run()
}
pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
@@ -440,7 +440,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
if stdout.contains("valet") || stderr.contains("valet") {
if let Some(valet) = utils::which("valet") {
ctx.run_type().execute(valet).arg("install").check_run()?;
ctx.run_type().execute(&valet).arg("install").check_run()?;
}
}
@@ -485,21 +485,21 @@ pub fn run_raco_update(run_type: RunType) -> Result<()> {
print_separator("Racket Package Manager");
run_type.execute(raco).args(["pkg", "update", "--all"]).check_run()
run_type.execute(&raco).args(["pkg", "update", "--all"]).check_run()
}
pub fn bin_update(ctx: &ExecutionContext) -> Result<()> {
let bin = utils::require("bin")?;
print_separator("Bin");
ctx.run_type().execute(bin).arg("update").check_run()
ctx.run_type().execute(&bin).arg("update").check_run()
}
pub fn spicetify_upgrade(ctx: &ExecutionContext) -> Result<()> {
let spicetify = utils::require("spicetify")?;
print_separator("Spicetify");
ctx.run_type().execute(spicetify).arg("upgrade").check_run()
ctx.run_type().execute(&spicetify).arg("upgrade").check_run()
}
pub fn run_ghcli_extensions_upgrade(ctx: &ExecutionContext) -> Result<()> {
@@ -523,7 +523,7 @@ pub fn update_julia_packages(ctx: &ExecutionContext) -> Result<()> {
print_separator("Julia Packages");
ctx.run_type()
.execute(julia)
.execute(&julia)
.args(["-e", "using Pkg; Pkg.update()"])
.check_run()
}

View File

@@ -13,7 +13,7 @@ pub fn upgrade_kak_plug(ctx: &ExecutionContext) -> Result<()> {
print_separator("Kakoune");
let mut command = ctx.run_type().execute(kak);
let mut command = ctx.run_type().execute(&kak);
command.args(["-ui", "dummy", "-e", UPGRADE_KAK]);
let output = command.output()?;

View File

@@ -11,15 +11,15 @@ pub fn run_macports(ctx: &ExecutionContext) -> Result<()> {
require("port")?;
let sudo = ctx.sudo().as_ref().unwrap();
print_separator("MacPorts");
ctx.run_type().execute(sudo).args(["port", "selfupdate"]).check_run()?;
ctx.run_type().execute(sudo).args(&["port", "selfupdate"]).check_run()?;
ctx.run_type()
.execute(sudo)
.args(["port", "-u", "upgrade", "outdated"])
.args(&["port", "-u", "upgrade", "outdated"])
.check_run()?;
if ctx.config().cleanup() {
ctx.run_type()
.execute(sudo)
.args(["port", "-N", "reclaim"])
.args(&["port", "-N", "reclaim"])
.check_run()?;
}
@@ -52,7 +52,7 @@ pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
}
let mut command = ctx.run_type().execute("softwareupdate");
command.args(["--install", "--all"]);
command.args(&["--install", "--all"]);
if should_ask {
command.arg("--no-scan");
@@ -81,12 +81,12 @@ pub fn run_sparkle(ctx: &ExecutionContext) -> Result<()> {
for application in (fs::read_dir("/Applications")?).flatten() {
let probe = Command::new(&sparkle)
.args(["--probe", "--application"])
.args(&["--probe", "--application"])
.arg(application.path())
.check_output();
if probe.is_ok() {
let mut command = ctx.run_type().execute(&sparkle);
command.args(["bundle", "--check-immediately", "--application"]);
command.args(&["bundle", "--check-immediately", "--application"]);
command.arg(application.path());
command.spawn()?.wait()?;
}

View File

@@ -124,7 +124,7 @@ pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> {
print_separator("oh-my-fish");
ctx.run_type().execute(fish).args(["-c", "omf update"]).check_run()
ctx.run_type().execute(&fish).args(["-c", "omf update"]).check_run()
}
pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> {
@@ -154,7 +154,7 @@ pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> {
print_separator("fish-plug");
ctx.run_type().execute(fish).args(["-c", "plug update"]).check_run()
ctx.run_type().execute(&fish).args(["-c", "plug update"]).check_run()
}
/// Upgrades `fundle` and `fundle` plugins.
@@ -258,19 +258,19 @@ pub fn run_brew_cask(ctx: &ExecutionContext, variant: BrewVariant) -> Result<()>
let cask_upgrade_exists = variant
.execute(RunType::Wet)
.args(["--repository", "buo/cask-upgrade"])
.args(&["--repository", "buo/cask-upgrade"])
.check_output()
.map(|p| Path::new(p.trim()).exists())?;
let mut brew_args = vec![];
if cask_upgrade_exists {
brew_args.extend(["cu", "-y"]);
brew_args.extend(&["cu", "-y"]);
if ctx.config().brew_cask_greedy() {
brew_args.push("-a");
}
} else {
brew_args.extend(["upgrade", "--cask"]);
brew_args.extend(&["upgrade", "--cask"]);
if ctx.config().brew_cask_greedy() {
brew_args.push("--greedy");
}
@@ -352,7 +352,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
}
}
run_type.execute(nix_channel).arg("--update").check_run()?;
run_type.execute(&nix_channel).arg("--update").check_run()?;
if std::path::Path::new(&manifest_json_path).exists() {
run_type
@@ -371,7 +371,7 @@ pub fn run_yadm(ctx: &ExecutionContext) -> Result<()> {
print_separator("yadm");
ctx.run_type().execute(yadm).arg("pull").check_run()
ctx.run_type().execute(&yadm).arg("pull").check_run()
}
pub fn run_asdf(run_type: RunType) -> Result<()> {
@@ -392,21 +392,21 @@ pub fn run_home_manager(run_type: RunType) -> Result<()> {
let home_manager = require("home-manager")?;
print_separator("home-manager");
run_type.execute(home_manager).arg("switch").check_run()
run_type.execute(&home_manager).arg("switch").check_run()
}
pub fn run_tldr(run_type: RunType) -> Result<()> {
let tldr = require("tldr")?;
print_separator("TLDR");
run_type.execute(tldr).arg("--update").check_run()
run_type.execute(&tldr).arg("--update").check_run()
}
pub fn run_pearl(run_type: RunType) -> Result<()> {
let pearl = require("pearl")?;
print_separator("pearl");
run_type.execute(pearl).arg("update").check_run()
run_type.execute(&pearl).arg("update").check_run()
}
pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> {
@@ -471,7 +471,7 @@ pub fn run_bun(ctx: &ExecutionContext) -> Result<()> {
print_separator("Bun");
ctx.run_type().execute(bun).arg("upgrade").check_run()
ctx.run_type().execute(&bun).arg("upgrade").check_run()
}
/// Update dotfiles with `rcm(7)`.

View File

@@ -47,6 +47,6 @@ pub fn ssh_step(ctx: &ExecutionContext, hostname: &str) -> Result<()> {
print_separator(format!("Remote ({})", hostname));
println!("Connecting to {}...", hostname);
ctx.run_type().execute(ssh).args(&args).check_run()
ctx.run_type().execute(&ssh).args(&args).check_run()
}
}

View File

@@ -20,7 +20,7 @@ pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
print_separator("tmux plugins");
run_type.execute(tpm).arg("all").check_run()
run_type.execute(&tpm).arg("all").check_run()
}
struct Tmux {

View File

@@ -118,9 +118,9 @@ pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> {
upgrade(
ctx.run_type()
.execute(&vim)
.args(["-u"])
.args(&["-u"])
.arg(vimrc)
.args(["-U", "NONE", "-V1", "-nNesS"])
.args(&["-U", "NONE", "-V1", "-nNesS"])
.arg(upgrade_script()?.path()),
ctx,
)
@@ -133,10 +133,10 @@ pub fn upgrade_neovim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()
print_separator("Neovim");
upgrade(
ctx.run_type()
.execute(nvim)
.args(["-u"])
.execute(&nvim)
.args(&["-u"])
.arg(nvimrc)
.args(["--headless", "-V1", "-nS"])
.args(&["--headless", "-V1", "-nS"])
.arg(upgrade_script()?.path()),
ctx,
)

View File

@@ -223,7 +223,7 @@ impl Terminal {
self.term.set_title("Topgrade - Awaiting user");
}
self.notify_desktop(format!("{} failed", step_name), None);
self.notify_desktop(&format!("{} failed", step_name), None);
self.term
.write_fmt(format_args!(