The current spec for language versioning says that if no package_config.json file is found then libraries default to the latest language version supported by the SDK. Since the package_config.json file is itself new, we may find ourselves in this situation:
pub get yet, they have a .packages file, but not package_config.json.package_config.json file, so it treats their libraries as all being at the latest version, which is NNBD.This will be less of an issue if we ship pub support for packages_config.json before NNBD. But even then users who skip that SDK version and jump straight to the version that releases NNBD can be in this state.
Should we consider refining the proposal by saying that if there is no packages_config.json file, but there is a .packages file, then use something like 2.7 as the default language version?
@lrhn @leafpetersen @eernstg
cc @sigmundch
This does not feel like a technical problem, but more like a usability issue.
I don't think it's technically important what we do in the case where there is a .packages and no .package_config.json. That's only going to happen for a short while anyway, so whatever gives the best migration experience should be fine.
If there is no file at all, we do get the most current version. That's desired behavior for people writing new scripts from scratch.
If there is a package_config.json, we get the newest version for files which are not inside a package.
It seems slightly odd to not get the newest language version for files that are not inside a package just because there is a .packages file (potentially empty!), but if we do that, then that includes all files outside of lib in a package. So even if we pick 2.7 for all files in packages configured by a .packages file (which is kind-of reasonable since it's the last version prior to language versioning), we'll still see errors for files not in the lib dir.
Saying "everything is 2.7 if using a .packages file" could make sense. And that would apply no matter how you point to the .packages file or how it's discovered.
That's not something that can be handled by the package_config package because that only addresses files inside packages, it leaves it up to the user to decide for files outside of packages.
Maybe we should just tell people to run pub get if there is a .packages file and no package_config.json file.
I think it's a usability nightmare if installing Dart 2.10 and then doing a pub run suddenly means that you get run with the semantics of a new language version without having done anything to opt-in to that.
Will pub run tell you to run pub get if you're updated your SDK since the last time it was run? I thought it did.
@jonasfj
Will pub run tell you to run pub get if you're updated your SDK since the last time it was run? I thought it did.
I'd argue we need this more broadly and not just for pub run. I assume many users out there use the dart command line tool out of the box without running pub run. For that reason, I expect both the CFE and analyzer would need to handle this scenario properly.
I believe that our tools need to handle the case that there is a .packages and not a package_config.json explicitly anyway, correct? So it seems easy enough to just hard-code a language version for use whenever you have the former and not the latter.
After discussion on the language team, we have decided to treat loading of a .packages file in a language-versioning aware SDK as follows:
.packages and there is an adjacent .dart_tool/package_config.json, assume that it's the Pub file layout and load the other file instead..packages file as an ini file./lib/, assume that it's the Pub package layout and make the parent directory the package root and the lib/ directory to package URI root.I'll update package:package_config to do this automatically.
Will pub run tell you to run pub get if you're updated your SDK since the last time it was run? I thought it did.
We check that the current SDK is allowed by the resolution in pubspec.lock. I don't think this is exactly the same.
We recently reverted a change where we would reject the package_config.json if it was generated with a different Dart SDK. But this is the best-effort check that only runs if timestamps are out-of-order.
We do ask users to run pub get if they don't have a .dart_tool/package_config.json, we have been doing this since 2.7.0 -- when we added .dart_tool/package_config.json and language versioning.
@lrhn any news on getting package:package_config updated for this?
I have just published version 1.9.2 with the new behavior.
What do we need to do to roll that to the various tools?
I think it should be sufficient to update the DEPS file in the SDK.
I believe this is now fixed in https://github.com/dart-lang/package_config/commit/74c0bbb8283556ad1208c778a20be3684d1c3a9e and https://github.com/dart-lang/sdk/commit/9ef6c1e1a4039076fa0907a2c730dd45038ff749.
main.dart contains:
void main(List<String> arguments) {
int n = null;
print(n);
}
pubspec.yaml contains (note: this doesn't opt-in to null safety>:
name: app1
description: A simple command-line application.
environment:
sdk: '>=2.7.0 <3.0.0'
$ ~/dev/dartsdk/sdk/out/ReleaseX64NNBD/dart-sdk/bin/pub get
Resolving dependencies...
Got dependencies!
$ ~/dev/dartsdk/sdk/out/ReleaseX64NNBD/dart-sdk/bin/dart --enable-experiment=non-nullable bin/main.dart
null
$ rm -rf .dart_tool/
$ ~/dev/dartsdk/sdk/out/ReleaseX64NNBD/dart-sdk/bin/dart --enable-experiment=non-nullable bin/main.dart
bin/main.dart:2:11: Error: A value of type 'Null?' can't be assigned to a variable of type 'int'.
int n = null;
^
$ ~/dev/sdkrepo/sdk/xcodebuild/ReleaseX64NNBD/dart-sdk/bin/pub get
Resolving dependencies...
Got dependencies!
$ ~/dev/sdkrepo/sdk/xcodebuild/ReleaseX64NNBD/dart-sdk/bin/dart --enable-experiment=non-nullable bin/main.dart
null
$ rm -rf .dart_tool/
$ ~/dev/sdkrepo/sdk/xcodebuild/ReleaseX64NNBD/dart-sdk/bin/dart --enable-experiment=non-nullable bin/main.dart
null
Most helpful comment
After discussion on the language team, we have decided to treat loading of a
.packagesfile in a language-versioning aware SDK as follows:.packagesand there is an adjacent.dart_tool/package_config.json, assume that it's the Pub file layout and load the other file instead..packagesfile as aninifile./lib/, assume that it's the Pub package layout and make the parent directory the package root and thelib/directory to package URI root.I'll update
package:package_configto do this automatically.