Add support for multiple binary names and idea having multiple binaries (#1167)

Add support for tools to have multiple possible binaries because IntellIj IDEA on the AUR can have multiple depending on the edition.

[AUR Ultimate Edition](https://aur.archlinux.org/packages/intellij-idea-ultimate-edition) and [AUR Community Edition](https://aur.archlinux.org/packages/intellij-idea-community-edition-bin) renames the binary to `intellij-idea-ultimate-edition` and `intellij-idea-community-edition` respectively.
This commit is contained in:
Stuart Reilly
2025-06-17 04:52:58 +01:00
committed by GitHub
parent 31fe5aa452
commit 845558c1da
3 changed files with 77 additions and 15 deletions

View File

@@ -414,6 +414,14 @@ _version: 2
zh_CN: "在 $PATH 中找不到 %{binary_name} 二进制" zh_CN: "在 $PATH 中找不到 %{binary_name} 二进制"
zh_TW: "在 $PATH 中找不到 %{binary_name} 執行檔" zh_TW: "在 $PATH 中找不到 %{binary_name} 執行檔"
de: "Kann %{binary_name} nicht im PATH finden" de: "Kann %{binary_name} nicht im PATH finden"
"Cannot find any of {binary_names} in PATH":
en: "Cannot find any of %{binary_names} in PATH"
lt: "Nepavyksta rasti jokių %{binary_names} PATH sąraše"
es: "No se puede encontrar ninguno de %{binary_names} en PATH"
fr: "Impossible de trouver %{binary_names} dans PATH"
zh_CH: "在 PATH 中找不到 %{binary_names}"
zh_TW: "在 PATH 中找不到 %{binary_names}"
de: "Kann keines von %{binary_names} im PATH finden"
"Failed to get a UTF-8 encoded hostname": "Failed to get a UTF-8 encoded hostname":
en: "Failed to get a UTF-8 encoded hostname" en: "Failed to get a UTF-8 encoded hostname"
lt: "Nepavyko gauti UTF-8 koduoto kompiuterio pavadinimo" lt: "Nepavyko gauti UTF-8 koduoto kompiuterio pavadinimo"

View File

@@ -18,7 +18,9 @@ use crate::command::{CommandExt, Utf8Output};
use crate::execution_context::ExecutionContext; use crate::execution_context::ExecutionContext;
use crate::executor::ExecutorOutput; use crate::executor::ExecutorOutput;
use crate::terminal::{print_separator, shell}; use crate::terminal::{print_separator, shell};
use crate::utils::{check_is_python_2_or_shim, get_require_sudo_string, require, require_option, which, PathExt}; use crate::utils::{
check_is_python_2_or_shim, get_require_sudo_string, require, require_one, require_option, which, PathExt,
};
use crate::HOME_DIR; use crate::HOME_DIR;
use crate::{ use crate::{
error::{SkipStep, StepFailed, TopgradeError}, error::{SkipStep, StepFailed, TopgradeError},
@@ -1594,7 +1596,16 @@ fn run_jetbrains_ide(ctx: &ExecutionContext, bin: PathBuf, name: &str) -> Result
pub fn run_android_studio(ctx: &ExecutionContext) -> Result<()> { pub fn run_android_studio(ctx: &ExecutionContext) -> Result<()> {
// We don't use `run_jetbrains_ide` here because that would print "JetBrains Android Studio", // We don't use `run_jetbrains_ide` here because that would print "JetBrains Android Studio",
// which is incorrect as Android Studio is made by Google. Just "Android Studio" is fine. // which is incorrect as Android Studio is made by Google. Just "Android Studio" is fine.
run_jetbrains_ide_generic::<false>(ctx, require("studio")?, "Android Studio") run_jetbrains_ide_generic::<false>(
ctx,
require_one([
"studio",
"android-studio",
"android-studio-beta",
"android-studio-canary",
])?,
"Android Studio",
)
} }
pub fn run_jetbrains_aqua(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_aqua(ctx: &ExecutionContext) -> Result<()> {
@@ -1602,31 +1613,43 @@ pub fn run_jetbrains_aqua(ctx: &ExecutionContext) -> Result<()> {
} }
pub fn run_jetbrains_clion(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_clion(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("clion")?, "CLion") run_jetbrains_ide(ctx, require_one(["clion", "clion-eap"])?, "CLion")
} }
pub fn run_jetbrains_datagrip(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_datagrip(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("datagrip")?, "DataGrip") run_jetbrains_ide(ctx, require_one(["datagrip", "datagrip-eap"])?, "DataGrip")
} }
pub fn run_jetbrains_dataspell(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_dataspell(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("dataspell")?, "DataSpell") run_jetbrains_ide(ctx, require_one(["dataspell", "dataspell-eap"])?, "DataSpell")
} }
pub fn run_jetbrains_gateway(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_gateway(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("gateway")?, "Gateway") run_jetbrains_ide(
ctx,
require_one(["gateway", "jetbrains-gateway", "jetbrains-gateway-eap"])?,
"Gateway",
)
} }
pub fn run_jetbrains_goland(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_goland(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("goland")?, "Goland") run_jetbrains_ide(ctx, require_one(["goland", "goland-eap"])?, "Goland")
} }
pub fn run_jetbrains_idea(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_idea(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("idea")?, "IntelliJ IDEA") run_jetbrains_ide(
ctx,
require_one([
"idea",
"intellij-idea-ultimate-edition",
"intellij-idea-community-edition",
])?,
"IntelliJ IDEA",
)
} }
pub fn run_jetbrains_mps(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_mps(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("mps")?, "MPS") run_jetbrains_ide(ctx, require_one(["mps", "jetbrains-mps"])?, "MPS")
} }
pub fn run_jetbrains_phpstorm(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_phpstorm(ctx: &ExecutionContext) -> Result<()> {
@@ -1634,23 +1657,31 @@ pub fn run_jetbrains_phpstorm(ctx: &ExecutionContext) -> Result<()> {
} }
pub fn run_jetbrains_pycharm(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_pycharm(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("pycharm")?, "PyCharm") run_jetbrains_ide(
ctx,
require_one(["pycharm", "pycharm-professional", "pycharm-eap"])?,
"PyCharm",
)
} }
pub fn run_jetbrains_rider(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_rider(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("rider")?, "Rider") run_jetbrains_ide(ctx, require_one(["rider", "rider-eap"])?, "Rider")
} }
pub fn run_jetbrains_rubymine(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_rubymine(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("rubymine")?, "RubyMine") run_jetbrains_ide(
ctx,
require_one(["rubymine", "jetbrains-rubymine", "rubymine-eap"])?,
"RubyMine",
)
} }
pub fn run_jetbrains_rustrover(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_rustrover(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("rustrover")?, "RustRover") run_jetbrains_ide(ctx, require_one(["rustrover", "rustrover-eap"])?, "RustRover")
} }
pub fn run_jetbrains_webstorm(ctx: &ExecutionContext) -> Result<()> { pub fn run_jetbrains_webstorm(ctx: &ExecutionContext) -> Result<()> {
run_jetbrains_ide(ctx, require("webstorm")?, "WebStorm") run_jetbrains_ide(ctx, require_one(["webstorm", "webstorm-eap"])?, "WebStorm")
} }
pub fn run_yazi(ctx: &ExecutionContext) -> Result<()> { pub fn run_yazi(ctx: &ExecutionContext) -> Result<()> {

View File

@@ -112,6 +112,29 @@ pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf> {
} }
} }
pub fn require_one<T: AsRef<OsStr> + Debug>(binary_names: impl IntoIterator<Item = T>) -> Result<PathBuf> {
let mut failed_bins = Vec::new();
for bin in binary_names {
match require(&bin) {
Ok(path) => return Ok(path),
Err(_) => failed_bins.push(bin),
}
}
Err(SkipStep(format!(
"{}",
t!(
"Cannot find any of {binary_names} in PATH",
binary_names = failed_bins
.iter()
.map(|bin| format!("{:?}", bin))
.collect::<Vec<_>>()
.join(", ")
)
))
.into())
}
#[allow(dead_code)] #[allow(dead_code)]
pub fn require_option<T>(option: Option<T>, cause: String) -> Result<T> { pub fn require_option<T>(option: Option<T>, cause: String) -> Result<T> {
if let Some(value) = option { if let Some(value) = option {