Skip to content

Commit 4b3a3e7

Browse files
authored
Fix "Only one instance of <IDE> can be run at a a time." error (#1123)
1 parent 2c4751c commit 4b3a3e7

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

src/steps/generic.rs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use color_eyre::eyre::eyre;
21
use color_eyre::eyre::Context;
32
use color_eyre::eyre::Result;
3+
use color_eyre::eyre::{eyre, OptionExt};
44
use jetbrains_toolbox_updater::{find_jetbrains_toolbox, update_jetbrains_toolbox, FindError};
55
use regex::bytes::Regex;
66
use rust_i18n::t;
@@ -12,7 +12,7 @@ use std::sync::LazyLock;
1212
use std::{env, path::Path};
1313
use std::{fs, io::Write};
1414
use tempfile::tempfile_in;
15-
use tracing::{debug, error};
15+
use tracing::{debug, error, warn};
1616

1717
use crate::command::{CommandExt, Utf8Output};
1818
use crate::execution_context::ExecutionContext;
@@ -1549,21 +1549,52 @@ pub fn run_jetbrains_toolbox(_ctx: &ExecutionContext) -> Result<()> {
15491549
}
15501550
}
15511551

1552-
fn run_jetbrains_ide(ctx: &ExecutionContext, bin: PathBuf, name: &str) -> Result<()> {
1553-
print_separator(format!("JetBrains {name} plugins"));
1552+
fn run_jetbrains_ide_generic<const IS_JETBRAINS: bool>(ctx: &ExecutionContext, bin: PathBuf, name: &str) -> Result<()> {
1553+
let prefix = if IS_JETBRAINS { "JetBrains " } else { "" };
1554+
print_separator(format!("{prefix}{name} plugins"));
15541555

15551556
// The `update` command is undocumented, but tested on all of the below.
1556-
ctx.run_type().execute(bin).arg("update").status_checked()
1557+
let output = ctx.run_type().execute(&bin).arg("update").output()?;
1558+
let output = match output {
1559+
ExecutorOutput::Dry => return Ok(()),
1560+
ExecutorOutput::Wet(output) => output,
1561+
};
1562+
// Write the output which we swallowed in all cases
1563+
std::io::stdout().lock().write_all(&output.stdout).unwrap();
1564+
std::io::stderr().lock().write_all(&output.stderr).unwrap();
1565+
1566+
let stdout = String::from_utf8(output.stdout.clone()).wrap_err("Expected valid UTF-8 output")?;
1567+
1568+
// "Only one instance of RustRover can be run at a time."
1569+
if stdout.contains("Only one instance of ") && stdout.contains(" can be run at a time.") {
1570+
// It's always paired with status code 1
1571+
let status_code = output
1572+
.status
1573+
.code()
1574+
.ok_or_eyre("Failed to get status code; was killed with signal")?;
1575+
if status_code != 1 {
1576+
return Err(eyre!("Expected status code 1 ('Only one instance of <IDE> can be run at a time.'), but found status code {}. Output: {output:?}", status_code));
1577+
}
1578+
// Don't crash, but don't be silent either
1579+
warn!("{name} is already running, can't update it now.");
1580+
Err(SkipStep(format!("{name} is already running, can't update it now.")).into())
1581+
} else if !output.status.success() {
1582+
// Unknown failure
1583+
Err(eyre!("Running `{bin:?} update` failed. Output: {output:?}"))
1584+
} else {
1585+
// Success. Output was already written above
1586+
Ok(())
1587+
}
1588+
}
1589+
1590+
fn run_jetbrains_ide(ctx: &ExecutionContext, bin: PathBuf, name: &str) -> Result<()> {
1591+
run_jetbrains_ide_generic::<true>(ctx, bin, name)
15571592
}
15581593

15591594
pub fn run_android_studio(ctx: &ExecutionContext) -> Result<()> {
15601595
// We don't use `run_jetbrains_ide` here because that would print "JetBrains Android Studio",
15611596
// which is incorrect as Android Studio is made by Google. Just "Android Studio" is fine.
1562-
let bin = require("studio")?;
1563-
1564-
print_separator("Android Studio plugins");
1565-
1566-
ctx.run_type().execute(bin).arg("update").status_checked()
1597+
run_jetbrains_ide_generic::<false>(ctx, require("studio")?, "Android Studio")
15671598
}
15681599

15691600
pub fn run_jetbrains_aqua(ctx: &ExecutionContext) -> Result<()> {

0 commit comments

Comments
 (0)