Unverified Commit 0d83e801 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_tools] Null safe update packages (#99357)

parent c2409797
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:collection'; import 'dart:collection';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
...@@ -46,14 +44,12 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -46,14 +44,12 @@ class UpdatePackagesCommand extends FlutterCommand {
'force-upgrade', 'force-upgrade',
help: 'Attempt to update all the dependencies to their latest versions.\n' help: 'Attempt to update all the dependencies to their latest versions.\n'
'This will actually modify the pubspec.yaml files in your checkout.', 'This will actually modify the pubspec.yaml files in your checkout.',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'paths', 'paths',
help: 'Finds paths in the dependency chain leading from package specified ' help: 'Finds paths in the dependency chain leading from package specified '
'in "--from" to package specified in "--to".', 'in "--from" to package specified in "--to".',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addOption( ..addOption(
...@@ -70,7 +66,6 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -70,7 +66,6 @@ class UpdatePackagesCommand extends FlutterCommand {
'transitive-closure', 'transitive-closure',
help: 'Prints the dependency graph that is the transitive closure of ' help: 'Prints the dependency graph that is the transitive closure of '
'packages the Flutter SDK depends on.', 'packages the Flutter SDK depends on.',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
...@@ -78,25 +73,21 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -78,25 +73,21 @@ class UpdatePackagesCommand extends FlutterCommand {
help: 'Only prints the dependency graph that is the transitive closure ' help: 'Only prints the dependency graph that is the transitive closure '
'that a consumer of the Flutter SDK will observe (when combined ' 'that a consumer of the Flutter SDK will observe (when combined '
'with transitive-closure).', 'with transitive-closure).',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'verify-only', 'verify-only',
help: 'Verifies the package checksum without changing or updating deps.', help: 'Verifies the package checksum without changing or updating deps.',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'offline', 'offline',
help: 'Use cached packages instead of accessing the network.', help: 'Use cached packages instead of accessing the network.',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addFlag( ..addFlag(
'crash', 'crash',
help: 'For Flutter CLI testing only, forces this command to throw an unhandled exception.', help: 'For Flutter CLI testing only, forces this command to throw an unhandled exception.',
defaultsTo: false,
negatable: false, negatable: false,
) )
..addOption( ..addOption(
...@@ -121,8 +112,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -121,8 +112,7 @@ class UpdatePackagesCommand extends FlutterCommand {
// Lazy-initialize the net utilities with values from the context. // Lazy-initialize the net utilities with values from the context.
Net _cachedNet; late final Net _net = Net(
Net get _net => _cachedNet ??= Net(
httpClientFactory: context.get<HttpClientFactory>(), httpClientFactory: context.get<HttpClientFactory>(),
logger: globals.logger, logger: globals.logger,
platform: globals.platform, platform: globals.platform,
...@@ -131,9 +121,15 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -131,9 +121,15 @@ class UpdatePackagesCommand extends FlutterCommand {
Future<void> _downloadCoverageData() async { Future<void> _downloadCoverageData() async {
final String urlBase = globals.platform.environment['FLUTTER_STORAGE_BASE_URL'] ?? 'https://storage.googleapis.com'; final String urlBase = globals.platform.environment['FLUTTER_STORAGE_BASE_URL'] ?? 'https://storage.googleapis.com';
final Uri coverageUri = Uri.parse('$urlBase/flutter_infra_release/flutter/coverage/lcov.info'); final Uri coverageUri = Uri.parse('$urlBase/flutter_infra_release/flutter/coverage/lcov.info');
final List<int> data = await _net.fetchUrl(coverageUri); final List<int>? data = await _net.fetchUrl(
coverageUri,
maxAttempts: 3,
);
if (data == null) {
throwToolExit('Failed to fetch coverage data from $coverageUri');
}
final String coverageDir = globals.fs.path.join( final String coverageDir = globals.fs.path.join(
Cache.flutterRoot, Cache.flutterRoot!,
'packages/flutter/coverage', 'packages/flutter/coverage',
); );
globals.fs.file(globals.fs.path.join(coverageDir, 'lcov.base.info')) globals.fs.file(globals.fs.path.join(coverageDir, 'lcov.base.info'))
...@@ -146,7 +142,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -146,7 +142,7 @@ class UpdatePackagesCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final List<Directory> packages = runner.getRepoPackages(); final List<Directory> packages = runner!.getRepoPackages();
final bool forceUpgrade = boolArg('force-upgrade'); final bool forceUpgrade = boolArg('force-upgrade');
final bool isPrintPaths = boolArg('paths'); final bool isPrintPaths = boolArg('paths');
...@@ -268,7 +264,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -268,7 +264,7 @@ class UpdatePackagesCommand extends FlutterCommand {
checksumDependencies[data.name] = data.version; checksumDependencies[data.name] = data.version;
} }
} }
final String checksum = _computeChecksum(checksumDependencies.keys, (String name) => checksumDependencies[name]); final String checksum = _computeChecksum(checksumDependencies.keys, (String name) => checksumDependencies[name]!);
if (checksum != pubspec.checksum.value) { if (checksum != pubspec.checksum.value) {
// If the checksum doesn't match, they may have added or removed some dependencies. // If the checksum doesn't match, they may have added or removed some dependencies.
// we need to run update-packages to recapture the transitive deps. // we need to run update-packages to recapture the transitive deps.
...@@ -294,12 +290,12 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -294,12 +290,12 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
void _collectDependencies({ void _collectDependencies({
@required List<Directory> packages, required List<Directory> packages,
@required List<PubspecYaml> pubspecs, required List<PubspecYaml> pubspecs,
@required Set<String> specialDependencies, required Set<String> specialDependencies,
@required Map<String, PubspecDependency> explicitDependencies, required Map<String, PubspecDependency> explicitDependencies,
@required Map<String, PubspecDependency> allDependencies, required Map<String, PubspecDependency> allDependencies,
@required bool doUpgrade, required bool doUpgrade,
}) { }) {
// Visit all the directories with pubspec.yamls we care about. // Visit all the directories with pubspec.yamls we care about.
for (final Directory directory in packages) { for (final Directory directory in packages) {
...@@ -320,12 +316,12 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -320,12 +316,12 @@ class UpdatePackagesCommand extends FlutterCommand {
// This makes sure that we don't import a package in two different // This makes sure that we don't import a package in two different
// ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and // ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and
// saying "path: ../../..." in another. // saying "path: ../../..." in another.
final PubspecDependency previous = allDependencies[dependency.name]; final PubspecDependency previous = allDependencies[dependency.name]!;
if (dependency.kind != previous.kind || dependency.lockTarget != previous.lockTarget) { if (dependency.kind != previous.kind || dependency._lockTarget != previous._lockTarget) {
throwToolExit( throwToolExit(
'Inconsistent requirements around ${dependency.name}; ' 'Inconsistent requirements around ${dependency.name}; '
'saw ${dependency.kind} (${dependency.lockTarget}) in "${dependency.sourcePath}" ' 'saw ${dependency.kind} (${dependency._lockTarget}) in "${dependency.sourcePath}" '
'and ${previous.kind} (${previous.lockTarget}) in "${previous.sourcePath}".' 'and ${previous.kind} (${previous._lockTarget}) in "${previous.sourcePath}".'
); );
} }
if (dependency.version != previous.version) { if (dependency.version != previous.version) {
...@@ -350,12 +346,12 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -350,12 +346,12 @@ class UpdatePackagesCommand extends FlutterCommand {
// This makes sure that we don't import a package in two different // This makes sure that we don't import a package in two different
// ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and // ways, e.g. by saying "sdk: flutter" in one pubspec.yaml and
// saying "path: ../../..." in another. // saying "path: ../../..." in another.
final PubspecDependency previous = explicitDependencies[dependency.name]; final PubspecDependency previous = explicitDependencies[dependency.name]!;
if (dependency.kind != previous.kind || dependency.lockTarget != previous.lockTarget) { if (dependency.kind != previous.kind || dependency._lockTarget != previous._lockTarget) {
throwToolExit( throwToolExit(
'Inconsistent requirements around ${dependency.name}; ' 'Inconsistent requirements around ${dependency.name}; '
'saw ${dependency.kind} (${dependency.lockTarget}) in "${dependency.sourcePath}" ' 'saw ${dependency.kind} (${dependency._lockTarget}) in "${dependency.sourcePath}" '
'and ${previous.kind} (${previous.lockTarget}) in "${previous.sourcePath}".' 'and ${previous.kind} (${previous._lockTarget}) in "${previous.sourcePath}".'
); );
} }
} }
...@@ -373,11 +369,11 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -373,11 +369,11 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
Future<void> _generateFakePackage({ Future<void> _generateFakePackage({
Directory tempDir, required Directory tempDir,
Iterable<PubspecDependency> dependencies, required Iterable<PubspecDependency> dependencies,
List<PubspecYaml> pubspecs, required List<PubspecYaml> pubspecs,
PubDependencyTree tree, required PubDependencyTree tree,
bool doUpgrade, required bool doUpgrade,
}) async { }) async {
try { try {
final File fakePackage = _pubspecFor(tempDir); final File fakePackage = _pubspecFor(tempDir);
...@@ -390,7 +386,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -390,7 +386,7 @@ class UpdatePackagesCommand extends FlutterCommand {
); );
// Create a synthetic flutter SDK so that transitive flutter SDK // Create a synthetic flutter SDK so that transitive flutter SDK
// constraints are not affected by this upgrade. // constraints are not affected by this upgrade.
Directory temporaryFlutterSdk; Directory? temporaryFlutterSdk;
if (doUpgrade) { if (doUpgrade) {
temporaryFlutterSdk = createTemporaryFlutterSdk( temporaryFlutterSdk = createTemporaryFlutterSdk(
globals.logger, globals.logger,
...@@ -407,8 +403,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -407,8 +403,7 @@ class UpdatePackagesCommand extends FlutterCommand {
directory: tempDir.path, directory: tempDir.path,
upgrade: doUpgrade, upgrade: doUpgrade,
offline: boolArg('offline'), offline: boolArg('offline'),
flutterRootOverride: doUpgrade ? temporaryFlutterSdk.path : null, flutterRootOverride: temporaryFlutterSdk?.path,
generateSyntheticPackage: false,
); );
// Cleanup the temporary SDK // Cleanup the temporary SDK
try { try {
...@@ -437,10 +432,10 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -437,10 +432,10 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
bool _upgradePubspecs({ bool _upgradePubspecs({
@required PubDependencyTree tree, required PubDependencyTree tree,
@required List<PubspecYaml> pubspecs, required List<PubspecYaml> pubspecs,
@required Set<String> specialDependencies, required Set<String> specialDependencies,
@required Map<String, PubspecDependency> explicitDependencies, required Map<String, PubspecDependency> explicitDependencies,
}) { }) {
// The transitive dependency tree for the fake package does not contain // The transitive dependency tree for the fake package does not contain
// dependencies between Flutter SDK packages and pub packages. We add them // dependencies between Flutter SDK packages and pub packages. We add them
...@@ -453,7 +448,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -453,7 +448,7 @@ class UpdatePackagesCommand extends FlutterCommand {
tree._dependencyTree[package] = <String>{}; tree._dependencyTree[package] = <String>{};
for (final PubspecDependency dependency in pubspec.dependencies) { for (final PubspecDependency dependency in pubspec.dependencies) {
if (dependency.kind == DependencyKind.normal) { if (dependency.kind == DependencyKind.normal) {
tree._dependencyTree[package].add(dependency.name); tree._dependencyTree[package]!.add(dependency.name);
} }
} }
} }
...@@ -466,7 +461,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -466,7 +461,7 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
if (boolArg('paths')) { if (boolArg('paths')) {
showDependencyPaths(from: stringArg('from'), to: stringArg('to'), tree: tree); showDependencyPaths(from: stringArg('from')!, to: stringArg('to')!, tree: tree);
return true; return true;
} }
...@@ -499,8 +494,8 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -499,8 +494,8 @@ class UpdatePackagesCommand extends FlutterCommand {
'Running "flutter pub get" in affected packages...', 'Running "flutter pub get" in affected packages...',
); );
try { try {
// int.tryParse will convert an empty string to null // int.tryParse will not accept null, but will convert empty string to null
final int/*?*/ maxJobs = int.tryParse(stringArg('jobs') ?? ''); final int? maxJobs = int.tryParse(stringArg('jobs') ?? '');
final TaskQueue<void> queue = TaskQueue<void>(maxJobs: maxJobs); final TaskQueue<void> queue = TaskQueue<void>(maxJobs: maxJobs);
for (final Directory dir in packages) { for (final Directory dir in packages) {
unawaited(queue.add(() async { unawaited(queue.add(() async {
...@@ -512,7 +507,6 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -512,7 +507,6 @@ class UpdatePackagesCommand extends FlutterCommand {
// All dependencies should already have been downloaded by the fake // All dependencies should already have been downloaded by the fake
// package, so the concurrent checks can all happen offline. // package, so the concurrent checks can all happen offline.
offline: true, offline: true,
generateSyntheticPackage: false,
printProgress: false, printProgress: false,
); );
stopwatch.stop(); stopwatch.stop();
...@@ -530,10 +524,10 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -530,10 +524,10 @@ class UpdatePackagesCommand extends FlutterCommand {
globals.printStatus('Downloaded lcov data for package:flutter in ${seconds.toStringAsFixed(1)}s...'); globals.printStatus('Downloaded lcov data for package:flutter in ${seconds.toStringAsFixed(1)}s...');
})); }));
await queue.tasksComplete; await queue.tasksComplete;
status?.stop(); status.stop();
// The exception is rethrown, so don't catch only Exceptions. // The exception is rethrown, so don't catch only Exceptions.
} catch (exception) { // ignore: avoid_catches_without_on_clauses } catch (exception) { // ignore: avoid_catches_without_on_clauses
status?.cancel(); status.cancel();
rethrow; rethrow;
} }
...@@ -542,9 +536,9 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -542,9 +536,9 @@ class UpdatePackagesCommand extends FlutterCommand {
} }
void showDependencyPaths({ void showDependencyPaths({
@required String from, required String from,
@required String to, required String to,
@required PubDependencyTree tree, required PubDependencyTree tree,
}) { }) {
if (!tree.contains(from)) { if (!tree.contains(from)) {
throwToolExit('Package $from not found in the dependency tree.'); throwToolExit('Package $from not found in the dependency tree.');
...@@ -564,9 +558,9 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -564,9 +558,9 @@ class UpdatePackagesCommand extends FlutterCommand {
paths.add(link); paths.add(link);
} }
if (link.from != null) { if (link.from != null) {
visited.add(link.from.to); visited.add(link.from!.to);
} }
for (final String dependency in tree._dependencyTree[link.to]) { for (final String dependency in tree._dependencyTree[link.to]!) {
if (!visited.contains(dependency)) { if (!visited.contains(dependency)) {
traversalQueue.addFirst(_DependencyLink(from: link, to: dependency)); traversalQueue.addFirst(_DependencyLink(from: link, to: dependency));
} }
...@@ -577,7 +571,7 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -577,7 +571,7 @@ class UpdatePackagesCommand extends FlutterCommand {
final StringBuffer buf = StringBuffer(); final StringBuffer buf = StringBuffer();
while (path != null) { while (path != null) {
buf.write(path.to); buf.write(path.to);
path = path.from; path = path.from!;
if (path != null) { if (path != null) {
buf.write(' <- '); buf.write(' <- ');
} }
...@@ -593,11 +587,11 @@ class UpdatePackagesCommand extends FlutterCommand { ...@@ -593,11 +587,11 @@ class UpdatePackagesCommand extends FlutterCommand {
class _DependencyLink { class _DependencyLink {
_DependencyLink({ _DependencyLink({
@required this.from, required this.from,
@required this.to, required this.to,
}); });
final _DependencyLink from; final _DependencyLink? from;
final String to; final String to;
@override @override
...@@ -662,7 +656,7 @@ class PubspecYaml { ...@@ -662,7 +656,7 @@ class PubspecYaml {
final String name; final String name;
/// The package version. /// The package version.
final String version; final String? version;
final List<PubspecLine> inputData; // Each line of the pubspec.yaml file, parsed(ish). final List<PubspecLine> inputData; // Each line of the pubspec.yaml file, parsed(ish).
...@@ -679,9 +673,9 @@ class PubspecYaml { ...@@ -679,9 +673,9 @@ class PubspecYaml {
/// about (since they're all under our control). /// about (since they're all under our control).
static PubspecYaml _parse(File file, List<String> lines) { static PubspecYaml _parse(File file, List<String> lines) {
final String filename = file.path; final String filename = file.path;
String packageName; String? packageName;
String packageVersion; String? packageVersion;
PubspecChecksum checksum; // the checksum value used to verify that dependencies haven't changed. PubspecChecksum? checksum; // the checksum value used to verify that dependencies haven't changed.
final List<PubspecLine> result = <PubspecLine>[]; // The output buffer. final List<PubspecLine> result = <PubspecLine>[]; // The output buffer.
Section section = Section.other; // Which section we're currently reading from. Section section = Section.other; // Which section we're currently reading from.
bool seenMain = false; // Whether we've seen the "dependencies:" section. bool seenMain = false; // Whether we've seen the "dependencies:" section.
...@@ -695,13 +689,13 @@ class PubspecYaml { ...@@ -695,13 +689,13 @@ class PubspecYaml {
// whatnot) have the style of having extra data after the line that declares // whatnot) have the style of having extra data after the line that declares
// the dependency. So we track what is the "current" (or "last") dependency // the dependency. So we track what is the "current" (or "last") dependency
// that we are dealing with using this variable. // that we are dealing with using this variable.
PubspecDependency lastDependency; PubspecDependency? lastDependency;
for (int index = 0; index < lines.length; index += 1) { for (int index = 0; index < lines.length; index += 1) {
String line = lines[index]; String line = lines[index];
if (lastDependency == null) { if (lastDependency == null) {
// First we look to see if we're transitioning to a new top-level section. // First we look to see if we're transitioning to a new top-level section.
// The PubspecHeader.parse static method can recognize those headers. // The PubspecHeader.parse static method can recognize those headers.
final PubspecHeader header = PubspecHeader.parse(line); // See if it's a header. final PubspecHeader? header = PubspecHeader.parse(line); // See if it's a header.
if (header != null) { // It is! if (header != null) { // It is!
section = header.section; // The parser determined what kind of section it is. section = header.section; // The parser determined what kind of section it is.
if (section == Section.header) { if (section == Section.header) {
...@@ -748,7 +742,7 @@ class PubspecYaml { ...@@ -748,7 +742,7 @@ class PubspecYaml {
} }
} else { } else {
// We're in a section we care about. Try to parse out the dependency: // We're in a section we care about. Try to parse out the dependency:
final PubspecDependency dependency = PubspecDependency.parse(line, filename: filename); final PubspecDependency? dependency = PubspecDependency.parse(line, filename: filename);
if (dependency != null) { // We got one! if (dependency != null) { // We got one!
// Track whether or not this a dev dependency. // Track whether or not this a dev dependency.
dependency.isDevDependency = seenDev; dependency.isDevDependency = seenDev;
...@@ -813,7 +807,7 @@ class PubspecYaml { ...@@ -813,7 +807,7 @@ class PubspecYaml {
throw StateError('Invalid pubspec.yaml: a "git" dependency section terminated early.'); throw StateError('Invalid pubspec.yaml: a "git" dependency section terminated early.');
} }
line = lines[index]; line = lines[index];
lastDependency._lockLine += '\n$line'; lastDependency._lockLine = '${lastDependency._lockLine}\n$line';
} while (line.startsWith(' ')); } while (line.startsWith(' '));
} }
// We're done with this special dependency, so reset back to null so // We're done with this special dependency, so reset back to null so
...@@ -821,7 +815,7 @@ class PubspecYaml { ...@@ -821,7 +815,7 @@ class PubspecYaml {
lastDependency = null; lastDependency = null;
} }
} }
return PubspecYaml._(file, packageName, packageVersion, result, checksum ?? PubspecChecksum(null, '')); return PubspecYaml._(file, packageName!, packageVersion, result, checksum ?? PubspecChecksum(null, ''));
} }
/// This returns all the explicit dependencies that this pubspec.yaml lists under dependencies. /// This returns all the explicit dependencies that this pubspec.yaml lists under dependencies.
...@@ -860,9 +854,9 @@ class PubspecYaml { ...@@ -860,9 +854,9 @@ class PubspecYaml {
Section section = Section.other; // the section we're currently handling Section section = Section.other; // the section we're currently handling
// the line number where we're going to insert the transitive dependencies. // the line number where we're going to insert the transitive dependencies.
int endOfDirectDependencies; int? endOfDirectDependencies;
// The line number where we're going to insert the transitive dev dependencies. // The line number where we're going to insert the transitive dev dependencies.
int endOfDevDependencies; int? endOfDevDependencies;
// Walk the pre-parsed input file, outputting it unmodified except for // Walk the pre-parsed input file, outputting it unmodified except for
// updating version numbers, removing the old transitive dependencies lines, // updating version numbers, removing the old transitive dependencies lines,
// and adding our new transitive dependencies lines. We also do a little // and adding our new transitive dependencies lines. We also do a little
...@@ -913,7 +907,7 @@ class PubspecYaml { ...@@ -913,7 +907,7 @@ class PubspecYaml {
// flutter" line) then we output that too. // flutter" line) then we output that too.
output.add(data.line); output.add(data.line);
if (data.lockLine != null) { if (data.lockLine != null) {
output.add(data.lockLine); output.add(data.lockLine!);
} }
} }
// Remember that we've dealt with this dependency so we don't // Remember that we've dealt with this dependency so we don't
...@@ -940,7 +934,7 @@ class PubspecYaml { ...@@ -940,7 +934,7 @@ class PubspecYaml {
// In other sections, pass everything through in its original form. // In other sections, pass everything through in its original form.
output.add(data.line); output.add(data.line);
if (data.lockLine != null) { if (data.lockLine != null) {
output.add(data.lockLine); output.add(data.lockLine!);
} }
break; break;
} }
...@@ -1040,7 +1034,7 @@ class PubspecYaml { ...@@ -1040,7 +1034,7 @@ class PubspecYaml {
line = line.trimRight(); line = line.trimRight();
if (line == '') { if (line == '') {
if (!hadBlankLine) { if (!hadBlankLine) {
contents.writeln(''); contents.writeln();
} }
hadBlankLine = true; hadBlankLine = true;
} else { } else {
...@@ -1070,7 +1064,7 @@ class PubspecChecksum extends PubspecLine { ...@@ -1070,7 +1064,7 @@ class PubspecChecksum extends PubspecLine {
/// and special dependencies sorted lexically. /// and special dependencies sorted lexically.
/// ///
/// If the line cannot be parsed, [value] will be null. /// If the line cannot be parsed, [value] will be null.
final String value; final String? value;
/// Parses a [PubspecChecksum] from a line. /// Parses a [PubspecChecksum] from a line.
/// ///
...@@ -1087,7 +1081,12 @@ class PubspecChecksum extends PubspecLine { ...@@ -1087,7 +1081,12 @@ class PubspecChecksum extends PubspecLine {
/// A header, e.g. "dependencies:". /// A header, e.g. "dependencies:".
class PubspecHeader extends PubspecLine { class PubspecHeader extends PubspecLine {
PubspecHeader(String line, this.section, { this.name, this.value }) : super(line); PubspecHeader(
String line,
this.section, {
this.name,
this.value,
}) : super(line);
/// The section of the pubspec where the parse [line] appears. /// The section of the pubspec where the parse [line] appears.
final Section section; final Section section;
...@@ -1102,7 +1101,7 @@ class PubspecHeader extends PubspecLine { ...@@ -1102,7 +1101,7 @@ class PubspecHeader extends PubspecLine {
/// ``` /// ```
/// version: 0.16.5 /// version: 0.16.5
/// ``` /// ```
final String name; final String? name;
/// The value in the pubspec line providing a name/value pair, such as "name" /// The value in the pubspec line providing a name/value pair, such as "name"
/// and "version". /// and "version".
...@@ -1114,9 +1113,9 @@ class PubspecHeader extends PubspecLine { ...@@ -1114,9 +1113,9 @@ class PubspecHeader extends PubspecLine {
/// ``` /// ```
/// version: 0.16.5 /// version: 0.16.5
/// ``` /// ```
final String value; final String? value;
static PubspecHeader parse(String line) { static PubspecHeader? parse(String line) {
// We recognize any line that: // We recognize any line that:
// * doesn't start with a space (i.e. is aligned on the left edge) // * doesn't start with a space (i.e. is aligned on the left edge)
// * ignoring trailing spaces and comments, ends with a colon // * ignoring trailing spaces and comments, ends with a colon
...@@ -1167,14 +1166,14 @@ class PubspecDependency extends PubspecLine { ...@@ -1167,14 +1166,14 @@ class PubspecDependency extends PubspecLine {
String line, String line,
this.name, this.name,
this.suffix, { this.suffix, {
@required this.isTransitive, required this.isTransitive,
DependencyKind kind, required DependencyKind kind,
this.version, required this.version,
this.sourcePath, required this.sourcePath,
}) : _kind = kind, }) : _kind = kind,
super(line); super(line);
static PubspecDependency parse(String line, { @required String filename }) { static PubspecDependency? parse(String line, { required String filename }) {
// We recognize any line that: // We recognize any line that:
// * starts with exactly two spaces, no more or less // * starts with exactly two spaces, no more or less
// * has some content, then a colon // * has some content, then a colon
...@@ -1231,26 +1230,25 @@ class PubspecDependency extends PubspecLine { ...@@ -1231,26 +1230,25 @@ class PubspecDependency extends PubspecLine {
final String version; // the version string if found, or blank. final String version; // the version string if found, or blank.
final bool isTransitive; // whether the suffix matched kTransitiveMagicString final bool isTransitive; // whether the suffix matched kTransitiveMagicString
final String sourcePath; // the filename of the pubspec.yaml file, for error messages final String sourcePath; // the filename of the pubspec.yaml file, for error messages
bool isDevDependency; // Whether this dependency is under the `dev dependencies` section. late bool isDevDependency; // Whether this dependency is under the `dev dependencies` section.
DependencyKind get kind => _kind; DependencyKind get kind => _kind;
DependencyKind _kind = DependencyKind.normal; DependencyKind _kind = DependencyKind.normal;
/// If we're a path or sdk dependency, the path or sdk in question. /// If we're a path or sdk dependency, the path or sdk in question.
String get lockTarget => _lockTarget; String? _lockTarget;
String _lockTarget;
/// If we were a two-line dependency, the second line (see the inherited [line] /// If we were a two-line dependency, the second line (see the inherited [line]
/// for the first). /// for the first).
String get lockLine => _lockLine; String? get lockLine => _lockLine;
String _lockLine; String? _lockLine;
/// If we're a path or sdk dependency, whether we were found in a /// If we're a path or sdk dependency, whether we were found in a
/// dependencies/dev_dependencies section, or a dependency_overrides section. /// dependencies/dev_dependencies section, or a dependency_overrides section.
/// We track this so that we can put ourselves in the right section when /// We track this so that we can put ourselves in the right section when
/// generating the fake pubspec.yaml. /// generating the fake pubspec.yaml.
bool get lockIsOverride => _lockIsOverride; bool get lockIsOverride => _lockIsOverride;
bool _lockIsOverride; late bool _lockIsOverride;
static const String _pathPrefix = ' path: '; static const String _pathPrefix = ' path: ';
static const String _sdkPrefix = ' sdk: '; static const String _sdkPrefix = ' sdk: ';
...@@ -1268,9 +1266,10 @@ class PubspecDependency extends PubspecLine { ...@@ -1268,9 +1266,10 @@ class PubspecDependency extends PubspecLine {
return true; return true;
} }
if (_kind == DependencyKind.path && final String? lockTarget = _lockTarget;
!globals.fs.path.isWithin(globals.fs.path.join(Cache.flutterRoot, 'bin'), _lockTarget) && if (_kind == DependencyKind.path && lockTarget != null &&
globals.fs.path.isWithin(Cache.flutterRoot, _lockTarget)) { !globals.fs.path.isWithin(globals.fs.path.join(Cache.flutterRoot!, 'bin'), lockTarget) &&
globals.fs.path.isWithin(Cache.flutterRoot!, lockTarget)) {
return true; return true;
} }
...@@ -1281,7 +1280,7 @@ class PubspecDependency extends PubspecLine { ...@@ -1281,7 +1280,7 @@ class PubspecDependency extends PubspecLine {
/// We throw if we couldn't parse this line. /// We throw if we couldn't parse this line.
/// We return true if we parsed it and stored the line in lockLine. /// We return true if we parsed it and stored the line in lockLine.
/// We return false if we parsed it and it's a git dependency that needs the next few lines. /// We return false if we parsed it and it's a git dependency that needs the next few lines.
bool parseLock(String line, String pubspecPath, { @required bool lockIsOverride }) { bool parseLock(String line, String pubspecPath, { required bool lockIsOverride }) {
assert(lockIsOverride != null); assert(lockIsOverride != null);
assert(kind == DependencyKind.unknown); assert(kind == DependencyKind.unknown);
if (line.startsWith(_pathPrefix)) { if (line.startsWith(_pathPrefix)) {
...@@ -1333,27 +1332,27 @@ class PubspecDependency extends PubspecLine { ...@@ -1333,27 +1332,27 @@ class PubspecDependency extends PubspecLine {
} }
break; break;
case DependencyKind.path: case DependencyKind.path:
if (_lockIsOverride) { if (lockIsOverride) {
dependencies.writeln(' $name: $versionToUse'); dependencies.writeln(' $name: $versionToUse');
overrides.writeln(' $name:'); overrides.writeln(' $name:');
overrides.writeln(' path: $lockTarget'); overrides.writeln(' path: $_lockTarget');
} else { } else {
dependencies.writeln(' $name:'); dependencies.writeln(' $name:');
dependencies.writeln(' path: $lockTarget'); dependencies.writeln(' path: $_lockTarget');
} }
break; break;
case DependencyKind.sdk: case DependencyKind.sdk:
if (_lockIsOverride) { if (lockIsOverride) {
dependencies.writeln(' $name: $versionToUse'); dependencies.writeln(' $name: $versionToUse');
overrides.writeln(' $name:'); overrides.writeln(' $name:');
overrides.writeln(' sdk: $lockTarget'); overrides.writeln(' sdk: $_lockTarget');
} else { } else {
dependencies.writeln(' $name:'); dependencies.writeln(' $name:');
dependencies.writeln(' sdk: $lockTarget'); dependencies.writeln(' sdk: $_lockTarget');
} }
break; break;
case DependencyKind.git: case DependencyKind.git:
if (_lockIsOverride) { if (lockIsOverride) {
dependencies.writeln(' $name: $versionToUse'); dependencies.writeln(' $name: $versionToUse');
overrides.writeln(' $name:'); overrides.writeln(' $name:');
overrides.writeln(lockLine); overrides.writeln(lockLine);
...@@ -1398,20 +1397,19 @@ String _generateFakePubspec( ...@@ -1398,20 +1397,19 @@ String _generateFakePubspec(
for (final PubspecDependency dependency in dependencies) for (final PubspecDependency dependency in dependencies)
dependency.name, dependency.name,
}; };
for (final String package in kManuallyPinnedDependencies.keys) { kManuallyPinnedDependencies.forEach((String package, String version) {
// Don't add pinned dependency if it is not in the set of all transitive dependencies. // Don't add pinned dependency if it is not in the set of all transitive dependencies.
if (!allTransitive.contains(package)) { if (!allTransitive.contains(package)) {
if (verbose) { if (verbose) {
globals.printStatus('Skipping $package because it was not transitive'); globals.printStatus('Skipping $package because it was not transitive');
} }
continue; return;
} }
final String version = kManuallyPinnedDependencies[package];
result.writeln(' $package: $version'); result.writeln(' $package: $version');
if (verbose) { if (verbose) {
globals.printStatus(' - $package: $version'); globals.printStatus(' - $package: $version');
} }
} });
} }
for (final PubspecDependency dependency in dependencies) { for (final PubspecDependency dependency in dependencies) {
if (!dependency.pointsToSdk) { if (!dependency.pointsToSdk) {
...@@ -1427,7 +1425,7 @@ String _generateFakePubspec( ...@@ -1427,7 +1425,7 @@ String _generateFakePubspec(
/// It ends up holding the full graph of dependencies, and the version number for /// It ends up holding the full graph of dependencies, and the version number for
/// each one. /// each one.
class PubDependencyTree { class PubDependencyTree {
final Map<String, String> _versions = <String, String>{}; final Map<String, String?> _versions = <String, String>{};
final Map<String, Set<String>> _dependencyTree = <String, Set<String>>{}; final Map<String, Set<String>> _dependencyTree = <String, Set<String>>{};
/// Handles the output from "pub deps --style=compact". /// Handles the output from "pub deps --style=compact".
...@@ -1460,7 +1458,7 @@ class PubDependencyTree { ...@@ -1460,7 +1458,7 @@ class PubDependencyTree {
/// We then parse out the package name, version number, and sub-dependencies for /// We then parse out the package name, version number, and sub-dependencies for
/// each entry, and store than in our _versions and _dependencyTree fields /// each entry, and store than in our _versions and _dependencyTree fields
/// above. /// above.
String fill(String message) { String? fill(String message) {
if (message.startsWith('- ')) { if (message.startsWith('- ')) {
final int space2 = message.indexOf(' ', 2); final int space2 = message.indexOf(' ', 2);
int space3 = message.indexOf(' ', space2 + 1); int space3 = message.indexOf(' ', space2 + 1);
...@@ -1497,19 +1495,20 @@ class PubDependencyTree { ...@@ -1497,19 +1495,20 @@ class PubDependencyTree {
/// excluding any listed in `seen`. /// excluding any listed in `seen`.
Iterable<String> getTransitiveDependenciesFor( Iterable<String> getTransitiveDependenciesFor(
String package, { String package, {
@required Set<String> seen, required Set<String> seen,
@required Set<String> exclude, required Set<String> exclude,
List<String>/*?*/ result, List<String>? result,
}) { }) {
assert(seen != null); assert(seen != null);
assert(exclude != null); assert(exclude != null);
result ??= <String>[]; result ??= <String>[];
if (!_dependencyTree.containsKey(package)) { final Set<String>? dependencies = _dependencyTree[package];
if (dependencies == null) {
// We have no transitive dependencies extracted for flutter_sdk packages // We have no transitive dependencies extracted for flutter_sdk packages
// because they were omitted from pubspec.yaml used for 'pub upgrade' run. // because they were omitted from pubspec.yaml used for 'pub upgrade' run.
return result; return result;
} }
for (final String dependency in _dependencyTree[package]) { for (final String dependency in dependencies) {
if (!seen.contains(dependency)) { if (!seen.contains(dependency)) {
if (!exclude.contains(dependency)) { if (!exclude.contains(dependency)) {
result.add(dependency); result.add(dependency);
...@@ -1523,7 +1522,7 @@ class PubDependencyTree { ...@@ -1523,7 +1522,7 @@ class PubDependencyTree {
/// The version that a particular package ended up with. /// The version that a particular package ended up with.
String versionFor(String package) { String versionFor(String package) {
return _versions[package]; return _versions[package]!;
} }
} }
...@@ -1535,7 +1534,6 @@ String _computeChecksum(Iterable<String> names, String Function(String name) get ...@@ -1535,7 +1534,6 @@ String _computeChecksum(Iterable<String> names, String Function(String name) get
final List<String> sortedNames = names.toList()..sort(); final List<String> sortedNames = names.toList()..sort();
for (final String name in sortedNames) { for (final String name in sortedNames) {
final String version = getVersion(name); final String version = getVersion(name);
assert(version != '');
if (version == null) { if (version == null) {
continue; continue;
} }
...@@ -1589,7 +1587,7 @@ Directory createTemporaryFlutterSdk( ...@@ -1589,7 +1587,7 @@ Directory createTemporaryFlutterSdk(
.childDirectory(flutterPackage) .childDirectory(flutterPackage)
.childFile('pubspec.yaml') .childFile('pubspec.yaml')
..createSync(recursive: true); ..createSync(recursive: true);
final PubspecYaml pubspecYaml = pubspecsByName[flutterPackage]; final PubspecYaml? pubspecYaml = pubspecsByName[flutterPackage];
if (pubspecYaml == null) { if (pubspecYaml == null) {
logger.printWarning( logger.printWarning(
"Unexpected package '$flutterPackage' found in packages directory", "Unexpected package '$flutterPackage' found in packages directory",
......
...@@ -31,7 +31,7 @@ const String _kPubCacheEnvironmentKey = 'PUB_CACHE'; ...@@ -31,7 +31,7 @@ const String _kPubCacheEnvironmentKey = 'PUB_CACHE';
/// (see https://github.com/dart-lang/pub/blob/master/lib/src/exit_codes.dart) /// (see https://github.com/dart-lang/pub/blob/master/lib/src/exit_codes.dart)
const int _kPubExitCodeUnavailable = 69; const int _kPubExitCodeUnavailable = 69;
typedef MessageFilter = String Function(String message); typedef MessageFilter = String? Function(String message);
/// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT` /// Represents Flutter-specific data that is added to the `PUB_ENVIRONMENT`
/// environment variable and allows understanding the type of requests made to /// environment variable and allows understanding the type of requests made to
...@@ -311,7 +311,7 @@ class _DefaultPub implements Pub { ...@@ -311,7 +311,7 @@ class _DefaultPub implements Pub {
String lastPubMessage = 'no message'; String lastPubMessage = 'no message';
bool versionSolvingFailed = false; bool versionSolvingFailed = false;
String filterWrapper(String line) { String? filterWrapper(String line) {
lastPubMessage = line; lastPubMessage = line;
if (line.contains('version solving failed')) { if (line.contains('version solving failed')) {
versionSolvingFailed = true; versionSolvingFailed = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment