Skip to content

Commit 0270af8

Browse files
authored
feat: Cross-platform microfrontends port command (#11098)
### Description Adds a `turbo get-mfe-port` command so you can more easily assign the ports to your microfrontends. The command fetches the port for the microfrontend according to `microfrontends.json`, and forwards it into the script. ### Testing Instructions Hand-tested it and added some tests.
1 parent 1de3775 commit 0270af8

File tree

12 files changed

+565
-102
lines changed

12 files changed

+565
-102
lines changed

crates/turborepo-lib/src/cli/error.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use turborepo_telemetry::events::command::CommandEventBuilder;
99
use turborepo_ui::{color, BOLD, GREY};
1010

1111
use crate::{
12-
commands::{bin, generate, link, login, ls, prune, CommandBase},
12+
commands::{bin, generate, get_mfe_port, link, login, ls, prune, CommandBase},
1313
daemon::DaemonError,
1414
query,
1515
rewrite_json::RewriteError,
@@ -46,6 +46,8 @@ pub enum Error {
4646
#[error(transparent)]
4747
Generate(#[from] generate::Error),
4848
#[error(transparent)]
49+
GetMfePort(#[from] get_mfe_port::Error),
50+
#[error(transparent)]
4951
#[diagnostic(transparent)]
5052
Ls(#[from] ls::Error),
5153
#[error(transparent)]
@@ -125,3 +127,58 @@ pub async fn print_potential_tasks(
125127

126128
Ok(())
127129
}
130+
131+
#[cfg(test)]
132+
mod tests {
133+
use super::*;
134+
135+
#[test]
136+
fn test_get_mfe_port_error_conversion() {
137+
// Test NoPackageJson error
138+
let err = get_mfe_port::Error::NoPackageJson;
139+
let cli_err: Error = err.into();
140+
assert!(matches!(cli_err, Error::GetMfePort(_)));
141+
assert_eq!(
142+
cli_err.to_string(),
143+
"No package.json found in current directory"
144+
);
145+
146+
// Test NoPackageName error
147+
let err = get_mfe_port::Error::NoPackageName;
148+
let cli_err: Error = err.into();
149+
assert!(matches!(cli_err, Error::GetMfePort(_)));
150+
assert_eq!(
151+
cli_err.to_string(),
152+
"package.json is missing the 'name' field"
153+
);
154+
155+
// Test NoMicrofrontendsConfig error
156+
let err = get_mfe_port::Error::NoMicrofrontendsConfig;
157+
let cli_err: Error = err.into();
158+
assert!(matches!(cli_err, Error::GetMfePort(_)));
159+
assert_eq!(cli_err.to_string(), "No microfrontends configuration found");
160+
161+
// Test PackageNotInConfig error
162+
let err = get_mfe_port::Error::PackageNotInConfig("my-app".to_string());
163+
let cli_err: Error = err.into();
164+
assert!(matches!(cli_err, Error::GetMfePort(_)));
165+
assert_eq!(
166+
cli_err.to_string(),
167+
"Package 'my-app' not found in microfrontends configuration"
168+
);
169+
}
170+
171+
#[test]
172+
fn test_get_mfe_port_error_source() {
173+
// Test that error source chain works properly
174+
let err = get_mfe_port::Error::NoPackageJson;
175+
let cli_err: Error = err.into();
176+
177+
match cli_err {
178+
Error::GetMfePort(inner) => {
179+
assert!(matches!(inner, get_mfe_port::Error::NoPackageJson));
180+
}
181+
_ => panic!("Expected GetMfePort error variant"),
182+
}
183+
}
184+
}

crates/turborepo-lib/src/cli/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use turborepo_ui::{ColorConfig, GREY};
2828
use crate::{
2929
cli::error::print_potential_tasks,
3030
commands::{
31-
bin, boundaries, clone, config, daemon, generate, info, link, login, logout, ls, prune,
32-
query, run, scan, telemetry, unlink, CommandBase,
31+
bin, boundaries, clone, config, daemon, generate, get_mfe_port, info, link, login, logout,
32+
ls, prune, query, run, scan, telemetry, unlink, CommandBase,
3333
},
3434
get_version,
3535
run::watch::WatchClient,
@@ -574,6 +574,9 @@ impl Args {
574574
pub enum Command {
575575
/// Get the path to the Turbo binary
576576
Bin,
577+
/// Get the port assigned to the current microfrontend
578+
#[clap(name = "get-mfe-port")]
579+
GetMfePort,
577580
#[clap(hide = true)]
578581
Boundaries {
579582
#[clap(short = 'F', long, group = "scope-filter-group")]
@@ -1393,6 +1396,15 @@ pub async fn run(
13931396

13941397
Ok(0)
13951398
}
1399+
Command::GetMfePort => {
1400+
let event = CommandEventBuilder::new("get-mfe-port").with_parent(&root_telemetry);
1401+
event.track_call();
1402+
1403+
let base = CommandBase::new(cli_args.clone(), repo_root, version, color_config)?;
1404+
get_mfe_port::run(&base).await?;
1405+
1406+
Ok(0)
1407+
}
13961408
Command::Boundaries { ignore, reason, .. } => {
13971409
let event = CommandEventBuilder::new("boundaries").with_parent(&root_telemetry);
13981410
let ignore = *ignore;

0 commit comments

Comments
 (0)