Skip to content
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

Support for resolving package config and pubspec.lock in workspaces #3684

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

sigurdm
Copy link
Contributor

@sigurdm sigurdm commented May 13, 2024

Instead of expecting pubspec.lock and .dart_tool/package_config.json to reside in the same folder as pubspec.yaml, we visit each parent of the current directory until we find a .dart_tool/package_config.json, and expect pubspec.lock to exist next to that.

Also invoke the generated scripts with an explicit packageConfig.

This is to support running build_runner build in a workspace package, as implemented in dart-lang/pub#4127

@sigurdm
Copy link
Contributor Author

sigurdm commented May 13, 2024

The CI failures seem unrelated.

@sigurdm sigurdm requested a review from jakemac53 May 13, 2024 10:07
@@ -78,14 +78,31 @@ class PackageGraph {
'pubspec.yaml.');
}

final packageConfig =
await findPackageConfig(Directory(packagePath), recurse: false);
// The path of the directory that contains .dart_tool/package_config.json.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different from just passing recurse: true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only difference is that we can use the discovered path rootDir where we find the package config below.

With recurse: true that would not be the case - we would only be given the packageConfig itself...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we could just set the root dir as the parent of the package config dir though. Not a big difference either way but I would slightly prefer it that way.

On a related note though - I am not sure we actually want to load the pubspec from the workspace root instead of the package root? We will end up seeing all the deps used by any package in the workspace then, instead of just the deps of the current package. Unless the current package doesn't list its deps at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With workspaces there is only a single pubspec.lock.

I'm not sure how build runner uses this dependency graph - we might need to prune it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only way I can see to do that would be to parse pubspec.yaml of the current package and all its dependencies transitively.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a new problem? Did we know the ordering before?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I hadn't seen your other comments when I did my last response :).

But in any case:

I'm not sure how build runner uses this dependency graph - we might need to prune it?

Some builders will generate code for all packages in the whole dependency graph, so we could do extra work here if we see deps that are never used.

The only way I can see to do that would be to parse pubspec.yaml of the current package and all its dependencies transitively.

Right, this is what we do today, we parse all transitive pubspec.yaml files. We want to know the entire dependency structure including cycles, as it influences the order in which we build things.

Problem is, that with findPackageConfig we don't get a package config dir. Only the package config object (that doesn't expose it's location if I understand right).

Oh, ok then this code makes sense. Is there a different API that just gives us the location?

Is this a new problem? Did we know the ordering before?

Answered above, we crawl transitive pubspecs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answered above, we crawl transitive pubspecs.

Ah - then there should be no problem if we just start from the pubspec in packagePath (which we still do with this change) the workspace-wide package config and lockfile will just contain a superset of the needed packages.

Is there a different API that just gives us the location?

I don't think so. That's why I wrote it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, if we are still reading the actual package pubspec and not a root one, this is probably all fine. As long as we handle the case where there are more packages in the package config than we can find in the pubspecs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read this code right: https://github.com/dart-lang/build/blob/db5180c903b27fd1c3d344c5b22c396540ea0c78/build_runner_core/lib/src/package_graph/package_graph.dart#L133-L144

The package graph will contain all packages in the workspace-wide resolution, but will have the correct root. And if I'm not wrong, only the reachable packages are handled according to:

final orderedPackages = stronglyConnectedComponents<PackageNode>(

@sigurdm
Copy link
Contributor Author

sigurdm commented May 17, 2024

I added a test of the package graph creation.

And support for .packages.

@sigurdm
Copy link
Contributor Author

sigurdm commented May 17, 2024

Not sure what goes wrong in the community test. I am not able to reproduce the failures locally.

@jakemac53
Copy link
Contributor

Not sure what goes wrong in the community test. I am not able to reproduce the failures locally.

I can look into that, but probably not until next week. Or possibly @simolus3 would have some idea, but it seems like the code just isn't getting generated for some reason.

@simolus3
Copy link
Contributor

The failure looks surprising to me as well. I commit generated code into the repository and the build integrity test shows that re-running build_runner does not alter the state of the checkout. So the generated code should be there.

My best guess is that we hit a race condition where the build integrity test started running (and thus deleting previous generated sources) while the other tests were being loaded, thus causing these errors? I have disabled concurrency for the community tests in the drift repository, I hope that resolves the problem.

@jakemac53
Copy link
Contributor

I have disabled concurrency for the community tests in the drift repository, I hope that resolves the problem.

I restarted the job and it passed 👍

@sigurdm sigurdm requested a review from jakemac53 May 21, 2024 09:40
@sigurdm
Copy link
Contributor Author

sigurdm commented May 23, 2024

Anything more blocking this?

@jonasfj
Copy link
Member

jonasfj commented May 27, 2024

This is really another good case for adding the dependency types and relationships in package_config.json. That would much parsing all pubspec.yaml files unnecessary in this case.

@sigurdm
Copy link
Contributor Author

sigurdm commented May 28, 2024

This is really another good case for adding the dependency types and relationships in package_config.json. That would much parsing all pubspec.yaml files unnecessary in this case.

Yeah - lets do that another time!

dart-lang/pub#3795

@sigurdm
Copy link
Contributor Author

sigurdm commented May 31, 2024

Gentle ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants