Skip to content

Commit

Permalink
feat(mfe): inject local proxy task
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-olszewski committed Oct 28, 2024
1 parent ac99d41 commit c7d492f
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 16 deletions.
1 change: 1 addition & 0 deletions crates/turborepo-lib/src/engine/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl<'a> EngineBuilder<'a> {
let task_id = task
.task_id()
.unwrap_or_else(|| TaskId::new(workspace.as_ref(), task.task()));
eprintln!("{task_id:?}");

if Self::has_task_definition(&mut turbo_json_loader, workspace, task, &task_id)? {
missing_tasks.remove(task.as_inner());
Expand Down
37 changes: 33 additions & 4 deletions crates/turborepo-lib/src/run/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use {
},
};

use super::task_id::TaskId;
use crate::{
cli::DryRunMode,
commands::CommandBase,
Expand Down Expand Up @@ -403,6 +404,14 @@ impl RunBuilder {
self.repo_root.clone(),
pkg_dep_graph.packages(),
)
} else if !micro_frontend_configs.is_empty() {
eprintln!("hit this");
TurboJsonLoader::workspace_with_microfrontends(
self.repo_root.clone(),
self.root_turbo_json_path.clone(),
pkg_dep_graph.packages(),
micro_frontend_configs.clone(),
)
} else {
TurboJsonLoader::workspace(
self.repo_root.clone(),
Expand All @@ -429,6 +438,7 @@ impl RunBuilder {
&root_turbo_json,
filtered_pkgs.keys(),
turbo_json_loader.clone(),
&micro_frontend_configs,
)?;

if self.opts.run_opts.parallel {
Expand All @@ -438,6 +448,7 @@ impl RunBuilder {
&root_turbo_json,
filtered_pkgs.keys(),
turbo_json_loader,
&micro_frontend_configs,
)?;
}

Expand Down Expand Up @@ -488,7 +499,28 @@ impl RunBuilder {
root_turbo_json: &TurboJson,
filtered_pkgs: impl Iterator<Item = &'a PackageName>,
turbo_json_loader: TurboJsonLoader,
micro_frontends_configs: &HashMap<String, HashSet<TaskId<'static>>>,
) -> Result<Engine, Error> {
let mut tasks = self
.opts
.run_opts
.tasks
.iter()
.map(|task| {
// TODO: Pull span info from command
Spanned::new(TaskName::from(task.as_str()).into_owned())
})
.collect::<Vec<_>>();
if !micro_frontends_configs.is_empty() {
tasks.push(Spanned::new(TaskName::from("proxy").into_owned()));
}
/*
tasks.extend(
micro_frontends_configs
.keys()
.map(|pkg| Spanned::new(TaskId::new(pkg, "proxy").as_task_name().into_owned())),
);
*/
let mut builder = EngineBuilder::new(
&self.repo_root,
pkg_dep_graph,
Expand All @@ -498,10 +530,7 @@ impl RunBuilder {
.with_root_tasks(root_turbo_json.tasks.keys().cloned())
.with_tasks_only(self.opts.run_opts.only)
.with_workspaces(filtered_pkgs.cloned().collect())
.with_tasks(self.opts.run_opts.tasks.iter().map(|task| {
// TODO: Pull span info from command
Spanned::new(TaskName::from(task.as_str()).into_owned())
}));
.with_tasks(tasks);

if self.add_all_tasks {
builder = builder.add_all_tasks();
Expand Down
1 change: 1 addition & 0 deletions crates/turborepo-lib/src/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ impl Run {
global_env,
ui_sender,
is_watch,
&self.micro_frontend_configs,
)
.await;

Expand Down
83 changes: 81 additions & 2 deletions crates/turborepo-lib/src/task_graph/visitor/command.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::path::PathBuf;
use std::{
collections::{HashMap, HashSet},
path::PathBuf,
};

use turbopath::AbsoluteSystemPath;
use turborepo_env::EnvironmentVariableMap;
use turborepo_repository::package_graph::{PackageGraph, PackageInfo, PackageName};

use super::Error;
use crate::{opts::TaskArgs, process::Command, run::task_id::TaskId};
use crate::{engine::Engine, opts::TaskArgs, process::Command, run::task_id::TaskId};

pub trait CommandProvider {
fn command(
Expand Down Expand Up @@ -126,6 +129,82 @@ impl<'a> CommandProvider for PackageGraphCommandProvider<'a> {
}
}

#[derive(Debug)]
pub struct MicroFrontendProxyProvider<'a> {
repo_root: &'a AbsoluteSystemPath,
package_graph: &'a PackageGraph,
tasks_in_graph: HashSet<TaskId<'a>>,
mfe_configs: &'a HashMap<String, HashSet<TaskId<'static>>>,
}

impl<'a> MicroFrontendProxyProvider<'a> {
pub fn new(
repo_root: &'a AbsoluteSystemPath,
package_graph: &'a PackageGraph,
engine: &Engine,
micro_frontends_configs: &'a HashMap<String, HashSet<TaskId<'static>>>,
) -> Self {
let tasks_in_graph = engine
.tasks()
.filter_map(|task| match task {
crate::engine::TaskNode::Task(task_id) => Some(task_id),
crate::engine::TaskNode::Root => None,
})
.cloned()
.collect();
Self {
repo_root,
package_graph,
tasks_in_graph,
mfe_configs: micro_frontends_configs,
}
}

fn dev_tasks(&self, task_id: &TaskId) -> Option<&HashSet<TaskId<'static>>> {
(task_id.task() == "proxy")
.then(|| self.mfe_configs.get(task_id.package()))
.flatten()
}

fn package_info(&self, task_id: &TaskId) -> Result<&PackageInfo, Error> {
self.package_graph
.package_info(&PackageName::from(task_id.package()))
.ok_or_else(|| Error::MissingPackage {
package_name: task_id.package().into(),
task_id: task_id.clone().into_owned(),
})
}
}

impl<'a> CommandProvider for MicroFrontendProxyProvider<'a> {
fn command(
&self,
task_id: &TaskId,
_environment: EnvironmentVariableMap,
) -> Result<Option<Command>, Error> {
let Some(dev_tasks) = self.dev_tasks(task_id) else {
return Ok(None);
};
let package_info = self.package_info(task_id)?;
let local_apps = dev_tasks
.iter()
.filter(|task| self.tasks_in_graph.contains(task))
.map(|task| task.package());
let package_dir = self.repo_root.resolve(package_info.package_path());
let mfe_path = package_dir.join_component("micro-frontends.jsonc");
let mut args = vec!["proxy", mfe_path.as_str(), "--names"];
args.extend(local_apps);

// TODO: leverage package manager to find the local proxy
let program = package_dir.join_components(&["node_modules", ".bin", "micro-frontends"]);
let mut cmd = Command::new(program.as_std_path());
cmd.current_dir(package_dir).args(args);
eprintln!("running proxy {}", cmd.label());

Ok(Some(cmd))
}
}

#[cfg(test)]
mod test {
use std::ffi::OsStr;
Expand Down
12 changes: 10 additions & 2 deletions crates/turborepo-lib/src/task_graph/visitor/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use turborepo_telemetry::events::{task::PackageTaskEventBuilder, TrackedErrors};
use turborepo_ui::{ColorConfig, OutputWriter};

use super::{
command::{CommandFactory, PackageGraphCommandProvider},
command::{CommandFactory, MicroFrontendProxyProvider, PackageGraphCommandProvider},
error::{TaskError, TaskErrorCause, TaskWarning},
output::TaskCacheOutput,
TaskOutput, Visitor,
Expand Down Expand Up @@ -51,7 +51,15 @@ impl<'a> ExecContextFactory<'a> {
&visitor.package_graph,
visitor.run_opts.task_args(),
);
let command_factory = CommandFactory::new().add_provider(pkg_graph_provider);
let mfe_proxy_provider = MicroFrontendProxyProvider::new(
visitor.repo_root,
&visitor.package_graph,
engine,
visitor.micro_frontends_configs,
);
let command_factory = CommandFactory::new()
.add_provider(mfe_proxy_provider)
.add_provider(pkg_graph_provider);
Ok(Self {
visitor,
errors,
Expand Down
5 changes: 4 additions & 1 deletion crates/turborepo-lib/src/task_graph/visitor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod output;

use std::{
borrow::Cow,
collections::HashSet,
collections::{HashMap, HashSet},
io::Write,
sync::{Arc, Mutex, OnceLock},
};
Expand Down Expand Up @@ -65,6 +65,7 @@ pub struct Visitor<'a> {
is_watch: bool,
ui_sender: Option<UISender>,
warnings: Arc<Mutex<Vec<TaskWarning>>>,
micro_frontends_configs: &'a HashMap<String, HashSet<TaskId<'static>>>,
}

#[derive(Debug, thiserror::Error, Diagnostic)]
Expand Down Expand Up @@ -119,6 +120,7 @@ impl<'a> Visitor<'a> {
global_env: EnvironmentVariableMap,
ui_sender: Option<UISender>,
is_watch: bool,
micro_frontends_configs: &'a HashMap<String, HashSet<TaskId<'static>>>,
) -> Self {
let task_hasher = TaskHasher::new(
package_inputs_hashes,
Expand Down Expand Up @@ -155,6 +157,7 @@ impl<'a> Visitor<'a> {
ui_sender,
is_watch,
warnings: Default::default(),
micro_frontends_configs,
}
}

Expand Down
Loading

0 comments on commit c7d492f

Please sign in to comment.