1
- use std:: { path :: MAIN_SEPARATOR , time:: Duration } ;
1
+ use std:: time:: Duration ;
2
2
3
3
use anyhow:: { Context , Result , bail} ;
4
4
use indexmap:: map:: Entry ;
@@ -37,8 +37,8 @@ use turbo_tasks::{
37
37
} ;
38
38
use turbo_tasks_env:: { EnvMap , ProcessEnv } ;
39
39
use turbo_tasks_fs:: {
40
- DiskFileSystem , FileSystem , FileSystemPath , VirtualFileSystem , get_relative_path_to ,
41
- invalidation ,
40
+ DiskFileSystem , FileSystem , FileSystemPath , VirtualFileSystem , invalidation ,
41
+ util :: { join_path , unix_to_sys } ,
42
42
} ;
43
43
use turbopack:: {
44
44
ModuleAssetContext , evaluate_context:: node_build_environment,
@@ -149,11 +149,13 @@ pub struct WatchOptions {
149
149
) ]
150
150
#[ serde( rename_all = "camelCase" ) ]
151
151
pub struct ProjectOptions {
152
- /// A root path from which all files must be nested under. Trying to access
153
- /// a file outside this root will fail. Think of this as a chroot.
152
+ /// An absolute root path (Unix or Windows path) from which all files must be nested under.
153
+ /// Trying to access a file outside this root will fail, so think of this as a chroot.
154
+ /// E.g. `/home/user/projects/my-repo`.
154
155
pub root_path : RcStr ,
155
156
156
- /// A path inside the root_path which contains the app/pages directories.
157
+ /// A path which contains the app/pages directories, relative to [`Project::root_path`], always
158
+ /// Unix path. E.g. `apps/my-app`
157
159
pub project_path : RcStr ,
158
160
159
161
/// The contents of next.config.js, serialized to JSON.
@@ -538,15 +540,20 @@ impl ProjectContainer {
538
540
539
541
#[ turbo_tasks:: value]
540
542
pub struct Project {
541
- /// A root path from which all files must be nested under. Trying to access
542
- /// a file outside this root will fail. Think of this as a chroot.
543
+ /// An absolute root path (Windows or Unix path) from which all files must be nested under.
544
+ /// Trying to access a file outside this root will fail, so think of this as a chroot.
545
+ /// E.g. `/home/user/projects/my-repo`.
543
546
root_path : RcStr ,
544
547
545
- /// A path where to emit the build outputs. next.config.js's distDir.
546
- dist_dir : RcStr ,
548
+ /// A path which contains the app/pages directories, relative to [`Project::root_path`], always
549
+ /// a Unix path.
550
+ /// E.g. `apps/my-app`
551
+ project_path : RcStr ,
547
552
548
- /// A path inside the root_path which contains the app/pages directories.
549
- pub project_path : RcStr ,
553
+ /// A path where to emit the build outputs, relative to [`Project::project_path`], always a
554
+ /// Unix path. Corresponds to next.config.js's `distDir`.
555
+ /// E.g. `.next`
556
+ dist_dir : RcStr ,
550
557
551
558
/// Filesystem watcher options.
552
559
watch : WatchOptions ,
@@ -685,21 +692,30 @@ impl Project {
685
692
}
686
693
687
694
#[ turbo_tasks:: function]
688
- pub fn dist_dir ( & self ) -> Vc < RcStr > {
689
- Vc :: cell ( self . dist_dir . clone ( ) )
695
+ pub fn dist_dir_absolute ( & self ) -> Result < Vc < RcStr > > {
696
+ Ok ( Vc :: cell (
697
+ format ! (
698
+ "{}{}{}" ,
699
+ self . root_path,
700
+ std:: path:: MAIN_SEPARATOR ,
701
+ unix_to_sys(
702
+ & join_path( & self . project_path, & self . dist_dir)
703
+ . context( "expected project_path to be inside of root_path" ) ?
704
+ )
705
+ )
706
+ . into ( ) ,
707
+ ) )
690
708
}
691
709
692
710
#[ turbo_tasks:: function]
693
711
pub async fn node_root ( self : Vc < Self > ) -> Result < Vc < FileSystemPath > > {
694
712
let this = self . await ?;
695
- let relative_from_root_to_project_path =
696
- get_relative_path_to ( & this. root_path , & this. project_path ) ;
697
713
Ok ( self
698
714
. output_fs ( )
699
715
. root ( )
700
716
. await ?
701
- . join ( & relative_from_root_to_project_path ) ?
702
- . join ( & this. dist_dir . clone ( ) ) ?
717
+ . join ( & this . project_path ) ?
718
+ . join ( & this. dist_dir ) ?
703
719
. cell ( ) )
704
720
}
705
721
@@ -726,28 +742,24 @@ impl Project {
726
742
. cell ( ) )
727
743
}
728
744
745
+ /// Returns the relative path from the node root to the output root.
746
+ /// E.g. from `[project]/test/e2e/app-dir/non-root-project-monorepo/apps/web/app/
747
+ /// import-meta-url-ssr/page.tsx` to `[project]/`.
729
748
#[ turbo_tasks:: function]
730
749
pub async fn node_root_to_root_path ( self : Vc < Self > ) -> Result < Vc < RcStr > > {
731
- let this = self . await ?;
732
- let output_root_to_root_path = self
733
- . project_path ( )
734
- . await ?
735
- . join ( & this. dist_dir . clone ( ) ) ?
736
- . get_relative_path_to ( & * self . project_root_path ( ) . await ?)
737
- . context ( "Project path need to be in root path" ) ?;
738
- Ok ( Vc :: cell ( output_root_to_root_path) )
750
+ Ok ( Vc :: cell (
751
+ self . node_root ( )
752
+ . await ?
753
+ . get_relative_path_to ( & * self . output_fs ( ) . root ( ) . await ?)
754
+ . context ( "Expected node root to be inside of output fs" ) ?,
755
+ ) )
739
756
}
740
757
741
758
#[ turbo_tasks:: function]
742
759
pub async fn project_path ( self : Vc < Self > ) -> Result < Vc < FileSystemPath > > {
743
760
let this = self . await ?;
744
761
let root = self . project_root_path ( ) . await ?;
745
- let project_relative = this. project_path . strip_prefix ( & * this. root_path ) . unwrap ( ) ;
746
- let project_relative = project_relative
747
- . strip_prefix ( MAIN_SEPARATOR )
748
- . unwrap_or ( project_relative)
749
- . replace ( MAIN_SEPARATOR , "/" ) ;
750
- Ok ( root. join ( & project_relative) ?. cell ( ) )
762
+ Ok ( root. join ( & this. project_path ) ?. cell ( ) )
751
763
}
752
764
753
765
#[ turbo_tasks:: function]
0 commit comments