@@ -7,7 +7,9 @@ use std::{
77
88use chrono:: Local ;
99use tracing:: Instrument ;
10- use turbopath:: { AbsoluteSystemPath , AbsoluteSystemPathBuf , RelativeUnixPathBuf } ;
10+ use turbopath:: {
11+ AbsoluteSystemPath , AbsoluteSystemPathBuf , AnchoredSystemPath , RelativeUnixPathBuf ,
12+ } ;
1113use turborepo_analytics:: { start_analytics, AnalyticsHandle } ;
1214use turborepo_api_client:: { APIAuth , APIClient , CacheClient , SharedHttpClient } ;
1315use turborepo_cache:: { AsyncCache , CacheScmState , LazyScmState } ;
@@ -284,21 +286,39 @@ impl RunBuilder {
284286 }
285287 }
286288
287- fn all_package_prefixes ( pkg_dep_graph : & PackageGraph ) -> Vec < RelativeUnixPathBuf > {
289+ fn package_prefix_for_repo_index (
290+ repo_root : & AbsoluteSystemPath ,
291+ index_root : & AbsoluteSystemPath ,
292+ package_dir : & AnchoredSystemPath ,
293+ ) -> Result < RelativeUnixPathBuf , Error > {
294+ let full_package_dir = repo_root. resolve ( package_dir) ;
295+ Ok ( index_root. anchor ( & full_package_dir) ?. to_unix ( ) )
296+ }
297+
298+ fn all_package_prefixes (
299+ pkg_dep_graph : & PackageGraph ,
300+ scm : & SCM ,
301+ ) -> Result < Vec < RelativeUnixPathBuf > , Error > {
302+ let repo_root = pkg_dep_graph. repo_root ( ) ;
303+ let index_root = scm. git_root ( ) . unwrap_or ( repo_root) ;
288304 let mut prefixes = pkg_dep_graph
289305 . packages ( )
290306 . filter_map ( |( name, _) | pkg_dep_graph. package_dir ( name) )
291- . map ( |package_dir| package_dir. to_unix ( ) )
292- . collect :: < Vec < _ > > ( ) ;
307+ . map ( |package_dir| {
308+ Self :: package_prefix_for_repo_index ( repo_root, index_root, package_dir)
309+ } )
310+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
293311
294- prefixes. extend (
295- pkg_dep_graph
296- . root_internal_package_dependencies_paths ( )
297- . into_iter ( )
298- . map ( |package_dir| package_dir. to_unix ( ) ) ,
299- ) ;
312+ let root_dependency_prefixes = pkg_dep_graph
313+ . root_internal_package_dependencies_paths ( )
314+ . into_iter ( )
315+ . map ( |package_dir| {
316+ Self :: package_prefix_for_repo_index ( repo_root, index_root, package_dir)
317+ } )
318+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
319+ prefixes. extend ( root_dependency_prefixes) ;
300320
301- prefixes
321+ Ok ( prefixes)
302322 }
303323
304324 /// Resolve the set of packages that should participate in this run.
@@ -493,11 +513,11 @@ impl RunBuilder {
493513 // parallel walk for untracked file discovery. This replaces the
494514 // subprocess approach (ls-tree + diff-index + ls-files race) which
495515 // burned ~500ms of CPU on background threads.
496- let all_prefixes = Self :: all_package_prefixes ( & pkg_dep_graph) ;
497516 let scm = scm_task
498517 . instrument ( tracing:: info_span!( "scm_task_await" ) )
499518 . await
500519 . expect ( "detecting scm panicked" ) ;
520+ let all_prefixes = Self :: all_package_prefixes ( & pkg_dep_graph, & scm) ?;
501521 let repo_index_task = if all_prefixes. is_empty ( ) {
502522 None
503523 } else {
@@ -1052,6 +1072,51 @@ fn hosts_match(url1: &str, url2: &str) -> bool {
10521072 }
10531073}
10541074
1075+ #[ cfg( test) ]
1076+ mod package_prefix_tests {
1077+ use super :: * ;
1078+
1079+ #[ test]
1080+ fn repo_index_prefixes_are_git_root_relative_for_nested_turbo_root ( ) {
1081+ let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
1082+ let git_root = AbsoluteSystemPathBuf :: try_from ( tmp. path ( ) ) . unwrap ( ) ;
1083+ let repo_root = git_root. join_component ( "downloaded-app" ) ;
1084+
1085+ let root_package = AnchoredSystemPath :: new ( "" ) . unwrap ( ) ;
1086+ let workspace_package = AnchoredSystemPath :: new ( "packages/web" ) . unwrap ( ) ;
1087+
1088+ assert_eq ! (
1089+ RunBuilder :: package_prefix_for_repo_index( & repo_root, & git_root, root_package) . unwrap( ) ,
1090+ RelativeUnixPathBuf :: new( "downloaded-app" ) . unwrap( )
1091+ ) ;
1092+ assert_eq ! (
1093+ RunBuilder :: package_prefix_for_repo_index( & repo_root, & git_root, workspace_package)
1094+ . unwrap( ) ,
1095+ RelativeUnixPathBuf :: new( "downloaded-app/packages/web" ) . unwrap( )
1096+ ) ;
1097+ }
1098+
1099+ #[ test]
1100+ fn repo_index_prefixes_stay_repo_relative_when_git_root_matches_turbo_root ( ) {
1101+ let tmp = tempfile:: tempdir ( ) . unwrap ( ) ;
1102+ let repo_root = AbsoluteSystemPathBuf :: try_from ( tmp. path ( ) ) . unwrap ( ) ;
1103+
1104+ let root_package = AnchoredSystemPath :: new ( "" ) . unwrap ( ) ;
1105+ let workspace_package = AnchoredSystemPath :: new ( "packages/web" ) . unwrap ( ) ;
1106+
1107+ assert_eq ! (
1108+ RunBuilder :: package_prefix_for_repo_index( & repo_root, & repo_root, root_package)
1109+ . unwrap( ) ,
1110+ RelativeUnixPathBuf :: new( "" ) . unwrap( )
1111+ ) ;
1112+ assert_eq ! (
1113+ RunBuilder :: package_prefix_for_repo_index( & repo_root, & repo_root, workspace_package)
1114+ . unwrap( ) ,
1115+ RelativeUnixPathBuf :: new( "packages/web" ) . unwrap( )
1116+ ) ;
1117+ }
1118+ }
1119+
10551120#[ cfg( test) ]
10561121mod hosts_match_tests {
10571122 use super :: * ;
0 commit comments