[flutter_tools] Add flutter update-packages --synthetic-package-path (#115665)
* allow persisting synthetic package with option * allow presisting synthetic packages dir * fix * fix bug and add tests * clean up tests * nits
This commit is contained in:
parent
ce2fa9a56d
commit
0b9d18f8fa
@ -99,6 +99,14 @@ class UpdatePackagesCommand extends FlutterCommand {
|
||||
abbr: 'j',
|
||||
help: 'Causes the "pub get" runs to happen concurrently on this many '
|
||||
'CPUs. Defaults to the number of CPUs that this machine has.',
|
||||
)
|
||||
..addOption(
|
||||
'synthetic-package-path',
|
||||
help: 'Write the synthetic monolithic pub package generated to do '
|
||||
'version solving to a persistent path. By default, a temporary '
|
||||
'directory that is deleted before the command exits. By '
|
||||
'providing this path, a Flutter maintainer can inspect further '
|
||||
'exactly how version solving was achieved.',
|
||||
);
|
||||
}
|
||||
|
||||
@ -106,7 +114,10 @@ class UpdatePackagesCommand extends FlutterCommand {
|
||||
final String name = 'update-packages';
|
||||
|
||||
@override
|
||||
final String description = 'Update the packages inside the Flutter repo.';
|
||||
final String description = 'Update the packages inside the Flutter repo. '
|
||||
'This is intended for CI and repo maintainers. '
|
||||
'Normal Flutter developers should not have to '
|
||||
'use this command.';
|
||||
|
||||
@override
|
||||
final List<String> aliases = <String>['upgrade-packages'];
|
||||
@ -144,6 +155,22 @@ class UpdatePackagesCommand extends FlutterCommand {
|
||||
..writeAsBytesSync(data, flush: true);
|
||||
}
|
||||
|
||||
late final Directory _syntheticPackageDir = (() {
|
||||
final String? optionPath = stringArg('synthetic-package-path');
|
||||
if (optionPath == null) {
|
||||
return globals.fs.systemTempDirectory.createTempSync('flutter_update_packages.');
|
||||
}
|
||||
final Directory syntheticPackageDir = globals.fs.directory(optionPath);
|
||||
if (!syntheticPackageDir.existsSync()) {
|
||||
syntheticPackageDir.createSync(recursive: true);
|
||||
}
|
||||
globals.printStatus(
|
||||
'The synthetic package with all pub dependencies across the repo will '
|
||||
'be written to ${syntheticPackageDir.absolute.path}.',
|
||||
);
|
||||
return syntheticPackageDir;
|
||||
})();
|
||||
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
final List<Directory> packages = runner!.getRepoPackages();
|
||||
@ -218,15 +245,19 @@ class UpdatePackagesCommand extends FlutterCommand {
|
||||
// attempt to download any necessary package versions to the pub cache to
|
||||
// warm the cache.
|
||||
final PubDependencyTree tree = PubDependencyTree(); // object to collect results
|
||||
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_update_packages.');
|
||||
await _generateFakePackage(
|
||||
tempDir: tempDir,
|
||||
tempDir: _syntheticPackageDir,
|
||||
dependencies: doUpgrade ? explicitDependencies.values : allDependencies.values,
|
||||
pubspecs: pubspecs,
|
||||
tree: tree,
|
||||
doUpgrade: doUpgrade,
|
||||
);
|
||||
|
||||
// Only delete the synthetic package if it was done in a temp directory
|
||||
if (stringArg('synthetic-package-path') == null) {
|
||||
_syntheticPackageDir.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
if (doUpgrade) {
|
||||
final bool done = _upgradePubspecs(
|
||||
tree: tree,
|
||||
@ -380,57 +411,49 @@ class UpdatePackagesCommand extends FlutterCommand {
|
||||
required bool doUpgrade,
|
||||
}) async {
|
||||
Directory? temporaryFlutterSdk;
|
||||
try {
|
||||
final File fakePackage = _pubspecFor(tempDir);
|
||||
fakePackage.createSync();
|
||||
fakePackage.writeAsStringSync(
|
||||
generateFakePubspec(
|
||||
dependencies,
|
||||
doUpgrade: doUpgrade,
|
||||
),
|
||||
final Directory syntheticPackageDir = tempDir.childDirectory('synthetic_package');
|
||||
final File fakePackage = _pubspecFor(syntheticPackageDir);
|
||||
fakePackage.createSync(recursive: true);
|
||||
fakePackage.writeAsStringSync(
|
||||
generateFakePubspec(
|
||||
dependencies,
|
||||
doUpgrade: doUpgrade,
|
||||
),
|
||||
);
|
||||
// Create a synthetic flutter SDK so that transitive flutter SDK
|
||||
// constraints are not affected by this upgrade.
|
||||
if (doUpgrade) {
|
||||
temporaryFlutterSdk = createTemporaryFlutterSdk(
|
||||
globals.logger,
|
||||
globals.fs,
|
||||
globals.fs.directory(Cache.flutterRoot),
|
||||
pubspecs,
|
||||
tempDir,
|
||||
);
|
||||
// Create a synthetic flutter SDK so that transitive flutter SDK
|
||||
// constraints are not affected by this upgrade.
|
||||
if (doUpgrade) {
|
||||
temporaryFlutterSdk = createTemporaryFlutterSdk(
|
||||
globals.logger,
|
||||
globals.fs,
|
||||
globals.fs.directory(Cache.flutterRoot),
|
||||
pubspecs,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Next we run "pub get" on it in order to force the download of any
|
||||
// needed packages to the pub cache, upgrading if requested.
|
||||
await pub.get(
|
||||
// Next we run "pub get" on it in order to force the download of any
|
||||
// needed packages to the pub cache, upgrading if requested.
|
||||
await pub.get(
|
||||
context: PubContext.updatePackages,
|
||||
project: FlutterProject.fromDirectory(syntheticPackageDir),
|
||||
upgrade: doUpgrade,
|
||||
offline: boolArgDeprecated('offline'),
|
||||
flutterRootOverride: temporaryFlutterSdk?.path,
|
||||
);
|
||||
|
||||
if (doUpgrade) {
|
||||
// If upgrading, we run "pub deps --style=compact" on the result. We
|
||||
// pipe all the output to tree.fill(), which parses it so that it can
|
||||
// create a graph of all the dependencies so that we can figure out the
|
||||
// transitive dependencies later. It also remembers which version was
|
||||
// selected for each package.
|
||||
await pub.batch(
|
||||
<String>['deps', '--style=compact'],
|
||||
context: PubContext.updatePackages,
|
||||
project: FlutterProject.fromDirectory(tempDir),
|
||||
upgrade: doUpgrade,
|
||||
offline: boolArgDeprecated('offline'),
|
||||
flutterRootOverride: temporaryFlutterSdk?.path,
|
||||
directory: syntheticPackageDir.path,
|
||||
filter: tree.fill,
|
||||
);
|
||||
|
||||
if (doUpgrade) {
|
||||
// If upgrading, we run "pub deps --style=compact" on the result. We
|
||||
// pipe all the output to tree.fill(), which parses it so that it can
|
||||
// create a graph of all the dependencies so that we can figure out the
|
||||
// transitive dependencies later. It also remembers which version was
|
||||
// selected for each package.
|
||||
await pub.batch(
|
||||
<String>['deps', '--style=compact'],
|
||||
context: PubContext.updatePackages,
|
||||
directory: tempDir.path,
|
||||
filter: tree.fill,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
// Cleanup the temporary SDK
|
||||
try {
|
||||
temporaryFlutterSdk?.deleteSync(recursive: true);
|
||||
} on FileSystemException {
|
||||
// Failed to delete temporary SDK.
|
||||
}
|
||||
tempDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1577,6 +1600,7 @@ Directory createTemporaryFlutterSdk(
|
||||
FileSystem fileSystem,
|
||||
Directory realFlutter,
|
||||
List<PubspecYaml> pubspecs,
|
||||
Directory tempDir,
|
||||
) {
|
||||
final Set<String> currentPackages = <String>{};
|
||||
for (final FileSystemEntity entity in realFlutter.childDirectory('packages').listSync()) {
|
||||
@ -1591,8 +1615,7 @@ Directory createTemporaryFlutterSdk(
|
||||
pubspecsByName[pubspec.name] = pubspec;
|
||||
}
|
||||
|
||||
final Directory directory = fileSystem.systemTempDirectory
|
||||
.createTempSync('flutter_upgrade_sdk.')
|
||||
final Directory directory = tempDir.childDirectory('flutter_upgrade_sdk')
|
||||
..createSync();
|
||||
// Fill in version info.
|
||||
realFlutter.childFile('version')
|
||||
|
@ -87,6 +87,7 @@ void main() {
|
||||
late Directory flutterSdk;
|
||||
late Directory flutter;
|
||||
late FakePub pub;
|
||||
late FakeProcessManager processManager;
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
@ -105,13 +106,14 @@ void main() {
|
||||
flutter.childFile('pubspec.yaml').writeAsStringSync(kFlutterPubspecYaml);
|
||||
Cache.flutterRoot = flutterSdk.absolute.path;
|
||||
pub = FakePub(fileSystem);
|
||||
processManager = FakeProcessManager.empty();
|
||||
});
|
||||
|
||||
testUsingContext('updates packages', () async {
|
||||
final UpdatePackagesCommand command = UpdatePackagesCommand();
|
||||
await createTestCommandRunner(command).run(<String>['update-packages']);
|
||||
expect(pub.pubGetDirectories, equals(<String>[
|
||||
'/.tmp_rand0/flutter_update_packages.rand0',
|
||||
'/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
|
||||
'/flutter/examples',
|
||||
'/flutter/packages/flutter',
|
||||
]));
|
||||
@ -119,9 +121,9 @@ void main() {
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => pub,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
ProcessManager: () => processManager,
|
||||
Cache: () => Cache.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
processManager: processManager,
|
||||
),
|
||||
});
|
||||
|
||||
@ -132,19 +134,19 @@ void main() {
|
||||
'--force-upgrade',
|
||||
]);
|
||||
expect(pub.pubGetDirectories, equals(<String>[
|
||||
'/.tmp_rand0/flutter_update_packages.rand0',
|
||||
'/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
|
||||
'/flutter/examples',
|
||||
'/flutter/packages/flutter',
|
||||
]));
|
||||
expect(pub.pubBatchDirectories, equals(<String>[
|
||||
'/.tmp_rand0/flutter_update_packages.rand0',
|
||||
'/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
|
||||
]));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => pub,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
ProcessManager: () => processManager,
|
||||
Cache: () => Cache.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
processManager: processManager,
|
||||
),
|
||||
});
|
||||
|
||||
@ -156,19 +158,44 @@ void main() {
|
||||
'--jobs=1',
|
||||
]);
|
||||
expect(pub.pubGetDirectories, equals(<String>[
|
||||
'/.tmp_rand0/flutter_update_packages.rand0',
|
||||
'/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
|
||||
'/flutter/examples',
|
||||
'/flutter/packages/flutter',
|
||||
]));
|
||||
expect(pub.pubBatchDirectories, equals(<String>[
|
||||
'/.tmp_rand0/flutter_update_packages.rand0',
|
||||
'/.tmp_rand0/flutter_update_packages.rand0/synthetic_package',
|
||||
]));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => pub,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
ProcessManager: () => processManager,
|
||||
Cache: () => Cache.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
processManager: processManager,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('force updates packages --synthetic-package-path', () async {
|
||||
final UpdatePackagesCommand command = UpdatePackagesCommand();
|
||||
const String dir = '/path/to/synthetic/package';
|
||||
await createTestCommandRunner(command).run(<String>[
|
||||
'update-packages',
|
||||
'--force-upgrade',
|
||||
'--synthetic-package-path=$dir',
|
||||
]);
|
||||
expect(pub.pubGetDirectories, equals(<String>[
|
||||
'$dir/synthetic_package',
|
||||
'/flutter/examples',
|
||||
'/flutter/packages/flutter',
|
||||
]));
|
||||
expect(pub.pubBatchDirectories, equals(<String>[
|
||||
'$dir/synthetic_package',
|
||||
]));
|
||||
}, overrides: <Type, Generator>{
|
||||
Pub: () => pub,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
Cache: () => Cache.test(
|
||||
processManager: processManager,
|
||||
),
|
||||
});
|
||||
});
|
||||
|
@ -121,6 +121,7 @@ void main() {
|
||||
fileSystem,
|
||||
flutterSdk,
|
||||
<PubspecYaml>[flutterPubspec],
|
||||
fileSystem.systemTempDirectory,
|
||||
);
|
||||
|
||||
expect(result, exists);
|
||||
|
Loading…
x
Reference in New Issue
Block a user