chore: update toolchain to 1.84.1. apply clippy fixes & rustfmt (#1026)
* chore: update to stable toolchain. apply clippy fixes & rustfmt * Bump MSRV * Try MSRV without the patch version * fix: pin toolchain to MSRV * trying again * fix dead code warning --------- Co-authored-by: Dan Sully <dsully@users.noreply.github.com>
This commit is contained in:
@@ -5,7 +5,7 @@ categories = ["os"]
|
|||||||
keywords = ["upgrade", "update"]
|
keywords = ["upgrade", "update"]
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
repository = "https://github.com/topgrade-rs/topgrade"
|
repository = "https://github.com/topgrade-rs/topgrade"
|
||||||
rust-version = "1.76.0"
|
rust-version = "1.84.1"
|
||||||
version = "16.0.2"
|
version = "16.0.2"
|
||||||
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
|
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
|
||||||
exclude = ["doc/screenshot.gif", "BREAKINGCHANGES_dev.md"]
|
exclude = ["doc/screenshot.gif", "BREAKINGCHANGES_dev.md"]
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.76.0"
|
channel = "1.84.1"
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ impl TryFrom<&Output> for Utf8Output {
|
|||||||
type Error = eyre::Error;
|
type Error = eyre::Error;
|
||||||
|
|
||||||
fn try_from(Output { status, stdout, stderr }: &Output) -> Result<Self, Self::Error> {
|
fn try_from(Output { status, stdout, stderr }: &Output) -> Result<Self, Self::Error> {
|
||||||
let stdout = String::from_utf8(stdout.to_vec()).map_err(|err| {
|
let stdout = String::from_utf8(stdout.clone()).map_err(|err| {
|
||||||
eyre!(
|
eyre!(
|
||||||
"Stdout contained invalid UTF-8: {}",
|
"Stdout contained invalid UTF-8: {}",
|
||||||
String::from_utf8_lossy(err.as_bytes())
|
String::from_utf8_lossy(err.as_bytes())
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let stderr = String::from_utf8(stderr.to_vec()).map_err(|err| {
|
let stderr = String::from_utf8(stderr.clone()).map_err(|err| {
|
||||||
eyre!(
|
eyre!(
|
||||||
"Stderr contained invalid UTF-8: {}",
|
"Stderr contained invalid UTF-8: {}",
|
||||||
String::from_utf8_lossy(err.as_bytes())
|
String::from_utf8_lossy(err.as_bytes())
|
||||||
@@ -149,6 +149,7 @@ pub trait CommandExt {
|
|||||||
/// Like [`Command::spawn`], but gives a nice error message if the command fails to
|
/// Like [`Command::spawn`], but gives a nice error message if the command fails to
|
||||||
/// execute.
|
/// execute.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[allow(dead_code)]
|
||||||
fn spawn_checked(&mut self) -> eyre::Result<Self::Child>;
|
fn spawn_checked(&mut self) -> eyre::Result<Self::Child>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ impl ConfigFile {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Search for the main config file
|
// Search for the main config file
|
||||||
for path in possible_config_paths.iter() {
|
for path in &possible_config_paths {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
debug!("Configuration at {}", path.display());
|
debug!("Configuration at {}", path.display());
|
||||||
res.0.clone_from(path);
|
res.0.clone_from(path);
|
||||||
@@ -1475,8 +1475,7 @@ impl Config {
|
|||||||
.misc
|
.misc
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|misc| misc.ignore_failures.as_ref())
|
.and_then(|misc| misc.ignore_failures.as_ref())
|
||||||
.map(|v| v.contains(&step))
|
.is_some_and(|v| v.contains(&step))
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_predefined_git_repos(&self) -> bool {
|
pub fn use_predefined_git_repos(&self) -> bool {
|
||||||
@@ -1694,40 +1693,40 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_execute_remote_different_hostname() {
|
fn test_should_execute_remote_different_hostname() {
|
||||||
assert!(config().should_execute_remote(Ok("hostname".to_string()), "remote_hostname"))
|
assert!(config().should_execute_remote(Ok("hostname".to_string()), "remote_hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_execute_remote_different_hostname_with_user() {
|
fn test_should_execute_remote_different_hostname_with_user() {
|
||||||
assert!(config().should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"))
|
assert!(config().should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_execute_remote_unknown_hostname() {
|
fn test_should_execute_remote_unknown_hostname() {
|
||||||
assert!(config().should_execute_remote(Err(eyre!("failed to get hostname")), "remote_hostname"))
|
assert!(config().should_execute_remote(Err(eyre!("failed to get hostname")), "remote_hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_not_execute_remote_same_hostname() {
|
fn test_should_not_execute_remote_same_hostname() {
|
||||||
assert!(!config().should_execute_remote(Ok("hostname".to_string()), "hostname"))
|
assert!(!config().should_execute_remote(Ok("hostname".to_string()), "hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_not_execute_remote_same_hostname_with_user() {
|
fn test_should_not_execute_remote_same_hostname_with_user() {
|
||||||
assert!(!config().should_execute_remote(Ok("hostname".to_string()), "user@hostname"))
|
assert!(!config().should_execute_remote(Ok("hostname".to_string()), "user@hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_execute_remote_matching_limit() {
|
fn test_should_execute_remote_matching_limit() {
|
||||||
let mut config = config();
|
let mut config = config();
|
||||||
config.opt = CommandLineArgs::parse_from(["topgrade", "--remote-host-limit", "remote_hostname"]);
|
config.opt = CommandLineArgs::parse_from(["topgrade", "--remote-host-limit", "remote_hostname"]);
|
||||||
assert!(config.should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"))
|
assert!(config.should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_should_not_execute_remote_not_matching_limit() {
|
fn test_should_not_execute_remote_not_matching_limit() {
|
||||||
let mut config = config();
|
let mut config = config();
|
||||||
config.opt = CommandLineArgs::parse_from(["topgrade", "--remote-host-limit", "other_hostname"]);
|
config.opt = CommandLineArgs::parse_from(["topgrade", "--remote-host-limit", "other_hostname"]);
|
||||||
assert!(!config.should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"))
|
assert!(!config.should_execute_remote(Ok("hostname".to_string()), "user@remote_hostname"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ pub fn interrupted() -> bool {
|
|||||||
/// Clears the interrupted flag
|
/// Clears the interrupted flag
|
||||||
pub fn unset_interrupted() {
|
pub fn unset_interrupted() {
|
||||||
debug_assert!(INTERRUPTED.load(Ordering::SeqCst));
|
debug_assert!(INTERRUPTED.load(Ordering::SeqCst));
|
||||||
INTERRUPTED.store(false, Ordering::SeqCst)
|
INTERRUPTED.store(false, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_interrupted() {
|
pub fn set_interrupted() {
|
||||||
INTERRUPTED.store(true, Ordering::SeqCst)
|
INTERRUPTED.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal
|
|||||||
|
|
||||||
/// Handle SIGINT. Set the interruption flag.
|
/// Handle SIGINT. Set the interruption flag.
|
||||||
extern "C" fn handle_sigint(_: i32) {
|
extern "C" fn handle_sigint(_: i32) {
|
||||||
set_interrupted()
|
set_interrupted();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the necessary signal handlers.
|
/// Set the necessary signal handlers.
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl Executor {
|
|||||||
pub fn status_checked_with_codes(&mut self, codes: &[i32]) -> Result<()> {
|
pub fn status_checked_with_codes(&mut self, codes: &[i32]) -> Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Executor::Wet(c) => c.status_checked_with(|status| {
|
Executor::Wet(c) => c.status_checked_with(|status| {
|
||||||
if status.success() || status.code().as_ref().map(|c| codes.contains(c)).unwrap_or(false) {
|
if status.success() || status.code().as_ref().is_some_and(|c| codes.contains(c)) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
|
|||||||
11
src/main.rs
11
src/main.rs
@@ -25,7 +25,9 @@ use self::config::{CommandLineArgs, Config, Step};
|
|||||||
use self::error::StepFailed;
|
use self::error::StepFailed;
|
||||||
#[cfg(all(windows, feature = "self-update"))]
|
#[cfg(all(windows, feature = "self-update"))]
|
||||||
use self::error::Upgraded;
|
use self::error::Upgraded;
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use self::steps::{remote::*, *};
|
use self::steps::{remote::*, *};
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use self::terminal::*;
|
use self::terminal::*;
|
||||||
|
|
||||||
use self::utils::{hostname, install_color_eyre, install_tracing, update_tracing};
|
use self::utils::{hostname, install_color_eyre, install_tracing, update_tracing};
|
||||||
@@ -58,6 +60,7 @@ pub(crate) static WINDOWS_DIRS: Lazy<Windows> = Lazy::new(|| Windows::new().expe
|
|||||||
// Init and load the i18n files
|
// Init and load the i18n files
|
||||||
i18n!("locales", fallback = "en");
|
i18n!("locales", fallback = "en");
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn run() -> Result<()> {
|
fn run() -> Result<()> {
|
||||||
install_color_eyre()?;
|
install_color_eyre()?;
|
||||||
ctrlc::set_handler();
|
ctrlc::set_handler();
|
||||||
@@ -494,13 +497,13 @@ fn run() -> Result<()> {
|
|||||||
print_info(t!("\n(R)eboot\n(S)hell\n(Q)uit"));
|
print_info(t!("\n(R)eboot\n(S)hell\n(Q)uit"));
|
||||||
loop {
|
loop {
|
||||||
match get_key() {
|
match get_key() {
|
||||||
Ok(Key::Char('s')) | Ok(Key::Char('S')) => {
|
Ok(Key::Char('s' | 'S')) => {
|
||||||
run_shell().context("Failed to execute shell")?;
|
run_shell().context("Failed to execute shell")?;
|
||||||
}
|
}
|
||||||
Ok(Key::Char('r')) | Ok(Key::Char('R')) => {
|
Ok(Key::Char('r' | 'R')) => {
|
||||||
reboot().context("Failed to reboot")?;
|
reboot().context("Failed to reboot")?;
|
||||||
}
|
}
|
||||||
Ok(Key::Char('q')) | Ok(Key::Char('Q')) => (),
|
Ok(Key::Char('q' | 'Q')) => (),
|
||||||
_ => {
|
_ => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -519,7 +522,7 @@ fn run() -> Result<()> {
|
|||||||
t!("Topgrade finished successfully")
|
t!("Topgrade finished successfully")
|
||||||
},
|
},
|
||||||
Some(Duration::from_secs(10)),
|
Some(Duration::from_secs(10)),
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use rust_i18n::t;
|
|||||||
use self_update_crate::backends::github::Update;
|
use self_update_crate::backends::github::Update;
|
||||||
use self_update_crate::update::UpdateStatus;
|
use self_update_crate::update::UpdateStatus;
|
||||||
|
|
||||||
use super::terminal::*;
|
use super::terminal::{print_info, print_separator};
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::error::Upgraded;
|
use crate::error::Upgraded;
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ pub fn run_containers(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
list_containers(&crt, ctx.config().containers_ignored_tags()).context("Failed to list Docker containers")?;
|
list_containers(&crt, ctx.config().containers_ignored_tags()).context("Failed to list Docker containers")?;
|
||||||
debug!("Containers to inspect: {:?}", containers);
|
debug!("Containers to inspect: {:?}", containers);
|
||||||
|
|
||||||
for container in containers.iter() {
|
for container in &containers {
|
||||||
debug!("Pulling container '{}'", container);
|
debug!("Pulling container '{}'", container);
|
||||||
let args = vec![
|
let args = vec![
|
||||||
"pull",
|
"pull",
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ pub fn is_wsl() -> Result<bool> {
|
|||||||
|
|
||||||
pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
||||||
let cargo_dir = env::var_os("CARGO_HOME")
|
let cargo_dir = env::var_os("CARGO_HOME")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|| HOME_DIR.join(".cargo"), PathBuf::from)
|
||||||
.unwrap_or_else(|| HOME_DIR.join(".cargo"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
require("cargo").or_else(|_| {
|
require("cargo").or_else(|_| {
|
||||||
require_option(
|
require_option(
|
||||||
@@ -60,13 +59,11 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let cargo_update = require("cargo-install-update")
|
let cargo_update = require("cargo-install-update")
|
||||||
.ok()
|
.ok()
|
||||||
.or_else(|| cargo_dir.join("bin/cargo-install-update").if_exists());
|
.or_else(|| cargo_dir.join("bin/cargo-install-update").if_exists());
|
||||||
let cargo_update = match cargo_update {
|
|
||||||
Some(e) => e,
|
let Some(cargo_update) = cargo_update else {
|
||||||
None => {
|
let message = String::from("cargo-update isn't installed so Topgrade can't upgrade cargo packages.\nInstall cargo-update by running `cargo install cargo-update`");
|
||||||
let message = String::from("cargo-update isn't installed so Topgrade can't upgrade cargo packages.\nInstall cargo-update by running `cargo install cargo-update`");
|
print_warning(&message);
|
||||||
print_warning(&message);
|
return Err(SkipStep(message).into());
|
||||||
return Err(SkipStep(message).into());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
@@ -78,14 +75,11 @@ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let cargo_cache = require("cargo-cache")
|
let cargo_cache = require("cargo-cache")
|
||||||
.ok()
|
.ok()
|
||||||
.or_else(|| cargo_dir.join("bin/cargo-cache").if_exists());
|
.or_else(|| cargo_dir.join("bin/cargo-cache").if_exists());
|
||||||
match cargo_cache {
|
if let Some(e) = cargo_cache {
|
||||||
Some(e) => {
|
ctx.run_type().execute(e).args(["-a"]).status_checked()?;
|
||||||
ctx.run_type().execute(e).args(["-a"]).status_checked()?;
|
} else {
|
||||||
}
|
let message = String::from("cargo-cache isn't installed so Topgrade can't cleanup cargo packages.\nInstall cargo-cache by running `cargo install cargo-cache`");
|
||||||
None => {
|
print_warning(message);
|
||||||
let message = String::from("cargo-cache isn't installed so Topgrade can't cleanup cargo packages.\nInstall cargo-cache by running `cargo install cargo-cache`");
|
|
||||||
print_warning(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +417,7 @@ pub fn run_vscodium_extensions_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.lines()
|
.lines()
|
||||||
.next()
|
.next()
|
||||||
{
|
{
|
||||||
Some(item) => Version::parse(item).map_err(|err| err.into()),
|
Some(item) => Version::parse(item).map_err(std::convert::Into::into),
|
||||||
_ => return Err(SkipStep(String::from("Cannot find vscodium version")).into()),
|
_ => return Err(SkipStep(String::from("Cannot find vscodium version")).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -459,7 +453,7 @@ pub fn run_vscode_extensions_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.lines()
|
.lines()
|
||||||
.next()
|
.next()
|
||||||
{
|
{
|
||||||
Some(item) => Version::parse(item).map_err(|err| err.into()),
|
Some(item) => Version::parse(item).map_err(std::convert::Into::into),
|
||||||
_ => return Err(SkipStep(String::from("Cannot find vscode version")).into()),
|
_ => return Err(SkipStep(String::from("Cannot find vscode version")).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -489,7 +483,7 @@ pub fn run_pipx_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.map(|s| s.stdout.trim().to_owned());
|
.map(|s| s.stdout.trim().to_owned());
|
||||||
let version = Version::parse(&version_str?);
|
let version = Version::parse(&version_str?);
|
||||||
if matches!(version, Ok(version) if version >= Version::new(1, 4, 0)) {
|
if matches!(version, Ok(version) if version >= Version::new(1, 4, 0)) {
|
||||||
command_args.push("--quiet")
|
command_args.push("--quiet");
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.run_type().execute(pipx).args(command_args).status_checked()
|
ctx.run_type().execute(pipx).args(command_args).status_checked()
|
||||||
@@ -555,7 +549,7 @@ pub fn run_pip3_update(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
(Ok(py), _) => py,
|
(Ok(py), _) => py,
|
||||||
(Err(_), Ok(py3)) => py3,
|
(Err(_), Ok(py3)) => py3,
|
||||||
(Err(py_err), Err(py3_err)) => {
|
(Err(py_err), Err(py3_err)) => {
|
||||||
return Err(SkipStep(format!("Skip due to following reasons: {} {}", py_err, py3_err)).into());
|
return Err(SkipStep(format!("Skip due to following reasons: {py_err} {py3_err}")).into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -904,7 +898,7 @@ pub fn run_dotnet_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.execute(&dotnet)
|
.execute(&dotnet)
|
||||||
.args(["tool", "update", package_name, "--global"])
|
.args(["tool", "update", package_name, "--global"])
|
||||||
.status_checked()
|
.status_checked()
|
||||||
.with_context(|| format!("Failed to update .NET package {:?}", package_name))?;
|
.with_context(|| format!("Failed to update .NET package {package_name:?}"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ pub fn run_git_pull(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
print_warning(t!(
|
print_warning(t!(
|
||||||
"Path {pattern} did not contain any git repositories",
|
"Path {pattern} did not contain any git repositories",
|
||||||
pattern = pattern
|
pattern = pattern
|
||||||
))
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
if repos.is_repos_empty() {
|
if repos.is_repos_empty() {
|
||||||
@@ -207,10 +207,13 @@ impl RepoStep {
|
|||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
Err(e) => match e.kind() {
|
Err(e) => {
|
||||||
io::ErrorKind::NotFound => debug!("{} does not exist", path.as_ref().display()),
|
if e.kind() == io::ErrorKind::NotFound {
|
||||||
_ => error!("Error looking for {}: {e}", path.as_ref().display(),),
|
debug!("{} does not exist", path.as_ref().display());
|
||||||
},
|
} else {
|
||||||
|
error!("Error looking for {}: {e}", path.as_ref().display());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -321,7 +324,7 @@ impl RepoStep {
|
|||||||
.output()
|
.output()
|
||||||
.await?;
|
.await?;
|
||||||
let result = output_checked_utf8(pull_output)
|
let result = output_checked_utf8(pull_output)
|
||||||
.and_then(|_| output_checked_utf8(submodule_output))
|
.and_then(|()| output_checked_utf8(submodule_output))
|
||||||
.wrap_err_with(|| format!("Failed to pull {}", repo.as_ref().display()));
|
.wrap_err_with(|| format!("Failed to pull {}", repo.as_ref().display()));
|
||||||
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
@@ -359,7 +362,7 @@ impl RepoStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.map(|_| ())
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pull the repositories specified in `self.repos`.
|
/// Pull the repositories specified in `self.repos`.
|
||||||
@@ -410,7 +413,7 @@ impl RepoStep {
|
|||||||
let basic_rt = runtime::Runtime::new()?;
|
let basic_rt = runtime::Runtime::new()?;
|
||||||
let results = basic_rt.block_on(async { stream_of_futures.collect::<Vec<Result<()>>>().await });
|
let results = basic_rt.block_on(async { stream_of_futures.collect::<Vec<Result<()>>>().await });
|
||||||
|
|
||||||
let error = results.into_iter().find(|r| r.is_err());
|
let error = results.into_iter().find(std::result::Result::is_err);
|
||||||
error.unwrap_or(Ok(()))
|
error.unwrap_or(Ok(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ impl NPM {
|
|||||||
.args(["--version"])
|
.args(["--version"])
|
||||||
.output_checked_utf8()
|
.output_checked_utf8()
|
||||||
.map(|s| s.stdout.trim().to_owned());
|
.map(|s| s.stdout.trim().to_owned());
|
||||||
Version::parse(&version_str?).map_err(|err| err.into())
|
Version::parse(&version_str?).map_err(std::convert::Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade(&self, ctx: &ExecutionContext, use_sudo: bool) -> Result<()> {
|
fn upgrade(&self, ctx: &ExecutionContext, use_sudo: bool) -> Result<()> {
|
||||||
@@ -266,7 +266,7 @@ impl Deno {
|
|||||||
.args(["-V"])
|
.args(["-V"])
|
||||||
.output_checked_utf8()
|
.output_checked_utf8()
|
||||||
.map(|s| s.stdout.trim().to_owned().split_off(5)); // remove "deno " prefix
|
.map(|s| s.stdout.trim().to_owned().split_off(5)); // remove "deno " prefix
|
||||||
Version::parse(&version_str?).map_err(|err| err.into())
|
Version::parse(&version_str?).map_err(std::convert::Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ pub fn run_volta_packages_upgrade(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
for package in installed_packages.iter() {
|
for package in &installed_packages {
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&volta)
|
.execute(&volta)
|
||||||
.args(["install", package])
|
.args(["install", package])
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ pub fn update_xcodes(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.execute(&xcodes)
|
.execute(&xcodes)
|
||||||
.args([
|
.args([
|
||||||
"uninstall",
|
"uninstall",
|
||||||
releases_new_installed.iter().next().cloned().unwrap_or_default(),
|
releases_new_installed.iter().next().copied().unwrap_or_default(),
|
||||||
])
|
])
|
||||||
.status_checked();
|
.status_checked();
|
||||||
}
|
}
|
||||||
@@ -216,12 +216,7 @@ pub fn update_xcodes(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
pub fn process_xcodes_releases(releases_filtered: Vec<String>, should_ask: bool, ctx: &ExecutionContext) -> Result<()> {
|
pub fn process_xcodes_releases(releases_filtered: Vec<String>, should_ask: bool, ctx: &ExecutionContext) -> Result<()> {
|
||||||
let xcodes = require("xcodes")?;
|
let xcodes = require("xcodes")?;
|
||||||
|
|
||||||
if releases_filtered
|
if releases_filtered.last().map_or(true, |s| !s.contains("(Installed)")) && !releases_filtered.is_empty() {
|
||||||
.last()
|
|
||||||
.map(|s| !s.contains("(Installed)"))
|
|
||||||
.unwrap_or(true)
|
|
||||||
&& !releases_filtered.is_empty()
|
|
||||||
{
|
|
||||||
println!(
|
println!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
t!("New Xcode release detected:"),
|
t!("New Xcode release detected:"),
|
||||||
|
|||||||
@@ -463,7 +463,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref NIX_VERSION_REGEX: Regex =
|
static ref NIX_VERSION_REGEX: Regex =
|
||||||
Regex::new(r#"^nix \([^)]*\) ([0-9.]+)"#).expect("Nix version regex always compiles");
|
Regex::new(r"^nix \([^)]*\) ([0-9.]+)").expect("Nix version regex always compiles");
|
||||||
}
|
}
|
||||||
|
|
||||||
if get_version_cmd_first_line_stdout.is_empty() {
|
if get_version_cmd_first_line_stdout.is_empty() {
|
||||||
@@ -611,8 +611,7 @@ fn nix_profile_dir(nix: &Path) -> Result<Option<PathBuf>> {
|
|||||||
if user_env
|
if user_env
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|name| name.to_str())
|
.and_then(|name| name.to_str())
|
||||||
.map(|name| name.ends_with("user-environment"))
|
.is_some_and(|name| name.ends_with("user-environment"))
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
{
|
||||||
Some(profile_dir)
|
Some(profile_dir)
|
||||||
} else {
|
} else {
|
||||||
@@ -651,9 +650,9 @@ pub fn run_asdf(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
// ```
|
// ```
|
||||||
let version_stdout = version_output.stdout.trim();
|
let version_stdout = version_output.stdout.trim();
|
||||||
// trim the starting 'v'
|
// trim the starting 'v'
|
||||||
let mut remaining = version_stdout.trim_start_matches(|char| char == 'v');
|
let mut remaining = version_stdout.trim_start_matches('v');
|
||||||
let idx = remaining
|
let idx = remaining
|
||||||
.find(|char| char == '-')
|
.find('-')
|
||||||
.expect("the output of `asdf version` changed, please file an issue to Topgrade");
|
.expect("the output of `asdf version` changed, please file an issue to Topgrade");
|
||||||
// remove the hash part
|
// remove the hash part
|
||||||
remaining = &remaining[..idx];
|
remaining = &remaining[..idx];
|
||||||
@@ -717,9 +716,7 @@ pub fn run_pyenv(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let pyenv = require("pyenv")?;
|
let pyenv = require("pyenv")?;
|
||||||
print_separator("pyenv");
|
print_separator("pyenv");
|
||||||
|
|
||||||
let pyenv_dir = var("PYENV_ROOT")
|
let pyenv_dir = var("PYENV_ROOT").map_or_else(|_| HOME_DIR.join(".pyenv"), PathBuf::from);
|
||||||
.map(PathBuf::from)
|
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".pyenv"));
|
|
||||||
|
|
||||||
if !pyenv_dir.exists() {
|
if !pyenv_dir.exists() {
|
||||||
return Err(SkipStep(t!("Pyenv is installed, but $PYENV_ROOT is not set correctly").to_string()).into());
|
return Err(SkipStep(t!("Pyenv is installed, but $PYENV_ROOT is not set correctly").to_string()).into());
|
||||||
@@ -740,8 +737,7 @@ pub fn run_sdkman(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let bash = require("bash")?;
|
let bash = require("bash")?;
|
||||||
|
|
||||||
let sdkman_init_path = var("SDKMAN_DIR")
|
let sdkman_init_path = var("SDKMAN_DIR")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join(".sdkman"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".sdkman"))
|
|
||||||
.join("bin")
|
.join("bin")
|
||||||
.join("sdkman-init.sh")
|
.join("sdkman-init.sh")
|
||||||
.require()
|
.require()
|
||||||
@@ -750,8 +746,7 @@ pub fn run_sdkman(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
print_separator("SDKMAN!");
|
print_separator("SDKMAN!");
|
||||||
|
|
||||||
let sdkman_config_path = var("SDKMAN_DIR")
|
let sdkman_config_path = var("SDKMAN_DIR")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join(".sdkman"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".sdkman"))
|
|
||||||
.join("etc")
|
.join("etc")
|
||||||
.join("config")
|
.join("config")
|
||||||
.require()?;
|
.require()?;
|
||||||
@@ -804,9 +799,7 @@ pub fn run_bun_packages(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
|
|
||||||
print_separator(t!("Bun Packages"));
|
print_separator(t!("Bun Packages"));
|
||||||
|
|
||||||
let mut package_json: PathBuf = var("BUN_INSTALL")
|
let mut package_json: PathBuf = var("BUN_INSTALL").map_or_else(|_| HOME_DIR.join(".bun"), PathBuf::from);
|
||||||
.map(PathBuf::from)
|
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".bun"));
|
|
||||||
package_json.push("install/global/package.json");
|
package_json.push("install/global/package.json");
|
||||||
|
|
||||||
if !package_json.exists() {
|
if !package_json.exists() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use rust_i18n::t;
|
|||||||
use crate::command::CommandExt;
|
use crate::command::CommandExt;
|
||||||
use crate::execution_context::ExecutionContext;
|
use crate::execution_context::ExecutionContext;
|
||||||
use crate::terminal::{is_dumb, print_separator};
|
use crate::terminal::{is_dumb, print_separator};
|
||||||
use crate::utils::{require_option, which, PathExt};
|
use crate::utils::{require_option, which};
|
||||||
use crate::Step;
|
use crate::Step;
|
||||||
|
|
||||||
pub struct Powershell {
|
pub struct Powershell {
|
||||||
@@ -30,7 +30,7 @@ impl Powershell {
|
|||||||
.args(["-NoProfile", "-Command", "Split-Path $profile"])
|
.args(["-NoProfile", "-Command", "Split-Path $profile"])
|
||||||
.output_checked_utf8()
|
.output_checked_utf8()
|
||||||
.map(|output| PathBuf::from(output.stdout.trim()))
|
.map(|output| PathBuf::from(output.stdout.trim()))
|
||||||
.and_then(|p| p.require())
|
.and_then(super::super::utils::PathExt::require)
|
||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -70,11 +70,11 @@ impl Powershell {
|
|||||||
let mut cmd = vec!["Update-Module"];
|
let mut cmd = vec!["Update-Module"];
|
||||||
|
|
||||||
if ctx.config().verbose() {
|
if ctx.config().verbose() {
|
||||||
cmd.push("-Verbose")
|
cmd.push("-Verbose");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.config().yes(Step::Powershell) {
|
if ctx.config().yes(Step::Powershell) {
|
||||||
cmd.push("-Force")
|
cmd.push("-Force");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}", t!("Updating modules..."));
|
println!("{}", t!("Updating modules..."));
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ pub fn upgrade_vagrant_boxes(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
println!("{}", t!("No outdated boxes"))
|
println!("{}", t!("No outdated boxes"));
|
||||||
} else {
|
} else {
|
||||||
ctx.run_type()
|
ctx.run_type()
|
||||||
.execute(&vagrant)
|
.execute(&vagrant)
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ impl Tmux {
|
|||||||
.output_checked_utf8()?
|
.output_checked_utf8()?
|
||||||
.stdout
|
.stdout
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| l.parse())
|
.map(str::parse)
|
||||||
.collect::<Result<Vec<usize>, _>>()
|
.collect::<Result<Vec<usize>, _>>()
|
||||||
.context("Failed to compute tmux windows")
|
.context("Failed to compute tmux windows")
|
||||||
}
|
}
|
||||||
@@ -181,19 +181,16 @@ pub fn run_in_tmux(config: TmuxConfig) -> Result<()> {
|
|||||||
pub fn run_command(ctx: &ExecutionContext, window_name: &str, command: &str) -> Result<()> {
|
pub fn run_command(ctx: &ExecutionContext, window_name: &str, command: &str) -> Result<()> {
|
||||||
let tmux = Tmux::new(ctx.config().tmux_config()?.args);
|
let tmux = Tmux::new(ctx.config().tmux_config()?.args);
|
||||||
|
|
||||||
match ctx.get_tmux_session() {
|
if let Some(session_name) = ctx.get_tmux_session() {
|
||||||
Some(session_name) => {
|
let indices = tmux.window_indices(&session_name)?;
|
||||||
let indices = tmux.window_indices(&session_name)?;
|
let last_window = indices
|
||||||
let last_window = indices
|
.iter()
|
||||||
.iter()
|
.last()
|
||||||
.last()
|
.ok_or_else(|| eyre!("tmux session {session_name} has no windows"))?;
|
||||||
.ok_or_else(|| eyre!("tmux session {session_name} has no windows"))?;
|
tmux.new_window(&session_name, &format!("{last_window}"), command)?;
|
||||||
tmux.new_window(&session_name, &format!("{last_window}"), command)?;
|
} else {
|
||||||
}
|
let name = tmux.new_unique_session("topgrade", window_name, command)?;
|
||||||
None => {
|
ctx.set_tmux_session(name);
|
||||||
let name = tmux.new_unique_session("topgrade", window_name, command)?;
|
|
||||||
ctx.set_tmux_session(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ fn upgrade(command: &mut Executor, ctx: &ExecutionContext) -> Result<()> {
|
|||||||
if !status.success() {
|
if !status.success() {
|
||||||
return Err(TopgradeError::ProcessFailed(command.get_program(), status).into());
|
return Err(TopgradeError::ProcessFailed(command.get_program(), status).into());
|
||||||
} else {
|
} else {
|
||||||
println!("{}", t!("Plugins upgraded"))
|
println!("{}", t!("Plugins upgraded"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,7 @@ pub fn run_zr(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn zdotdir() -> PathBuf {
|
fn zdotdir() -> PathBuf {
|
||||||
env::var("ZDOTDIR")
|
env::var("ZDOTDIR").map_or_else(|_| HOME_DIR.clone(), PathBuf::from)
|
||||||
.map(PathBuf::from)
|
|
||||||
.unwrap_or_else(|_| HOME_DIR.clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zshrc() -> PathBuf {
|
pub fn zshrc() -> PathBuf {
|
||||||
@@ -66,8 +64,7 @@ pub fn run_antigen(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let zsh = require("zsh")?;
|
let zsh = require("zsh")?;
|
||||||
let zshrc = zshrc().require()?;
|
let zshrc = zshrc().require()?;
|
||||||
env::var("ADOTDIR")
|
env::var("ADOTDIR")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join("antigen.zsh"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join("antigen.zsh"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
|
|
||||||
print_separator("antigen");
|
print_separator("antigen");
|
||||||
@@ -83,8 +80,7 @@ pub fn run_zgenom(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let zsh = require("zsh")?;
|
let zsh = require("zsh")?;
|
||||||
let zshrc = zshrc().require()?;
|
let zshrc = zshrc().require()?;
|
||||||
env::var("ZGEN_SOURCE")
|
env::var("ZGEN_SOURCE")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join(".zgenom"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".zgenom"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
|
|
||||||
print_separator("zgenom");
|
print_separator("zgenom");
|
||||||
@@ -101,8 +97,7 @@ pub fn run_zplug(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
zshrc().require()?;
|
zshrc().require()?;
|
||||||
|
|
||||||
env::var("ZPLUG_HOME")
|
env::var("ZPLUG_HOME")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join(".zplug"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".zplug"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
|
|
||||||
print_separator("zplug");
|
print_separator("zplug");
|
||||||
@@ -118,8 +113,7 @@ pub fn run_zinit(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
let zshrc = zshrc().require()?;
|
let zshrc = zshrc().require()?;
|
||||||
|
|
||||||
env::var("ZINIT_HOME")
|
env::var("ZINIT_HOME")
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| XDG_DIRS.data_dir().join("zinit"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| XDG_DIRS.data_dir().join("zinit"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
|
|
||||||
print_separator("zinit");
|
print_separator("zinit");
|
||||||
@@ -153,8 +147,7 @@ pub fn run_zim(ctx: &ExecutionContext) -> Result<()> {
|
|||||||
.output_checked_utf8()
|
.output_checked_utf8()
|
||||||
.map(|o| o.stdout)
|
.map(|o| o.stdout)
|
||||||
})
|
})
|
||||||
.map(PathBuf::from)
|
.map_or_else(|_| HOME_DIR.join(".zim"), PathBuf::from)
|
||||||
.unwrap_or_else(|_| HOME_DIR.join(".zim"))
|
|
||||||
.require()?;
|
.require()?;
|
||||||
|
|
||||||
print_separator("zim");
|
print_separator("zim");
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ impl Terminal {
|
|||||||
Self {
|
Self {
|
||||||
width: term.size_checked().map(|(_, w)| w),
|
width: term.size_checked().map(|(_, w)| w),
|
||||||
term,
|
term,
|
||||||
prefix: env::var("TOPGRADE_PREFIX")
|
prefix: env::var("TOPGRADE_PREFIX").map_or_else(|_| String::new(), |prefix| format!("({prefix}) ")),
|
||||||
.map(|prefix| format!("({prefix}) "))
|
|
||||||
.unwrap_or_else(|_| String::new()),
|
|
||||||
set_title: true,
|
set_title: true,
|
||||||
display_time: true,
|
display_time: true,
|
||||||
desktop_notification: false,
|
desktop_notification: false,
|
||||||
@@ -62,15 +60,15 @@ impl Terminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_desktop_notifications(&mut self, desktop_notifications: bool) {
|
fn set_desktop_notifications(&mut self, desktop_notifications: bool) {
|
||||||
self.desktop_notification = desktop_notifications
|
self.desktop_notification = desktop_notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_title(&mut self, set_title: bool) {
|
fn set_title(&mut self, set_title: bool) {
|
||||||
self.set_title = set_title
|
self.set_title = set_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_time(&mut self, display_time: bool) {
|
fn display_time(&mut self, display_time: bool) {
|
||||||
self.display_time = display_time
|
self.display_time = display_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notify_desktop<P: AsRef<str>>(&self, message: P, timeout: Option<Duration>) {
|
fn notify_desktop<P: AsRef<str>>(&self, message: P, timeout: Option<Duration>) {
|
||||||
@@ -223,8 +221,8 @@ impl Terminal {
|
|||||||
|
|
||||||
let answer = loop {
|
let answer = loop {
|
||||||
match self.term.read_key() {
|
match self.term.read_key() {
|
||||||
Ok(Key::Char('y')) | Ok(Key::Char('Y')) => break Ok(true),
|
Ok(Key::Char('y' | 'Y')) => break Ok(true),
|
||||||
Ok(Key::Char('s')) | Ok(Key::Char('S')) => {
|
Ok(Key::Char('s' | 'S')) => {
|
||||||
println!(
|
println!(
|
||||||
"\n\n{}\n",
|
"\n\n{}\n",
|
||||||
t!("Dropping you to shell. Fix what you need and then exit the shell.")
|
t!("Dropping you to shell. Fix what you need and then exit the shell.")
|
||||||
@@ -235,12 +233,12 @@ impl Terminal {
|
|||||||
break Ok(true);
|
break Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Key::Char('n')) | Ok(Key::Char('N')) | Ok(Key::Enter) => break Ok(false),
|
Ok(Key::Char('n' | 'N') | Key::Enter) => break Ok(false),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error reading from terminal: {}", e);
|
error!("Error reading from terminal: {}", e);
|
||||||
break Ok(false);
|
break Ok(false);
|
||||||
}
|
}
|
||||||
Ok(Key::Char('q')) | Ok(Key::Char('Q')) => {
|
Ok(Key::Char('q' | 'Q')) => {
|
||||||
return Err(io::Error::from(io::ErrorKind::Interrupted)).context("Quit from user input")
|
return Err(io::Error::from(io::ErrorKind::Interrupted)).context("Quit from user input")
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
@@ -268,26 +266,26 @@ pub fn should_retry(interrupted: bool, step_name: &str) -> eyre::Result<bool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_separator<P: AsRef<str>>(message: P) {
|
pub fn print_separator<P: AsRef<str>>(message: P) {
|
||||||
TERMINAL.lock().unwrap().print_separator(message)
|
TERMINAL.lock().unwrap().print_separator(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn print_error<P: AsRef<str>, Q: AsRef<str>>(key: Q, message: P) {
|
pub fn print_error<P: AsRef<str>, Q: AsRef<str>>(key: Q, message: P) {
|
||||||
TERMINAL.lock().unwrap().print_error(key, message)
|
TERMINAL.lock().unwrap().print_error(key, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn print_warning<P: AsRef<str>>(message: P) {
|
pub fn print_warning<P: AsRef<str>>(message: P) {
|
||||||
TERMINAL.lock().unwrap().print_warning(message)
|
TERMINAL.lock().unwrap().print_warning(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn print_info<P: AsRef<str>>(message: P) {
|
pub fn print_info<P: AsRef<str>>(message: P) {
|
||||||
TERMINAL.lock().unwrap().print_info(message)
|
TERMINAL.lock().unwrap().print_info(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_result<P: AsRef<str>>(key: P, result: &StepResult) {
|
pub fn print_result<P: AsRef<str>>(key: P, result: &StepResult) {
|
||||||
TERMINAL.lock().unwrap().print_result(key, result)
|
TERMINAL.lock().unwrap().print_result(key, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells whether the terminal is dumb.
|
/// Tells whether the terminal is dumb.
|
||||||
@@ -316,7 +314,7 @@ pub fn prompt_yesno(question: &str) -> Result<bool, io::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_desktop<P: AsRef<str>>(message: P, timeout: Option<Duration>) {
|
pub fn notify_desktop<P: AsRef<str>>(message: P, timeout: Option<Duration>) {
|
||||||
TERMINAL.lock().unwrap().notify_desktop(message, timeout)
|
TERMINAL.lock().unwrap().notify_desktop(message, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_time(display_time: bool) {
|
pub fn display_time(display_time: bool) {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ pub fn editor() -> Vec<String> {
|
|||||||
env::var("EDITOR")
|
env::var("EDITOR")
|
||||||
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
.unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(|s| s.to_owned())
|
.map(std::borrow::ToOwned::to_owned)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user