最近碰到一个奇怪的问题
先来看个现象
工程结构
.
├── README.md
├── android
├── build
├── ios
├── lib
├── pubspec.lock
├── pubspec.yaml
├── subpackage
├── test
└── webview_demo.iml
子工程空安全检测正确✅
jiodg45@jiodg45s-MacBook-Pro subpackage % dart pub outdated --mode=null-safetyShowing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
主工程检测却发现子工程出现空安全问题❌
jiodg45@jiodg45s-MacBook-Pro webview_demo % dart pub outdated --mode=null-safety
Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
Package Name Current Upgradable Resolvable Latest
direct dependencies:
subpackage ✗0.0.1 (path) ✗0.0.1 (path) ✗0.0.1 (path) ✗0.0.1 (path)
十分诡异,于是开启了--verbose
查看详细日志,空安全检测具体命令dart pub outdated --mode=null-safety --verbose
可以看到空安全检测主要是对每个库的sdk版本与2.12.0进行比较
- 获取依赖,包含git/path/pub三个级别的依赖
- 其中工程外的pub依赖关系保存在
/Users/jiodg45/.pub-cache/hosted/pub.dartlang.org/.cache/cupertino_icons-versions.json.
,对应路径为$HOME/$PUB_CACHE/hosted/HOST_PUB_URL/.cache/{package_name}-versions
, 此部分是从pub库上获取,通过json中的environment
获取到sdk版本,用于后续比较 - 工程内的依赖关系保存在
pubspec.lock
文件中,git
和path
相关的一级依赖也会被添加到此仓库中,以来类型为dependency: transitive
- 这样仓库的所有的依赖关系可以从三个文件一次进行查找,
pubspec.yaml
->pubspec.lock
->`` H O M E / HOME/ HOME/PUB_CACHE/hosted/HOST_PUB_URL/.cache/{package_name}-versions
对应的代码可以在pub
库的outdated.dart
中查看,省略后的关键代码如下,主要逻辑集中在supportsNullSafety
,逐一查找package的dart sdkVersion,然后与2.12.0
比较
https://github.com/dart-lang/pub/blob/master/lib/src/command/outdated.dart
-> OutdatedCommand
@override
Future<List<List<_MarkedVersionDetails>>> markVersionDetails(
List<_PackageDetails> packages) async {
final nullSafetyMap =
await log.spinner('Computing null safety support', () async {
/// Find all unique ids.
...
return Map.fromEntries(
await Future.wait(
ids.map(
(id) async => MapEntry(
id,
(await id.source.bind(cache).describe(id))
.languageVersion
.supportsNullSafety),
...
所以当子工程的pubspec.yaml
中sdkVersion
指定的最低版本低于2.12.0
时会报空安全检测异常. 因此在升级时一定要修改sdk的最低约束,防止误检.
environment:
sdk: ">=2.12.0 <3.0.0"