From ce5ed479bfa04cea5df97afffd348458685367b7 Mon Sep 17 00:00:00 2001 From: Anthony Shew Date: Mon, 21 Sep 2026 10:34:51 -0600 Subject: [PATCH] refactor: Use RepoContext in task graph visitor --- crates/turborepo-lib/src/run/mod.rs | 6 +- .../src/task_graph/visitor/exec.rs | 6 +- .../src/task_graph/visitor/mod.rs | 79 +++++++++---------- 3 files changed, 42 insertions(+), 49 deletions(-) diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 9e3cbfa33f23b..91c367ff1be1e 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -1181,7 +1181,7 @@ impl Run { drop(_setup_span); let mut visitor = Visitor::new( - self.pkg_dep_graph_handle(), + self.repo.as_ref(), self.run_cache.clone(), run_tracker, &self.task_access, @@ -1189,10 +1189,7 @@ impl Run { package_inputs_hashes, &self.env_at_execution_start, &global_hash, - self.color_config(), self.processes.clone(), - self.repo_root(), - self.scm(), repo_index, global_env, &self.root_turbo_json().global_env, @@ -1251,7 +1248,6 @@ impl Run { global_hash_inputs, &self.engine, &self.env_at_execution_start, - self.scm(), self.opts.scope_opts.pkg_inference_root.as_deref(), ) .await?; diff --git a/crates/turborepo-lib/src/task_graph/visitor/exec.rs b/crates/turborepo-lib/src/task_graph/visitor/exec.rs index 9b16fda9c456d..70c91d806ca45 100644 --- a/crates/turborepo-lib/src/task_graph/visitor/exec.rs +++ b/crates/turborepo-lib/src/task_graph/visitor/exec.rs @@ -62,7 +62,7 @@ impl<'a> ExecContextFactory<'a> { }) .collect(); let pkg_graph_provider = ToolchainCommandProvider::new( - &visitor.package_graph, + &visitor.repo.pkg_dep_graph, visitor.run_opts.task_args(), visitor.micro_frontends_configs, command_overrides, @@ -70,7 +70,7 @@ impl<'a> ExecContextFactory<'a> { let mut command_factory = CommandFactory::new(); if let Some(micro_frontends_configs) = visitor.micro_frontends_configs { command_factory.add_provider(MicroFrontendProxyProvider::new( - visitor.package_graph.as_ref(), + visitor.repo.pkg_dep_graph.as_ref(), engine.task_ids(), micro_frontends_configs, )); @@ -115,7 +115,7 @@ impl<'a> ExecContextFactory<'a> { takes_input, continue_on_error: self.visitor.run_opts.continue_on_error, ui_mode: self.visitor.run_opts.ui_mode, - color_config: self.visitor.color_config, + color_config: self.visitor.repo.color_config, is_github_actions: self.visitor.run_opts.is_github_actions, pretty_prefix, task_cache, diff --git a/crates/turborepo-lib/src/task_graph/visitor/mod.rs b/crates/turborepo-lib/src/task_graph/visitor/mod.rs index 102fb84a9fac0..9ba4db0721d45 100644 --- a/crates/turborepo-lib/src/task_graph/visitor/mod.rs +++ b/crates/turborepo-lib/src/task_graph/visitor/mod.rs @@ -16,16 +16,17 @@ use itertools::Itertools; use miette::{Diagnostic, NamedSource, SourceSpan}; use tokio::{sync::mpsc, task::JoinError}; use tracing::{debug, Instrument, Span}; -use turbopath::{AbsoluteSystemPath, AnchoredSystemPath, AnchoredSystemPathBuf}; +use turbopath::{AnchoredSystemPath, AnchoredSystemPathBuf}; use turborepo_engine::{TaskError, TaskWarning}; use turborepo_env::{platform::PlatformEnv, EnvironmentVariableMap}; use turborepo_errors::TURBO_SITE; use turborepo_log::grouping::{GroupingLayer, GroupingMode}; use turborepo_microfrontends_config::MicrofrontendsConfigs; use turborepo_process::ProcessManager; -use turborepo_repository::package_graph::{PackageGraph, PackageName, ROOT_PKG_NAME}; +use turborepo_repository::package_graph::{PackageName, ROOT_PKG_NAME}; +use turborepo_run_context::RepoContext; use turborepo_run_summary::{self as summary, GlobalHashSummary, RunTracker, TaskTracker}; -use turborepo_scm::{RepoGitIndex, SCM}; +use turborepo_scm::RepoGitIndex; use turborepo_task_access::TaskAccess; use turborepo_task_executor::{ command_invokes_turbo, InternalError as TaskInternalError, TaskOutput, @@ -38,7 +39,7 @@ use turborepo_telemetry::events::{ generic::GenericEventBuilder, task::PackageTaskEventBuilder, EventBuilder, TrackedErrors, }; use turborepo_types::{EnvMode, ResolvedLogOrder, ResolvedLogPrefix}; -use turborepo_ui::{sender::UISender, ColorConfig, ColorSelector}; +use turborepo_ui::{sender::UISender, ColorSelector}; use wax::Program; use crate::{ @@ -55,16 +56,13 @@ pub struct Visitor<'a> { global_env_mode: EnvMode, grouping_layer: Arc, manager: ProcessManager, + repo: &'a RepoContext, run_opts: &'a RunOpts, - package_graph: Arc, - repo_root: &'a AbsoluteSystemPath, run_cache: Arc, run_tracker: RunTracker, task_access: &'a TaskAccess, task_hasher: TaskHasher<'a>, - scm: &'a SCM, repo_index: Option<&'a RepoGitIndex>, - color_config: ColorConfig, is_watch: bool, ui_sender: Option, warnings: Arc>>, @@ -205,7 +203,7 @@ impl<'a> Visitor<'a> { // together #[allow(clippy::too_many_arguments)] pub async fn new( - package_graph: Arc, + repo: &'a RepoContext, run_cache: Arc, run_tracker: RunTracker, task_access: &'a TaskAccess, @@ -213,10 +211,7 @@ impl<'a> Visitor<'a> { package_inputs_hashes: PackageInputsHashes, env_at_execution_start: &'a EnvironmentVariableMap, global_hash: &'a str, - color_config: ColorConfig, manager: ProcessManager, - repo_root: &'a AbsoluteSystemPath, - scm: &'a SCM, repo_index: Option<&'a RepoGitIndex>, global_env: EnvironmentVariableMap, global_env_patterns: &'a [String], @@ -232,7 +227,7 @@ impl<'a> Visitor<'a> { run_opts, env_at_execution_start, global_hash, - repo_root, + &repo.repo_root, global_env, global_env_patterns, ); @@ -243,7 +238,7 @@ impl<'a> Visitor<'a> { match external_deps_hashes { Some(cache) => task_hasher.set_external_deps_hash_cache(cache), None => turborepo_rayon_compat::block_in_place(|| { - task_hasher.precompute_external_deps_hashes(&package_graph) + task_hasher.precompute_external_deps_hashes(&repo.pkg_dep_graph) })?, } @@ -277,16 +272,13 @@ impl<'a> Visitor<'a> { global_env_mode: run_opts.env_mode, grouping_layer, manager, + repo, run_opts, - package_graph, - repo_root, run_cache, run_tracker, task_access, task_hasher, - scm, repo_index, - color_config, ui_sender, is_watch, warnings: Default::default(), @@ -306,7 +298,8 @@ impl<'a> Visitor<'a> { ) -> Result { let package_name = PackageName::from(task_id.package()); let package_context = self - .package_graph + .repo + .pkg_dep_graph .package_task_context(&package_name) .ok_or_else(|| Error::MissingPackage { package_name: package_name.clone(), @@ -374,7 +367,10 @@ impl<'a> Visitor<'a> { for producer_task_id in selected_tasks { selected_any = true; let producer_package = PackageName::from(producer_task_id.package()); - let Some(producer_context) = self.package_graph.package_task_context(&producer_package) + let Some(producer_context) = self + .repo + .pkg_dep_graph + .package_task_context(&producer_package) else { return Err(Error::MissingPackage { package_name: producer_package, @@ -402,8 +398,8 @@ impl<'a> Visitor<'a> { let output_hashes = if dependency_outputs.globs.is_empty() { turborepo_task_hash::file_hashes_for_inputs( - self.scm, - self.repo_root, + &self.repo.scm, + &self.repo.repo_root, producer_directory, &declared_output_globs, false, @@ -413,8 +409,8 @@ impl<'a> Visitor<'a> { )? } else { let requested_hashes = turborepo_task_hash::file_hashes_for_inputs( - self.scm, - self.repo_root, + &self.repo.scm, + &self.repo.repo_root, producer_directory, &dependency_outputs.globs, false, @@ -427,12 +423,15 @@ impl<'a> Visitor<'a> { for (path, hash) in output_hashes.0.iter() { let full_output_path = self + .repo .repo_root .resolve(producer_directory) .join_unix_path(path); - let repo_relative_path = - AnchoredSystemPathBuf::relative_path_between(self.repo_root, &full_output_path) - .to_unix(); + let repo_relative_path = AnchoredSystemPathBuf::relative_path_between( + &self.repo.repo_root, + &full_output_path, + ) + .to_unix(); combined.insert(repo_relative_path, *hash); } } @@ -627,7 +626,8 @@ impl<'a> Visitor<'a> { if self.dry { let package_name = PackageName::from(task_id.package()); let package_context = self - .package_graph + .repo + .pkg_dep_graph .package_task_context(&package_name) .ok_or_else(|| Error::MissingPackage { package_name, @@ -719,7 +719,7 @@ impl<'a> Visitor<'a> { let crate::engine::Message { info, callback } = message; let package_name = PackageName::from(info.package()); - let Some(package_context) = self.package_graph.package_task_context(&package_name) + let Some(package_context) = self.repo.pkg_dep_graph.package_task_context(&package_name) else { dispatch_error = Some(Error::MissingPackage { package_name: package_name.clone(), @@ -815,8 +815,8 @@ impl<'a> Visitor<'a> { &package_context, &dependency_set, task_hash_telemetry, - self.scm, - self.repo_root, + &self.repo.scm, + &self.repo.repo_root, // Deferred inputs are hashed after dependencies run. Read them // from disk instead of consulting the run-start repo index. None, @@ -1064,7 +1064,6 @@ impl<'a> Visitor<'a> { global_hash_inputs, engine, env_at_execution_start, - scm, ))] #[allow(clippy::too_many_arguments)] pub(crate) async fn finish( @@ -1074,19 +1073,17 @@ impl<'a> Visitor<'a> { global_hash_inputs: GlobalHashableInputs<'_>, engine: &Engine, env_at_execution_start: &EnvironmentVariableMap, - scm: &SCM, pkg_inference_root: Option<&AnchoredSystemPath>, ) -> Result<(), Error> { let Self { - package_graph, - color_config: ui, + repo, run_opts, - repo_root, global_env_mode, task_hasher, is_watch, .. } = self; + let ui = repo.color_config; let global_hash_summary = GlobalHashSummary::try_from(global_hash_inputs)?; @@ -1099,13 +1096,13 @@ impl<'a> Visitor<'a> { ) .emit(); - PlatformEnv::output_header(global_env_mode == EnvMode::Strict, self.color_config); + PlatformEnv::output_header(global_env_mode == EnvMode::Strict, ui); for warning in warnings.iter() { PlatformEnv::output_for_task( warning.missing_platform_env().to_owned(), warning.task_id(), - self.color_config, + ui, ) } } @@ -1115,9 +1112,9 @@ impl<'a> Visitor<'a> { .run_tracker .finish( exit_code, - &package_graph, + &repo.pkg_dep_graph, ui, - repo_root, + &repo.repo_root, pkg_inference_root, run_opts, packages, @@ -1126,7 +1123,7 @@ impl<'a> Visitor<'a> { engine, &task_hasher.task_hash_tracker(), env_at_execution_start, - scm, + &repo.scm, is_watch, Some(task_hasher.external_deps_hash_cache()), )