From 3eb586683a0962ebba6005ad88e6e056ecbd3dac Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 17 Dec 2025 21:01:53 +0800 Subject: [PATCH] refactor: remove lifetime and cwd from WorkspaceRoot --- crates/vite_task/src/config/workspace.rs | 18 +++---- crates/vite_task_graph/src/lib.rs | 2 +- crates/vite_task_graph/tests/snapshots.rs | 4 +- crates/vite_workspace/src/lib.rs | 12 ++--- crates/vite_workspace/src/package_manager.rs | 52 +++++++++++--------- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/crates/vite_task/src/config/workspace.rs b/crates/vite_task/src/config/workspace.rs index 6e536a8c..a14b1ddf 100644 --- a/crates/vite_task/src/config/workspace.rs +++ b/crates/vite_task/src/config/workspace.rs @@ -52,8 +52,8 @@ impl Workspace { /// Returns (workspace root, cwd relative to workspace root, current package root relative to workspace root). fn determine_current_package_path( original_cwd: &AbsolutePath, - ) -> Result<(&AbsolutePath, RelativePathBuf, Option), Error> { - let WorkspaceRoot { path: workspace_root, cwd, .. } = find_workspace_root(original_cwd)?; + ) -> Result<(Arc, RelativePathBuf, Option), Error> { + let (WorkspaceRoot { path: workspace_root, .. }, cwd) = find_workspace_root(original_cwd)?; // current package root is None if it can't be found let Ok(package_root) = find_package_root(original_cwd) else { return Ok((workspace_root, cwd, None)); @@ -61,7 +61,7 @@ impl Workspace { let current_package_root = package_root.path; // Get relative path from workspace root to package root - let current_package_root = current_package_root.strip_prefix(workspace_root)?; + let current_package_root = current_package_root.strip_prefix(&*workspace_root)?; Ok((workspace_root, cwd, current_package_root)) } @@ -84,7 +84,7 @@ impl Workspace { pub fn get_cache_path(cwd: &AbsolutePath) -> Result { let (workspace_root, _, _) = Self::determine_current_package_path(cwd)?; - Ok(Self::get_cache_path_of_workspace(workspace_root)) + Ok(Self::get_cache_path_of_workspace(&workspace_root)) } pub fn partial_load_with_cache_path( @@ -96,7 +96,7 @@ impl Workspace { Self::determine_current_package_path(&cwd)?; let cache_path = - cache_path.unwrap_or_else(|| Self::get_cache_path_of_workspace(workspace_root)); + cache_path.unwrap_or_else(|| Self::get_cache_path_of_workspace(&workspace_root)); if !cache_path.as_path().exists() && let Some(cache_dir) = cache_path.as_path().parent() @@ -136,9 +136,9 @@ impl Workspace { let (workspace_root, cwd, current_package_path) = Self::determine_current_package_path(&cwd)?; - let package_graph = vite_workspace::discover_package_graph(workspace_root)?; + let package_graph = vite_workspace::discover_package_graph(&*workspace_root)?; // Load vite-task.json files for all packages - let packages_with_task_jsons = Self::load_vite_task_jsons(&package_graph, workspace_root)?; + let packages_with_task_jsons = Self::load_vite_task_jsons(&package_graph, &workspace_root)?; // Find root package.json let mut package_json = None; @@ -151,7 +151,7 @@ impl Workspace { } let cache_path = - cache_path.unwrap_or_else(|| Self::get_cache_path_of_workspace(workspace_root)); + cache_path.unwrap_or_else(|| Self::get_cache_path_of_workspace(&workspace_root)); if !cache_path.as_path().exists() && let Some(cache_dir) = cache_path.as_path().parent() @@ -181,7 +181,7 @@ impl Workspace { &package_graph, &package_path_to_node, &mut task_graph_builder, - workspace_root, + &workspace_root, )?; // Add topological dependencies if enabled diff --git a/crates/vite_task_graph/src/lib.rs b/crates/vite_task_graph/src/lib.rs index a258dd9b..a159cd3f 100644 --- a/crates/vite_task_graph/src/lib.rs +++ b/crates/vite_task_graph/src/lib.rs @@ -175,7 +175,7 @@ pub type TaskGraph = DiGraph; impl IndexedTaskGraph { /// Load the task graph from a discovered workspace using the provided config loader. pub async fn load( - workspace_root: WorkspaceRoot<'_>, + workspace_root: WorkspaceRoot, config_loader: impl loader::UserConfigLoader, ) -> Result { let mut task_graph = DiGraph::::default(); diff --git a/crates/vite_task_graph/tests/snapshots.rs b/crates/vite_task_graph/tests/snapshots.rs index 36d2be71..6f29798f 100644 --- a/crates/vite_task_graph/tests/snapshots.rs +++ b/crates/vite_task_graph/tests/snapshots.rs @@ -164,10 +164,10 @@ fn run_case(runtime: &Runtime, tmpdir: &AbsolutePath, case_path: &Path) { let case_stage_path = tmpdir.join(case_name); copy_dir(case_path, &case_stage_path).unwrap(); - let workspace_root = find_workspace_root(&case_stage_path).unwrap(); + let (workspace_root, _cwd) = find_workspace_root(&case_stage_path).unwrap(); assert_eq!( - &case_stage_path, workspace_root.path, + &case_stage_path, &*workspace_root.path, "folder '{}' should be a workspace root", case_name ); diff --git a/crates/vite_workspace/src/lib.rs b/crates/vite_workspace/src/lib.rs index ecccb377..23c3cb1e 100644 --- a/crates/vite_workspace/src/lib.rs +++ b/crates/vite_workspace/src/lib.rs @@ -192,13 +192,13 @@ pub type PackageEdgeIndex = EdgeIndex; pub fn discover_package_graph( cwd: impl AsRef, ) -> Result, Error> { - let workspace_root = find_workspace_root(cwd.as_ref())?; + let (workspace_root, _cwd) = find_workspace_root(cwd.as_ref())?; load_package_graph(&workspace_root) } /// Load the package graph from a discovered workspace. pub fn load_package_graph( - workspace_root: &WorkspaceRoot<'_>, + workspace_root: &WorkspaceRoot, ) -> Result, Error> { let mut graph_builder = PackageGraphBuilder::default(); let workspaces = match &workspace_root.workspace_file { @@ -215,7 +215,7 @@ pub fn load_package_graph( let package_json: PackageJson = serde_json::from_reader(file)?; graph_builder.add_package( RelativePathBuf::default(), - workspace_root.path.into(), + Arc::clone(&workspace_root.path), package_json, ); @@ -225,10 +225,10 @@ pub fn load_package_graph( let member_globs = WorkspaceMemberGlobs::new(workspaces); let mut has_root_package = false; - for package_json_path in member_globs.get_package_json_paths(workspace_root.path)? { + for package_json_path in member_globs.get_package_json_paths(&*workspace_root.path)? { let package_json: PackageJson = serde_json::from_slice(&fs::read(&package_json_path)?)?; let absolute_path = package_json_path.parent().unwrap(); - let Some(package_path) = absolute_path.strip_prefix(workspace_root.path)? else { + let Some(package_path) = absolute_path.strip_prefix(&*workspace_root.path)? else { return Err(Error::PackageOutsideWorkspace { package_path: package_json_path, workspace_root: workspace_root.path.to_absolute_path_buf(), @@ -246,7 +246,7 @@ pub fn load_package_graph( let package_json: PackageJson = serde_json::from_slice(&package_json)?; graph_builder.add_package( RelativePathBuf::default(), - workspace_root.path.into(), + Arc::clone(&workspace_root.path), package_json, ); } diff --git a/crates/vite_workspace/src/package_manager.rs b/crates/vite_workspace/src/package_manager.rs index aba5dbb9..a564ab56 100644 --- a/crates/vite_workspace/src/package_manager.rs +++ b/crates/vite_workspace/src/package_manager.rs @@ -2,6 +2,7 @@ use std::{ fs::File, io::{BufReader, Seek, SeekFrom}, path::Path, + sync::Arc, }; use vite_path::{AbsolutePath, RelativePathBuf}; @@ -60,33 +61,37 @@ pub enum WorkspaceFile { /// /// If the workspace file is not found, but a package is found, `workspace_file` will be `NonWorkspacePackage` with the `package.json` File. #[derive(Debug)] -pub struct WorkspaceRoot<'a> { +pub struct WorkspaceRoot { /// The absolute path of the workspace root directory. - pub path: &'a AbsolutePath, - /// The cwd that the workspace was found from, relative to the workspace root. - pub cwd: RelativePathBuf, + pub path: Arc, /// The workspace file. pub workspace_file: WorkspaceFile, } /// Find the workspace root directory from the current working directory. `original_cwd` must be absolute. /// +/// Returns the workspace root and the relative path from the workspace root to the original cwd. +/// /// If the workspace file is not found, but a package is found, `workspace_file` will be `NonWorkspacePackage` with the `package.json` File. /// /// If neither workspace nor package is found, will return `PackageJsonNotFound` error. -pub fn find_workspace_root(original_cwd: &AbsolutePath) -> Result, Error> { +pub fn find_workspace_root( + original_cwd: &AbsolutePath, +) -> Result<(WorkspaceRoot, RelativePathBuf), Error> { let mut cwd = original_cwd; loop { // Check for pnpm-workspace.yaml for pnpm workspace if let Some(file) = open_exists_file(cwd.join("pnpm-workspace.yaml"))? { - return Ok(WorkspaceRoot { - path: cwd, - cwd: original_cwd - .strip_prefix(cwd)? - .expect("cwd must be within the pnpm workspace"), - workspace_file: WorkspaceFile::PnpmWorkspaceYaml(file), - }); + let relative_cwd = + original_cwd.strip_prefix(cwd)?.expect("cwd must be within the pnpm workspace"); + return Ok(( + WorkspaceRoot { + path: Arc::from(cwd), + workspace_file: WorkspaceFile::PnpmWorkspaceYaml(file), + }, + relative_cwd, + )); } // Check for package.json with workspaces field for npm/yarn workspace @@ -96,11 +101,15 @@ pub fn find_workspace_root(original_cwd: &AbsolutePath) -> Result Result