-
Notifications
You must be signed in to change notification settings - Fork 213
Language Versioning: .packages file breaking changes? #365
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
Comments
One solution would be to use Dart 3.0.0 as the first version that ships with the NNBD experiment on by default, yes? |
If that also means that the It would be my preference that we don't break the .packages format until Dart 3.x, as I don't think anything else can be fully correct and it will be really difficult (but not impossible) to do something close enough to correct that ~nobody notices. |
I would also like to note that the current migration section doesn't call this out specifically, and it actually currently states that "The chosen design allows existing Pub packages to keep running without modification. ", which won't be true for any package that reads or produces .packages files. |
I don't think this is as dire as it seems. The ".packages" file is not really part of what constitutes a "Pub package", isn't uploaded to pub.dartlang.org, and generally isn't shared across machines. What this means is that any given .packages file is usually only consumed by tools that are part of the same SDK or a previous version of it. So once some Dart tool has produced a ".packages" file with the new syntax, it will typically only end up consumed by tools that can also handle it. Except for the case you note which is external packages like build which also parse (and produce) ".packages" files. So there is a real breakage, but it's not all tools that will break. To mitigate that pain, there are a couple of things I think we could do:
I do think we should consider changing ".packages" to a more extensible format so that we don't run into this exact same problem again the next time we want to pass some package metadata to all the tools. When ".packages" was first designed, I suggested the syntax be a Dart map literal. We already have high performance parsers for that, it's extensible, and supports comments (unlike JSON). I'm not picky, though. It would just be good to not run into this problem again. |
If we are going to do a breaking change anyways, we might as well completely change the format at the same time. Now or never :D |
I also did some searching around internally and fwiw most of the cases I found were tests, which were creating .packages files. If the old format is still valid, then these won't be affected (although I don't know what the behavior will end up being, they may get broken if they end up opting into NNBD by accident for instance). |
The old format is still valid. It just means that every package uses the languge version of the current SDK, and that code outside of a package will not have a default package, and will therefore also default to the language version of the current SDK. The new format is backwards compatible as long as the parser does not make too many assumptions. If a tool assumes that all entries point to valid directories, then it will fail. If you only do package name lookup and package URI resolution, then the new file is backwards compatible. |
That is quite broken though right? If tools that auto-generate .packages files by default still "work" but are actually stripping out the language version information for those packages, they will very likely be broken, because they are being silently upgraded to the current sdk version? Should the new SDK maybe even reject these .packages files entirely? Or consider an omitted version to be defaulted to some old sdk prior to the version identifier being added?
At least some do make assumptions about it being a valid path, scissors for instance. Also, note that
That gives the following exception:
|
@munificent do we have a concrete decision here? It looks like the pub team is already planning on implementing this which will start breaking people if we don't put together a plan dart-lang/pub#2154. |
There is something to say for supporting a richer If we ever dream of supporting things like: package aliasing, multiple versions of the same package, or explicit assets. |
@lrhn is the person to ask, I think, since he's driving the feature. |
@aadilmaan, it would be good to get the tools that consume the |
@lrhn , any decision on supporting a richer |
No current plan to change the format. The I'm open to using a more capable format, but I don't want to rush it, so it would be nice to know which actual features it must support. (I'd personally prefer JSON over YAML, if only JSON had comments.) |
As a heads up, the VS Code extension parses this file to convert package URIs to file paths (all interaction with VS Code uses file paths, it doesn't know what package URIs are). I think the other editors are probably doing it too (and that may include other community integrations for other editors). The changes above probably break my parsing (it's naive and was made up by just looking at the contents, as I couldn't find a spec). I'd prefer to not parse this file in the editor and had started to move away from using it, but I think we may need to go back. If the changes above will/have gone ahead, is there an official spec of the format so I can update it and ensure it covers all required cases correctly? (the link in Jake's very first comment here is a 404, so I couldn't find any more info there). Edit: Here's how Dart-Code is currently parsing it (much like Jake's notes above - skip lines that start with |
FWIW, VS Code uses JSON for its config, and they just allow comments. They have support for a language "JSON with comments" in the editor too. I don't think it's much different to having a completely custom format - it just happens to be the same as JSON with comments (I'm sure if more people started doing this, the common parsers would get settings to handle it - and if not, stripping comments and then using an existing JSON parser probably isn't too complicated versus parsing a completely custom format). |
fwiw I updated my link just now - looks like the file was renamed |
The official specification for the current The language versioning changes to the format are sketched in https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/feature-specification.md.
This is an extension of the existing syntax (mainly the one empty key being allowed, but not required), so old The recommended way to work with I'll write up a specification for the new format, and maybe even the new package resolution. |
@lrhn thanks! I'm not sure why I failed to find that document when first parsing this! One question I have is about the "default package" shown in this doc where it has Old:
New:
Previously I was looking for packages that have Edit: PR for Dart-Code at Dart-Code/Dart-Code#2001. I'll merge it once the above is confirmed. |
IntelliJ's
This is not possible for any tool not written in Dart.
There are many, critical, Dart and Flutter tools that are not developed in the SDK. Where are we on this change? I want to better evaluate the impact. We would have been in a much, much better place here if we hadn't invented our own file format. |
I've started implementing this in I may be wrong, but I assumed we extended Older versions of Creating a new file might be less disruptive. Maybe we could generate both It's not unlikely that users will jump between Dart/Flutter versions/channels using |
Right, the reason I opened this issue originally is that assumption is unfortunately not accurate. External tools ended up for the most part treating the value as a path and not a uri because that seemed like an entirely sensible thing to do. It is very unexpected for these to have fragments or query params as that gives no meaningful information about how to locate the package (which is all this file is supposed to do). While this is not breaking in terms of the original DEP in practice it is breaking for these tools. |
I agree here.
Thanks for the update. I think we need to pause the rollout, and do one of either:
cc @mit and @lrhn, @munificent @jakemac53 @jonasfj |
The example looks right.
You are trying to infer the name of a Pub package from the The technically perfect way to find the pub package of a file is to find the surrounding The
becomes
That's an equally correct way to point to the Dart package files, but would not be found if you only look for When Pub starts adding "default package" entries, it will most likely do so for all Pub packages and have the current Pub package be the default package. At that point, I think it is safe to assume that it is the name of the current Pub package. (You can manually create a |
Yeah, that's what I thought but I was trying to avoid having to parse YAML when I wrote this (I'm trying to cut down on nodejs dependencies we're shipping to end users after things like event-stream.. most npm packages don't think twice about bringing a tree of 4,000 transient dependencies). It'd be easier if pubspec was JSON 😉 We actually only use the local package name for a few minor things (eg. we show package names in hover tooltips, but wanted to skip that for the project itself, and we want to exclude the project itself from the dependencies tree). I think the hover one is solved by the analyzer now anyway, and probably I could switch the dependency one to use the path - so maybe I could just drop this entirely and avoid the complications - I'll file an issue to look at it. |
Note that this is a blocker for the NNBD release, so if we pause, we need to unpause fairly quickly, particularly given the tool lead times mentioned above. |
Yeah. :( I tried at the time. I think we may want to consider moving to a second file now that has an extensible format and eventually deprecating |
I agree that if the planned changes are actually breaking anyway, then we might as well do a new format now. |
Just an FYI, changing this format will break Observatory initially as its |
@sortie If any of the testing/benchmarking infra depends on the .packages format this will be breaking there too. |
This change will likely break the flutter tool - but this is written in Dart so we can switch to using package_config. Unfortunately the fuchsia source tree also contains multiple python programs that parse and consume .packages files. Updating these will be much more difficult. Ideally, this would be done as a soft transition - where we can continue using the old file format while we work towards supporting the new one. Is there a time frame when this new .packages format will be available? It would be great to have some time in Q4 to update our tooling in advance |
We had a discussion about this - we are now planning to have a soft transition. Overall, we'll:
|
@nshahan Thanks for thinking about us. Our benchmarking infrastructure does not rely on the format of .packages, that is, it never attempts to parse it. We do rewrite some absolute paths in there but that will continue to work. We also supply our own and that will continue to work. I asked and we also don't have any such dependencies in our regular CI. |
For discussion: should we actually stop generating the .packages file, or just keep generating it indefinitely? What's the cost of generating it, vs the cost of making the breaking change of removing it? |
I think we probably should keep it around until Dart 3.0, for two specific reasons:
Otherwise this is likely a pretty significant breaking change. |
We have a resolution to the immediate issue. When we remove support for |
Is the new JSON format fairly static now? Should I be thinking about switching Dart-Code over to it? |
@DanTup, yes, afaik it's being used by Read about it here -> https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md |
If you do change to use the new format (which you should), please use |
Dart-Code is written in TypeScript/JS (and runs in a Node VM) so this isn't straight forward. Long-term, it'd be nice to have a debug adapter written in Dart (using the DAP), but that probably won't happen in the near-term. (I suspect the same goes for IntelliJ - I think it's likely parsing this in Java?) |
@lrhn here's the implementation I added in TS for Dart-Code: It seems fairly straight-forward (the only thing we care about is the path for resolving a |
@DanTup A quick reading looks OK to me. Does the |
@lrhn Oops, good catch! If the trailing slash was included in the path, we would've ended up with Thanks! |
As a part of the language versioning proposal (around here), there are some proposed breaking changes to the
.packages
file format.The breaking changes
Specifically, I noticed two breaking changes:
#dart=<version>
comment to the end of the paths (so the paths are no longer valid)*:<package>
which denotes which package is the application package.Why it matters
All kinds of tools generate and consume
.packages
files today, from build_* packages to internal bazel rules, they are very prevalent. Tests often create them too in order to do integration tests.Many of these tools will be packages published on pub, with an upper bound sdk constraint of
<3.0.0
. So even if they are updated, we can't prevent users from getting a version that doesn't support the new format, or force a pub upgrade.The current
.packages
format is very simple, and because of that most tools I have seen do not go through any shared library to parse it either. They do some form of this pattern instead::
All of those implementations will be broken by the proposed changes, and will have to be individually updated/fixed.
Bazel specific notes
Currently today in bazel we generate
.packages
files in pure starlark code, which doesn't have access to the file system.In order to generate these new files, we would have to add an attribute or something to our dart_library rule which specifies the min version. This should be doable but it will be interesting for the NNBD migration, I don't know what the proper default should be.
The text was updated successfully, but these errors were encountered: