Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions crates/vite_task/src/config/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ 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<RelativePathBuf>), Error> {
let WorkspaceRoot { path: workspace_root, cwd, .. } = find_workspace_root(original_cwd)?;
) -> Result<(Arc<AbsolutePath>, RelativePathBuf, Option<RelativePathBuf>), 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));
};
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))
}

Expand All @@ -84,7 +84,7 @@ impl Workspace {

pub fn get_cache_path(cwd: &AbsolutePath) -> Result<AbsolutePathBuf, Error> {
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(
Expand All @@ -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()
Expand Down Expand Up @@ -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;
Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_task_graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub type TaskGraph = DiGraph<TaskNode, TaskDependencyType, TaskIx>;
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<Self, TaskGraphLoadError> {
let mut task_graph = DiGraph::<TaskNode, TaskDependencyType, TaskIx>::default();
Expand Down
4 changes: 2 additions & 2 deletions crates/vite_task_graph/tests/snapshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand Down
12 changes: 6 additions & 6 deletions crates/vite_workspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,13 @@ pub type PackageEdgeIndex = EdgeIndex<DefaultIx>;
pub fn discover_package_graph(
cwd: impl AsRef<AbsolutePath>,
) -> Result<DiGraph<PackageInfo, DependencyType, PackageIx>, 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<DiGraph<PackageInfo, DependencyType, PackageIx>, Error> {
let mut graph_builder = PackageGraphBuilder::default();
let workspaces = match &workspace_root.workspace_file {
Expand All @@ -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,
);

Expand All @@ -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(),
Expand All @@ -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,
);
}
Expand Down
52 changes: 30 additions & 22 deletions crates/vite_workspace/src/package_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{
fs::File,
io::{BufReader, Seek, SeekFrom},
path::Path,
sync::Arc,
};

use vite_path::{AbsolutePath, RelativePathBuf};
Expand Down Expand Up @@ -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<AbsolutePath>,
/// 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<WorkspaceRoot<'_>, 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
Expand All @@ -96,11 +101,15 @@ pub fn find_workspace_root(original_cwd: &AbsolutePath) -> Result<WorkspaceRoot<
if package_json.get("workspaces").is_some() {
// Reset the file cursor since we consumed it reading
file.seek(SeekFrom::Start(0))?;
return Ok(WorkspaceRoot {
path: cwd,
cwd: original_cwd.strip_prefix(cwd)?.expect("cwd must be within the workspace"),
workspace_file: WorkspaceFile::NpmWorkspaceJson(file),
});
let relative_cwd =
original_cwd.strip_prefix(cwd)?.expect("cwd must be within the workspace");
return Ok((
WorkspaceRoot {
path: Arc::from(cwd),
workspace_file: WorkspaceFile::NpmWorkspaceJson(file),
},
relative_cwd,
));
}
}

Expand All @@ -113,11 +122,10 @@ pub fn find_workspace_root(original_cwd: &AbsolutePath) -> Result<WorkspaceRoot<
// We've reached the root, try to find the package root and return the non-workspace package.
let package_root = find_package_root(original_cwd)?;
let workspace_file = WorkspaceFile::NonWorkspacePackage(package_root.package_json);
return Ok(WorkspaceRoot {
path: package_root.path,
cwd: package_root.cwd,
workspace_file,
});
return Ok((
WorkspaceRoot { path: Arc::from(package_root.path), workspace_file },
package_root.cwd,
));
}
}
}
Expand Down