diff --git a/crates/rome_cli/src/commands/rage.rs b/crates/rome_cli/src/commands/rage.rs
index 4d570eb434c..a88aeb454b9 100644
--- a/crates/rome_cli/src/commands/rage.rs
+++ b/crates/rome_cli/src/commands/rage.rs
@@ -9,6 +9,7 @@ use std::{env, io, ops::Deref};
use tokio::runtime::Runtime;
use crate::commands::daemon::read_most_recent_log_file;
+use crate::service::enumerate_pipes;
use crate::{service, CliSession, Termination, VERSION};
/// Handler for the `rage` command
@@ -85,38 +86,71 @@ struct RunningRomeServer;
impl Display for RunningRomeServer {
fn fmt(&self, f: &mut Formatter) -> io::Result<()> {
- let runtime = Runtime::new()?;
-
- match service::open_transport(runtime) {
- Ok(None) => {
- return markup!(
- {Section("Server")}
- {KeyValuePair("Status", markup!("stopped"))}
- )
- .fmt(f);
+ let versions = match enumerate_pipes() {
+ Ok(iter) => iter,
+ Err(err) => {
+ (markup! {"\u{2716} Enumerating Rome instances failed:"}).fmt(f)?;
+ return writeln!(f, " {err}");
}
- Ok(Some(transport)) => {
- markup!("\n""Running Rome Server:"" "{HorizontalLine::new(78)}"
+ };
+
+ for version in versions {
+ if version == rome_service::VERSION {
+ let runtime = Runtime::new()?;
+ match service::open_transport(runtime) {
+ Ok(None) => {
+ markup!(
+ {Section("Server")}
+ {KeyValuePair("Status", markup!("stopped"))}
+ )
+ .fmt(f)?;
+ continue;
+ }
+ Ok(Some(transport)) => {
+ markup!("\n""Running Rome Server:"" "{HorizontalLine::new(78)}"
""\u{2139} The client isn't connected to any server but rage discovered this running Rome server.""
")
.fmt(f)?;
- match client(transport) {
- Ok(client) => WorkspaceRage(client.deref()).fmt(f)?,
+ match client(transport) {
+ Ok(client) => WorkspaceRage(client.deref()).fmt(f)?,
+ Err(err) => {
+ markup!("\u{2716} Failed to connect: ").fmt(f)?;
+ writeln!(f, "{err}")?;
+ }
+ }
+ }
Err(err) => {
- markup!("\u{2716} Failed to connect: ").fmt(f)?;
+ markup!("\n""\u{2716} Failed to connect: ").fmt(f)?;
writeln!(f, "{err}")?;
}
}
+
+ RomeServerLog.fmt(f)?;
+ } else {
+ markup!("\n""Incompatible Rome Server:"" "{HorizontalLine::new(78)}"
+
+""\u{2139} Rage discovered this running server using an incompatible version of Rome.""
+")
+ .fmt(f)?;
+
+ // Version 10.0.0 and below did not include a service version in the pipe name
+ let version = if version.is_empty() {
+ "<=10.0.0"
+ } else {
+ version.as_str()
+ };
+
+ markup!(
+ {Section("Server")}
+ {KeyValuePair("Version", markup!({version}))}
+ )
+ .fmt(f)?;
}
- Err(err) => {
- markup!("\n""\u{2716} Failed to connect: ").fmt(f)?;
- writeln!(f, "{err}")?;
- }
- };
+ }
- RomeServerLog.fmt(f)
+ Ok(())
}
}
diff --git a/crates/rome_cli/src/service/mod.rs b/crates/rome_cli/src/service/mod.rs
index e983010b367..a0b5b3b6d8b 100644
--- a/crates/rome_cli/src/service/mod.rs
+++ b/crates/rome_cli/src/service/mod.rs
@@ -43,14 +43,16 @@ use tokio::{
#[cfg(windows)]
mod windows;
#[cfg(windows)]
-pub(crate) use self::windows::{ensure_daemon, open_socket, print_socket, run_daemon};
+pub(crate) use self::windows::{
+ ensure_daemon, enumerate_pipes, open_socket, print_socket, run_daemon,
+};
#[cfg(unix)]
mod unix;
#[cfg(unix)]
-pub(crate) use self::unix::open_socket;
-#[cfg(unix)]
-pub(crate) use self::unix::{ensure_daemon, print_socket, run_daemon};
+pub(crate) use self::unix::{
+ ensure_daemon, enumerate_pipes, open_socket, print_socket, run_daemon,
+};
/// Tries to open a connection to a running daemon instance, returning a
/// [WorkspaceTransport] instance if the socket is currently active
diff --git a/crates/rome_cli/src/service/unix.rs b/crates/rome_cli/src/service/unix.rs
index b9b0cfdbc4b..f5d046f92da 100644
--- a/crates/rome_cli/src/service/unix.rs
+++ b/crates/rome_cli/src/service/unix.rs
@@ -21,7 +21,24 @@ use tracing::Instrument;
/// Returns the filesystem path of the global socket used to communicate with
/// the server daemon
fn get_socket_name() -> PathBuf {
- env::temp_dir().join("rome-socket")
+ env::temp_dir().join(format!("rome-socket-{}", rome_service::VERSION))
+}
+
+pub(crate) fn enumerate_pipes() -> io::Result> {
+ fs::read_dir(env::temp_dir()).map(|iter| {
+ iter.filter_map(|entry| {
+ let entry = entry.ok()?.path();
+ let file_name = entry.file_name()?;
+ let file_name = file_name.to_str()?;
+
+ let rome_version = file_name.strip_prefix("rome-socket")?;
+ if rome_version.is_empty() {
+ Some(String::new())
+ } else {
+ Some(rome_version.strip_prefix('-')?.to_string())
+ }
+ })
+ })
}
/// Try to connect to the global socket and wait for the connection to become ready
diff --git a/crates/rome_cli/src/service/windows.rs b/crates/rome_cli/src/service/windows.rs
index b873cd46bdb..513cb16cae5 100644
--- a/crates/rome_cli/src/service/windows.rs
+++ b/crates/rome_cli/src/service/windows.rs
@@ -1,6 +1,7 @@
use std::{
convert::Infallible,
env,
+ fs::read_dir,
io::{self, ErrorKind},
mem::swap,
os::windows::process::CommandExt,
@@ -19,8 +20,28 @@ use tokio::{
};
use tracing::Instrument;
-/// Name of the global named pipe used to communicate with the server daemon
-const PIPE_NAME: &str = r"\\.\pipe\rome-service";
+/// Returns the name of the global named pipe used to communicate with the
+/// server daemon
+fn get_pipe_name() -> String {
+ format!(r"\\.\pipe\rome-service-{}", rome_service::VERSION)
+}
+
+pub(crate) fn enumerate_pipes() -> io::Result> {
+ read_dir(r"\\.\pipe").map(|iter| {
+ iter.filter_map(|entry| {
+ let entry = entry.ok()?.path();
+ let file_name = entry.file_name()?;
+ let file_name = file_name.to_str()?;
+
+ let rome_version = file_name.strip_prefix("rome-service")?;
+ if rome_version.is_empty() {
+ Some(String::new())
+ } else {
+ Some(rome_version.strip_prefix('-')?.to_string())
+ }
+ })
+ })
+}
/// Error code from the Win32 API
const ERROR_PIPE_BUSY: i32 = 231;
@@ -28,7 +49,7 @@ const ERROR_PIPE_BUSY: i32 = 231;
/// Try to connect to the global pipe and wait for the connection to become ready
async fn try_connect() -> io::Result {
loop {
- match ClientOptions::new().open(PIPE_NAME) {
+ match ClientOptions::new().open(get_pipe_name()) {
Ok(client) => return Ok(client),
// If the connection failed with ERROR_PIPE_BUSY, wait a few
// milliseconds then retry the connection (we should be using
@@ -165,7 +186,7 @@ pub(crate) async fn ensure_daemon() -> io::Result {
/// print the global pipe name in the standard output
pub(crate) async fn print_socket() -> io::Result<()> {
ensure_daemon().await?;
- println!("{PIPE_NAME}");
+ println!("{}", get_pipe_name());
Ok(())
}
@@ -174,11 +195,11 @@ pub(crate) async fn print_socket() -> io::Result<()> {
pub(crate) async fn run_daemon(factory: ServerFactory) -> io::Result {
let mut prev_server = ServerOptions::new()
.first_pipe_instance(true)
- .create(PIPE_NAME)?;
+ .create(get_pipe_name())?;
loop {
prev_server.connect().await?;
- let mut next_server = ServerOptions::new().create(PIPE_NAME)?;
+ let mut next_server = ServerOptions::new().create(get_pipe_name())?;
swap(&mut prev_server, &mut next_server);
let connection = factory.create();