-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat: add Workspace.find_package_by_path
#10493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b59c39c
f9cc110
d27e11b
b27a346
dd02af4
28d033d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ use turbopath::{AbsoluteSystemPath, AnchoredSystemPath, AnchoredSystemPathBuf}; | |
| use turborepo_repository::{ | ||
| change_mapper::{ | ||
| ChangeMapper, DefaultPackageChangeMapper, DefaultPackageChangeMapperWithLockfile, | ||
| LockfileContents, PackageChanges, | ||
| LockfileContents, PackageChangeMapper, PackageChanges, | ||
| }, | ||
| inference::RepoState as WorkspaceState, | ||
| package_graph::{PackageGraph, PackageName, PackageNode, WorkspacePackage, ROOT_PKG_NAME}, | ||
|
|
@@ -291,4 +291,39 @@ impl Workspace { | |
|
|
||
| Ok(serializable_packages) | ||
| } | ||
|
|
||
| /// Given a path (relative to the workspace root), returns the | ||
| /// package that contains it. | ||
| /// | ||
| /// This is a naive implementation that simply "iterates-up". If this | ||
| /// function is expected to be called many times for files that are deep | ||
| /// within the same package, we could optimize this by caching the | ||
| /// containing-package of every ancestor. | ||
| #[napi] | ||
| pub async fn find_package_by_path(&self, path: String) -> Result<Package, Error> { | ||
| let package_mapper = DefaultPackageChangeMapper::new(&self.graph); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is something that I should've given you a code pointer on. This is the structure we use to determine which files affect which packages. We can use it raw here to do the same purpose of mapping files to packages. Happy to chat a bit more about this! |
||
| let anchored_path = AnchoredSystemPath::new(&path) | ||
| .map_err(|e| Error::from_reason(e.to_string()))? | ||
| .clean(); | ||
| match package_mapper.detect_package(&anchored_path) { | ||
| turborepo_repository::change_mapper::PackageMapping::All( | ||
| _all_package_change_reason, | ||
| ) => Err(Error::from_reason("file belongs to many packages")), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative here would be to possibly return the root package or return that the file change is considered "global". |
||
| turborepo_repository::change_mapper::PackageMapping::None => Err(Error::from_reason( | ||
| "iterated to the root of the workspace and found no package", | ||
| )), | ||
| turborepo_repository::change_mapper::PackageMapping::Package((package, _reason)) => { | ||
| let workspace_root = match AbsoluteSystemPath::new(&self.absolute_path) { | ||
| Ok(path) => path, | ||
| Err(e) => return Err(Error::from_reason(e.to_string())), | ||
| }; | ||
| let package_path = workspace_root.resolve(&package.path); | ||
| Ok(Package::new( | ||
| package.name.to_string(), | ||
| workspace_root, | ||
| &package_path, | ||
| )) | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have some tests for root files e.g. a root
tsconfig.json,pnpm-lock.yaml,pnpm-workspace.yaml