mirror of
https://github.com/toyota-connected/emb_cli.git
synced 2026-06-21 07:19:37 -07:00
style: format with the Dart 3.12 formatter
Apply `dart format` (tall style) across bin/, lib/, and test/. No logic changes. Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
This commit is contained in:
+4
-2
@@ -16,6 +16,8 @@ Future<void> main(List<String> args) async {
|
||||
/// exited already. This is useful to prevent Future chains from proceeding
|
||||
/// after you've decided to exit.
|
||||
Future<void> _flushThenExit(int status) {
|
||||
return Future.wait<void>([stdout.close(), stderr.close()])
|
||||
.then<void>((_) => exit(status));
|
||||
return Future.wait<void>([
|
||||
stdout.close(),
|
||||
stderr.close(),
|
||||
]).then<void>((_) => exit(status));
|
||||
}
|
||||
|
||||
+108
-63
@@ -62,7 +62,8 @@ class AotBuilder {
|
||||
List<String> args, {
|
||||
required String workingDirectory,
|
||||
Map<String, String>? environment,
|
||||
}) runProcess;
|
||||
})
|
||||
runProcess;
|
||||
|
||||
static Future<int> _defaultRun(
|
||||
String executable,
|
||||
@@ -81,10 +82,26 @@ class AotBuilder {
|
||||
}
|
||||
|
||||
String get _flutterBin => FlutterSdk(workspace).flutterBin;
|
||||
Directory get _hostEngine => Directory(p.join(workspace.flutterDir.path,
|
||||
'bin', 'cache', 'artifacts', 'engine', 'linux-x64'));
|
||||
Directory get _engineCommon => Directory(p.join(workspace.flutterDir.path,
|
||||
'bin', 'cache', 'artifacts', 'engine', 'common'));
|
||||
Directory get _hostEngine => Directory(
|
||||
p.join(
|
||||
workspace.flutterDir.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'linux-x64',
|
||||
),
|
||||
);
|
||||
Directory get _engineCommon => Directory(
|
||||
p.join(
|
||||
workspace.flutterDir.path,
|
||||
'bin',
|
||||
'cache',
|
||||
'artifacts',
|
||||
'engine',
|
||||
'common',
|
||||
),
|
||||
);
|
||||
String get _dartSdkBin =>
|
||||
p.join(workspace.flutterDir.path, 'bin', 'cache', 'dart-sdk', 'bin');
|
||||
|
||||
@@ -102,11 +119,11 @@ class AotBuilder {
|
||||
'profile' => '--profile',
|
||||
_ => '--release',
|
||||
};
|
||||
final code = await runProcess(
|
||||
_flutterBin,
|
||||
['build', 'bundle', flag],
|
||||
workingDirectory: p.absolute(appPath),
|
||||
);
|
||||
final code = await runProcess(_flutterBin, [
|
||||
'build',
|
||||
'bundle',
|
||||
flag,
|
||||
], workingDirectory: p.absolute(appPath));
|
||||
return code == 0;
|
||||
}
|
||||
|
||||
@@ -132,32 +149,39 @@ class AotBuilder {
|
||||
]);
|
||||
}
|
||||
|
||||
final newScheme = File(p.join(_hostEngine.path,
|
||||
'frontend_server_aot.dart.snapshot'))
|
||||
.existsSync();
|
||||
final newScheme = File(
|
||||
p.join(_hostEngine.path, 'frontend_server_aot.dart.snapshot'),
|
||||
).existsSync();
|
||||
final targetArch = arch ?? host.machineArch;
|
||||
final gen = genSnapshot ?? await _resolveGenSnapshot(targetArch, modes);
|
||||
|
||||
final results = <AotModeResult>[];
|
||||
for (final mode in modes) {
|
||||
onStep?.call('[$mode] flutter build bundle');
|
||||
if (await runProcess(_flutterBin, ['build', 'bundle'],
|
||||
workingDirectory: app) !=
|
||||
if (await runProcess(_flutterBin, [
|
||||
'build',
|
||||
'bundle',
|
||||
], workingDirectory: app) !=
|
||||
0) {
|
||||
results.add(AotModeResult(
|
||||
mode: mode,
|
||||
success: false,
|
||||
message: 'flutter build bundle failed',
|
||||
));
|
||||
results.add(
|
||||
AotModeResult(
|
||||
mode: mode,
|
||||
success: false,
|
||||
message: 'flutter build bundle failed',
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
final buildDir = _firstBuildDir(app);
|
||||
if (buildDir == null) {
|
||||
results.add(AotModeResult(
|
||||
results.add(
|
||||
AotModeResult(
|
||||
mode: mode,
|
||||
success: false,
|
||||
message: 'No .dart_tool/flutter_build/<hash> dir found'));
|
||||
message: 'No .dart_tool/flutter_build/<hash> dir found',
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -170,44 +194,51 @@ class AotBuilder {
|
||||
newScheme: newScheme,
|
||||
);
|
||||
if (kernelOk != 0) {
|
||||
results.add(AotModeResult(
|
||||
mode: mode, success: false, message: 'kernel snapshot failed'));
|
||||
results.add(
|
||||
AotModeResult(
|
||||
mode: mode,
|
||||
success: false,
|
||||
message: 'kernel snapshot failed',
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
onStep?.call('[$mode] gen_snapshot app-aot-elf');
|
||||
if (gen == null) {
|
||||
final token = EngineArtifacts.engineArch(targetArch);
|
||||
results.add(AotModeResult(
|
||||
results.add(
|
||||
AotModeResult(
|
||||
mode: mode,
|
||||
success: false,
|
||||
message: 'No $token gen_snapshot for engine '
|
||||
message:
|
||||
'No $token gen_snapshot for engine '
|
||||
'${workspace.engineCommit() ?? "<unknown>"} — run '
|
||||
'`emb engine --arch $targetArch` (its gen_snapshot must come '
|
||||
'from the same engine as the SDK frontend_server)'));
|
||||
'from the same engine as the SDK frontend_server)',
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
final out = 'libapp.so.$mode';
|
||||
final (genExe, genLead) = _genSnapshotInvocation(gen);
|
||||
final genCode = await runProcess(
|
||||
genExe,
|
||||
[
|
||||
...genLead,
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$out',
|
||||
'--strip',
|
||||
'--obfuscate',
|
||||
p.join(buildDir, 'app.dill'),
|
||||
],
|
||||
workingDirectory: app,
|
||||
final genCode = await runProcess(genExe, [
|
||||
...genLead,
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=$out',
|
||||
'--strip',
|
||||
'--obfuscate',
|
||||
p.join(buildDir, 'app.dill'),
|
||||
], workingDirectory: app);
|
||||
results.add(
|
||||
AotModeResult(
|
||||
mode: mode,
|
||||
success: genCode == 0,
|
||||
output: genCode == 0 ? p.join(app, out) : null,
|
||||
message: genCode == 0 ? null : 'gen_snapshot failed',
|
||||
),
|
||||
);
|
||||
results.add(AotModeResult(
|
||||
mode: mode,
|
||||
success: genCode == 0,
|
||||
output: genCode == 0 ? p.join(app, out) : null,
|
||||
message: genCode == 0 ? null : 'gen_snapshot failed',
|
||||
));
|
||||
}
|
||||
return AotResult(results);
|
||||
}
|
||||
@@ -228,12 +259,16 @@ class AotBuilder {
|
||||
? 'frontend_server_aot.dart.snapshot'
|
||||
: 'frontend_server.dart.snapshot',
|
||||
);
|
||||
final depfile = p.join(buildDir,
|
||||
newScheme ? 'kernel_snapshot_program.d' : 'kernel_snapshot.d');
|
||||
final depfile = p.join(
|
||||
buildDir,
|
||||
newScheme ? 'kernel_snapshot_program.d' : 'kernel_snapshot.d',
|
||||
);
|
||||
|
||||
final isRelease = mode == 'release';
|
||||
var patched = p.join(_engineCommon.path,
|
||||
isRelease ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
|
||||
var patched = p.join(
|
||||
_engineCommon.path,
|
||||
isRelease ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk',
|
||||
);
|
||||
if (!Directory(patched).existsSync()) {
|
||||
patched = p.join(_engineCommon.path, 'flutter_patched_sdk');
|
||||
}
|
||||
@@ -241,7 +276,8 @@ class AotBuilder {
|
||||
final args = <String>[
|
||||
'--disable-dart-dev',
|
||||
frontend,
|
||||
'--sdk-root', '$patched/',
|
||||
'--sdk-root',
|
||||
'$patched/',
|
||||
'--target=flutter',
|
||||
'--no-print-incremental-dependencies',
|
||||
'-Ddart.vm.profile=${mode == "profile"}',
|
||||
@@ -251,10 +287,14 @@ class AotBuilder {
|
||||
if (mode == 'profile') '--track-widget-creation',
|
||||
'--aot',
|
||||
'--tfa',
|
||||
'--target-os', 'linux',
|
||||
'--packages', p.join(app, '.dart_tool', 'package_config.json'),
|
||||
'--output-dill', p.join(buildDir, 'app.dill'),
|
||||
'--depfile', depfile,
|
||||
'--target-os',
|
||||
'linux',
|
||||
'--packages',
|
||||
p.join(app, '.dart_tool', 'package_config.json'),
|
||||
'--output-dill',
|
||||
p.join(buildDir, 'app.dill'),
|
||||
'--depfile',
|
||||
depfile,
|
||||
..._sourceFlags(app),
|
||||
..._nativeAssets(buildDir),
|
||||
'--verbosity=error',
|
||||
@@ -265,12 +305,15 @@ class AotBuilder {
|
||||
|
||||
/// Optional dart_plugin_registrant source flags (mirrors create_aot.py).
|
||||
List<String> _sourceFlags(String app) {
|
||||
final reg = File(p.join(
|
||||
app, '.dart_tool', 'flutter_build', 'dart_plugin_registrant.dart'));
|
||||
final reg = File(
|
||||
p.join(app, '.dart_tool', 'flutter_build', 'dart_plugin_registrant.dart'),
|
||||
);
|
||||
if (!reg.existsSync()) return const [];
|
||||
return [
|
||||
'--source', 'file://${reg.path}',
|
||||
'--source', 'package:flutter/src/dart_plugin_registrant.dart',
|
||||
'--source',
|
||||
'file://${reg.path}',
|
||||
'--source',
|
||||
'package:flutter/src/dart_plugin_registrant.dart',
|
||||
'-Dflutter.dart_plugin_registrant=file://${reg.path}',
|
||||
];
|
||||
}
|
||||
@@ -301,11 +344,13 @@ class AotBuilder {
|
||||
final commit = workspace.engineCommit();
|
||||
if (commit != null) {
|
||||
for (final mode in [...modes, 'release', 'profile', 'debug']) {
|
||||
final dir = Directory(p.join(
|
||||
workspace.platformDir('flutter-engine').path,
|
||||
commit,
|
||||
'engine-sdk-$mode-$targetToken',
|
||||
));
|
||||
final dir = Directory(
|
||||
p.join(
|
||||
workspace.platformDir('flutter-engine').path,
|
||||
commit,
|
||||
'engine-sdk-$mode-$targetToken',
|
||||
),
|
||||
);
|
||||
if (!dir.existsSync()) continue;
|
||||
for (final e in dir.listSync(recursive: true, followLinks: false)) {
|
||||
if (e is! File || p.basename(e.path) != 'gen_snapshot') continue;
|
||||
|
||||
@@ -43,10 +43,12 @@ class BundleBuilder {
|
||||
final Workspace workspace;
|
||||
|
||||
/// The engine bundle directory staged by `emb engine` for [mode]/[arch].
|
||||
Directory engineBundleDir(String mode, String arch) => Directory(p.join(
|
||||
workspace.platformDir('flutter-engine').path,
|
||||
'bundle-$mode-${EngineArtifacts.engineArch(arch)}',
|
||||
));
|
||||
Directory engineBundleDir(String mode, String arch) => Directory(
|
||||
p.join(
|
||||
workspace.platformDir('flutter-engine').path,
|
||||
'bundle-$mode-${EngineArtifacts.engineArch(arch)}',
|
||||
),
|
||||
);
|
||||
|
||||
/// Assemble the bundle for the app at [appPath] into [outputDir].
|
||||
BundleResult assemble({
|
||||
@@ -63,16 +65,16 @@ class BundleBuilder {
|
||||
final libapp = File(p.join(app, 'libapp.so.$mode'));
|
||||
final engineDir = engineBundleDir(mode, arch);
|
||||
final icu = File(p.join(engineDir.path, 'data', 'icudtl.dat'));
|
||||
final engineSo =
|
||||
File(p.join(engineDir.path, 'lib', 'libflutter_engine.so'));
|
||||
final engineSo = File(
|
||||
p.join(engineDir.path, 'lib', 'libflutter_engine.so'),
|
||||
);
|
||||
|
||||
final missing = <String>[
|
||||
if (!assets.existsSync())
|
||||
'flutter_assets — run `emb bundle --build` (or flutter build bundle)',
|
||||
if (!isDebug && !libapp.existsSync())
|
||||
'libapp.so.$mode — run `emb aot --mode $mode`',
|
||||
if (!icu.existsSync())
|
||||
'icudtl.dat — run `emb engine --arch $arch`',
|
||||
if (!icu.existsSync()) 'icudtl.dat — run `emb engine --arch $arch`',
|
||||
if (!engineSo.existsSync())
|
||||
'libflutter_engine.so — run `emb engine --arch $arch`',
|
||||
];
|
||||
|
||||
@@ -19,12 +19,10 @@ const description = 'Flutter Embedder CLI Tool';
|
||||
/// {@endtemplate}
|
||||
class EmbCliCommandRunner extends CompletionCommandRunner<int> {
|
||||
/// {@macro emb_cli_command_runner}
|
||||
EmbCliCommandRunner({
|
||||
Logger? logger,
|
||||
PubUpdater? pubUpdater,
|
||||
}) : _logger = logger ?? Logger(),
|
||||
_pubUpdater = pubUpdater ?? PubUpdater(),
|
||||
super(executableName, description) {
|
||||
EmbCliCommandRunner({Logger? logger, PubUpdater? pubUpdater})
|
||||
: _logger = logger ?? Logger(),
|
||||
_pubUpdater = pubUpdater ?? PubUpdater(),
|
||||
super(executableName, description) {
|
||||
// Add root options and flags
|
||||
argParser
|
||||
..addFlag(
|
||||
@@ -142,11 +140,9 @@ class EmbCliCommandRunner extends CompletionCommandRunner<int> {
|
||||
if (!isUpToDate) {
|
||||
_logger
|
||||
..info('')
|
||||
..info(
|
||||
'''
|
||||
..info('''
|
||||
${lightYellow.wrap('Update available!')} ${lightCyan.wrap(packageVersion)} \u2192 ${lightCyan.wrap(latestVersion)}
|
||||
Run ${lightCyan.wrap('$executableName update')} to update''',
|
||||
);
|
||||
Run ${lightCyan.wrap('$executableName update')} to update''');
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@ class AotCommand extends Command<int> {
|
||||
required Logger logger,
|
||||
HostInfo? host,
|
||||
AotBuilder Function(Workspace ws, HostInfo host, String? glibcSysroot)?
|
||||
builderFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_builderFactory = builderFactory ??
|
||||
((ws, host, sysroot) =>
|
||||
AotBuilder(ws, host: host, glibcSysroot: sysroot)) {
|
||||
builderFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_builderFactory =
|
||||
builderFactory ??
|
||||
((ws, host, sysroot) =>
|
||||
AotBuilder(ws, host: host, glibcSysroot: sysroot)) {
|
||||
argParser
|
||||
..addOption(
|
||||
'app-path',
|
||||
@@ -43,7 +44,8 @@ class AotCommand extends Command<int> {
|
||||
)
|
||||
..addOption(
|
||||
'arch',
|
||||
help: 'Target arch for the engine gen_snapshot (defaults to host). '
|
||||
help:
|
||||
'Target arch for the engine gen_snapshot (defaults to host). '
|
||||
'Use e.g. arm64 to cross-build for a Raspberry Pi.',
|
||||
)
|
||||
..addOption(
|
||||
@@ -52,7 +54,8 @@ class AotCommand extends Command<int> {
|
||||
)
|
||||
..addOption(
|
||||
'glibc-sysroot',
|
||||
help: 'Directory with ld-linux + libc to run gen_snapshot under '
|
||||
help:
|
||||
'Directory with ld-linux + libc to run gen_snapshot under '
|
||||
"(defaults to the artifact's bundled clang_x64/lib64).",
|
||||
);
|
||||
}
|
||||
@@ -60,7 +63,7 @@ class AotCommand extends Command<int> {
|
||||
final Logger _logger;
|
||||
final HostInfo? _host;
|
||||
final AotBuilder Function(Workspace ws, HostInfo host, String? glibcSysroot)
|
||||
_builderFactory;
|
||||
_builderFactory;
|
||||
|
||||
@override
|
||||
String get description =>
|
||||
@@ -82,8 +85,11 @@ class AotCommand extends Command<int> {
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
|
||||
final builder =
|
||||
_builderFactory(workspace, host, args['glibc-sysroot'] as String?);
|
||||
final builder = _builderFactory(
|
||||
workspace,
|
||||
host,
|
||||
args['glibc-sysroot'] as String?,
|
||||
);
|
||||
final result = await builder.build(
|
||||
appPath: appPath,
|
||||
modes: args['mode'] as List<String>,
|
||||
|
||||
@@ -25,13 +25,12 @@ class BuildCommand extends Command<int> {
|
||||
AotBuilder Function(Workspace ws, HostInfo host)? aotFactory,
|
||||
BundleBuilder Function(Workspace ws)? bundleFactory,
|
||||
EngineArtifacts Function(Workspace ws)? engineFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_aotFactory = aotFactory ??
|
||||
((ws, host) => AotBuilder(ws, host: host)),
|
||||
_bundleFactory = bundleFactory ?? BundleBuilder.new,
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_aotFactory = aotFactory ?? ((ws, host) => AotBuilder(ws, host: host)),
|
||||
_bundleFactory = bundleFactory ?? BundleBuilder.new,
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
argParser
|
||||
..addOption(
|
||||
'workspace',
|
||||
@@ -74,8 +73,10 @@ class BuildCommand extends Command<int> {
|
||||
final args = argResults!;
|
||||
final rest = args.rest;
|
||||
if (rest.isEmpty) {
|
||||
_logger.err('Usage: emb build <package-dir> '
|
||||
'(a dir with emb.yaml or pubspec.yaml emb:)');
|
||||
_logger.err(
|
||||
'Usage: emb build <package-dir> '
|
||||
'(a dir with emb.yaml or pubspec.yaml emb:)',
|
||||
);
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
final host = _host ?? HostInfo.detect();
|
||||
@@ -84,8 +85,10 @@ class BuildCommand extends Command<int> {
|
||||
final pkgDir = Directory(rest.first);
|
||||
final manifest = _loader.loadPackageDir(pkgDir);
|
||||
if (manifest == null) {
|
||||
_logger.err('No emb manifest in ${pkgDir.path} '
|
||||
'(expected emb.yaml or an emb: key in pubspec.yaml).');
|
||||
_logger.err(
|
||||
'No emb manifest in ${pkgDir.path} '
|
||||
'(expected emb.yaml or an emb: key in pubspec.yaml).',
|
||||
);
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
final build = manifest.build;
|
||||
@@ -96,8 +99,9 @@ class BuildCommand extends Command<int> {
|
||||
|
||||
// Resolve the matrix: CLI overrides win, else the manifest, else defaults.
|
||||
final appPath = p.normalize(p.join(pkgDir.absolute.path, build.appPath));
|
||||
final archs = (args['arch'] as List<String>)
|
||||
.ifEmpty(build.archs.isEmpty ? [host.machineArch] : build.archs);
|
||||
final archs = (args['arch'] as List<String>).ifEmpty(
|
||||
build.archs.isEmpty ? [host.machineArch] : build.archs,
|
||||
);
|
||||
final modes = (args['mode'] as List<String>).ifEmpty(build.modes);
|
||||
|
||||
if (!Directory(appPath).existsSync()) {
|
||||
@@ -105,15 +109,22 @@ class BuildCommand extends Command<int> {
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
|
||||
_logger.info(styleBold.wrap('Building ${manifest.id}: '
|
||||
'archs=${archs.join(",")} modes=${modes.join(",")}'));
|
||||
_logger.info(
|
||||
styleBold.wrap(
|
||||
'Building ${manifest.id}: '
|
||||
'archs=${archs.join(",")} modes=${modes.join(",")}',
|
||||
),
|
||||
);
|
||||
|
||||
var failures = 0;
|
||||
for (final arch in archs) {
|
||||
for (final mode in modes) {
|
||||
final out = build.output != null
|
||||
? p.join(workspace.root.path, build.output,
|
||||
'${manifest.id}-$mode-${EngineArtifacts.engineArch(arch)}')
|
||||
? p.join(
|
||||
workspace.root.path,
|
||||
build.output,
|
||||
'${manifest.id}-$mode-${EngineArtifacts.engineArch(arch)}',
|
||||
)
|
||||
: defaultBundleOutput(workspace, appPath, mode, arch);
|
||||
|
||||
final progress = _logger.progress('$mode/$arch');
|
||||
|
||||
@@ -21,11 +21,10 @@ class BundleCommand extends Command<int> {
|
||||
HostInfo? host,
|
||||
BundleBuilder Function(Workspace ws)? bundleFactory,
|
||||
AotBuilder Function(Workspace ws, HostInfo host)? aotFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_bundleFactory = bundleFactory ?? BundleBuilder.new,
|
||||
_aotFactory =
|
||||
aotFactory ?? ((ws, host) => AotBuilder(ws, host: host)) {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_bundleFactory = bundleFactory ?? BundleBuilder.new,
|
||||
_aotFactory = aotFactory ?? ((ws, host) => AotBuilder(ws, host: host)) {
|
||||
argParser
|
||||
..addOption(
|
||||
'app-path',
|
||||
@@ -53,7 +52,8 @@ class BundleCommand extends Command<int> {
|
||||
'output',
|
||||
abbr: 'o',
|
||||
aliases: ['out'],
|
||||
help: 'Output bundle directory, any path (defaults under the '
|
||||
help:
|
||||
'Output bundle directory, any path (defaults under the '
|
||||
'workspace).',
|
||||
)
|
||||
..addFlag(
|
||||
@@ -89,7 +89,8 @@ class BundleCommand extends Command<int> {
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
|
||||
final output = (args['output'] as String?) ??
|
||||
final output =
|
||||
(args['output'] as String?) ??
|
||||
defaultBundleOutput(workspace, appPath, mode, arch);
|
||||
|
||||
final progress = _logger.progress('Bundle $mode/$arch');
|
||||
|
||||
@@ -19,10 +19,10 @@ class DepsCommand extends Command<int> {
|
||||
HostInfo? host,
|
||||
HostProvisioner Function(HostInfo host)? provisionerFactory,
|
||||
ManifestLoader loader = const ManifestLoader(),
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost {
|
||||
argParser
|
||||
..addMultiOption(
|
||||
'config',
|
||||
@@ -33,7 +33,8 @@ class DepsCommand extends Command<int> {
|
||||
..addMultiOption(
|
||||
'packages',
|
||||
abbr: 'p',
|
||||
help: 'Directory to discover self-describing emb manifests '
|
||||
help:
|
||||
'Directory to discover self-describing emb manifests '
|
||||
'(repeatable).',
|
||||
)
|
||||
..addFlag(
|
||||
@@ -76,8 +77,10 @@ class DepsCommand extends Command<int> {
|
||||
}
|
||||
|
||||
if (manifests.isEmpty) {
|
||||
_logger.warn('No manifests found. '
|
||||
'Pass --config <dir> and/or --packages <dir>.');
|
||||
_logger.warn(
|
||||
'No manifests found. '
|
||||
'Pass --config <dir> and/or --packages <dir>.',
|
||||
);
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
@@ -86,11 +89,15 @@ class DepsCommand extends Command<int> {
|
||||
final coalesced = resolver.coalesce(manifests);
|
||||
|
||||
_logger
|
||||
..info('Host: ${host.os.name}/${host.machineArch} '
|
||||
'(${host.hostType} ${host.versionId})')
|
||||
..info('Manifests: ${manifests.length}, '
|
||||
'contributing: ${coalesced.byComponent.length}, '
|
||||
'skipped: ${coalesced.skipped.length}')
|
||||
..info(
|
||||
'Host: ${host.os.name}/${host.machineArch} '
|
||||
'(${host.hostType} ${host.versionId})',
|
||||
)
|
||||
..info(
|
||||
'Manifests: ${manifests.length}, '
|
||||
'contributing: ${coalesced.byComponent.length}, '
|
||||
'skipped: ${coalesced.skipped.length}',
|
||||
)
|
||||
..info('Coalesced packages: ${coalesced.packages.length}')
|
||||
..detail('Cache key: ${coalesced.contentHash}');
|
||||
|
||||
@@ -113,21 +120,30 @@ class DepsCommand extends Command<int> {
|
||||
plan.additional.isEmpty &&
|
||||
plan.unresolved.isEmpty) {
|
||||
_logger.info(
|
||||
lightGreen.wrap('All ${coalesced.packages.length} dependencies '
|
||||
'already satisfied.'));
|
||||
lightGreen.wrap(
|
||||
'All ${coalesced.packages.length} dependencies '
|
||||
'already satisfied.',
|
||||
),
|
||||
);
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
if (plan.toInstall.isNotEmpty) {
|
||||
_logger.info('Would install (${plan.toInstall.length}): '
|
||||
'${plan.toInstall.join(", ")}');
|
||||
_logger.info(
|
||||
'Would install (${plan.toInstall.length}): '
|
||||
'${plan.toInstall.join(", ")}',
|
||||
);
|
||||
}
|
||||
if (plan.additional.isNotEmpty) {
|
||||
_logger.info('Additional deps (${plan.additional.length}): '
|
||||
'${plan.additional.join(", ")}');
|
||||
_logger.info(
|
||||
'Additional deps (${plan.additional.length}): '
|
||||
'${plan.additional.join(", ")}',
|
||||
);
|
||||
}
|
||||
if (plan.unresolved.isNotEmpty) {
|
||||
_logger.warn('Unresolved (${plan.unresolved.length}): '
|
||||
'${plan.unresolved.join(", ")}');
|
||||
_logger.warn(
|
||||
'Unresolved (${plan.unresolved.length}): '
|
||||
'${plan.unresolved.join(", ")}',
|
||||
);
|
||||
}
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
@@ -135,14 +151,19 @@ class DepsCommand extends Command<int> {
|
||||
// ── Filter ──────────────────────────────────────────────────────────
|
||||
final filtered = await resolver.filter(coalesced, provisioner);
|
||||
if (filtered.isSatisfied) {
|
||||
_logger.info(lightGreen
|
||||
.wrap('All ${coalesced.packages.length} dependencies already '
|
||||
'satisfied.'));
|
||||
_logger.info(
|
||||
lightGreen.wrap(
|
||||
'All ${coalesced.packages.length} dependencies already '
|
||||
'satisfied.',
|
||||
),
|
||||
);
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
_logger.info('Missing (${filtered.missing.length}): '
|
||||
'${filtered.missing.join(", ")}');
|
||||
_logger.info(
|
||||
'Missing (${filtered.missing.length}): '
|
||||
'${filtered.missing.join(", ")}',
|
||||
);
|
||||
|
||||
if (!(args['yes'] as bool)) {
|
||||
final proceed = _logger.confirm(
|
||||
@@ -156,8 +177,9 @@ class DepsCommand extends Command<int> {
|
||||
}
|
||||
|
||||
// ── Install (single transaction) ────────────────────────────────────
|
||||
final progress =
|
||||
_logger.progress('Installing ${filtered.missing.length} package(s)');
|
||||
final progress = _logger.progress(
|
||||
'Installing ${filtered.missing.length} package(s)',
|
||||
);
|
||||
final result = await provisioner.install(
|
||||
filtered.missing.toSet(),
|
||||
onProgress: (p) => progress.update(
|
||||
|
||||
@@ -13,9 +13,9 @@ class DoctorCommand extends Command<int> {
|
||||
required Logger logger,
|
||||
HostInfo? host,
|
||||
HostProvisioner Function(HostInfo host)? provisionerFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost;
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost;
|
||||
|
||||
final Logger _logger;
|
||||
final HostInfo? _host;
|
||||
@@ -35,8 +35,10 @@ class DoctorCommand extends Command<int> {
|
||||
_logger
|
||||
..info(styleBold.wrap('Host'))
|
||||
..info(' os: ${host.os.name}')
|
||||
..info(' arch: ${host.machineArch} (flutter: ${host.flutterArch}, '
|
||||
'engine: ${EngineArtifacts.engineArchForHost(host)})')
|
||||
..info(
|
||||
' arch: ${host.machineArch} (flutter: ${host.flutterArch}, '
|
||||
'engine: ${EngineArtifacts.engineArchForHost(host)})',
|
||||
)
|
||||
..info(' host type: ${host.hostType}')
|
||||
..info(' version: ${host.versionId}');
|
||||
if (host.prettyName != null) {
|
||||
|
||||
@@ -18,9 +18,9 @@ class EngineCommand extends Command<int> {
|
||||
required Logger logger,
|
||||
HostInfo? host,
|
||||
EngineArtifacts Function(Workspace ws)? engineFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
argParser
|
||||
..addOption(
|
||||
'workspace',
|
||||
@@ -29,7 +29,8 @@ class EngineCommand extends Command<int> {
|
||||
)
|
||||
..addOption(
|
||||
'commit',
|
||||
help: 'Engine commit (defaults to '
|
||||
help:
|
||||
'Engine commit (defaults to '
|
||||
'<workspace>/flutter/bin/internal/engine.version).',
|
||||
)
|
||||
..addOption(
|
||||
@@ -39,7 +40,8 @@ class EngineCommand extends Command<int> {
|
||||
..addMultiOption(
|
||||
'mode',
|
||||
abbr: 'm',
|
||||
help: 'Runtime modes to fetch (others are auto-fetched on demand by '
|
||||
help:
|
||||
'Runtime modes to fetch (others are auto-fetched on demand by '
|
||||
'`emb bundle`/`build`).',
|
||||
allowed: engineRuntimeModes,
|
||||
defaultsTo: const ['release'],
|
||||
@@ -73,12 +75,13 @@ class EngineCommand extends Command<int> {
|
||||
final host = _host ?? HostInfo.detect();
|
||||
final workspace = Workspace.resolve(override: args['workspace'] as String?);
|
||||
|
||||
final commit =
|
||||
(args['commit'] as String?) ?? workspace.engineCommit();
|
||||
final commit = (args['commit'] as String?) ?? workspace.engineCommit();
|
||||
if (commit == null || commit.isEmpty) {
|
||||
_logger.err('Could not determine the engine commit. '
|
||||
'Provide --commit or ensure '
|
||||
'${workspace.flutterDir.path}/bin/internal/engine.version exists.');
|
||||
_logger.err(
|
||||
'Could not determine the engine commit. '
|
||||
'Provide --commit or ensure '
|
||||
'${workspace.flutterDir.path}/bin/internal/engine.version exists.',
|
||||
);
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
// Determine the proper engine SDK arch token for this machine (or honor
|
||||
@@ -88,8 +91,10 @@ class EngineCommand extends Command<int> {
|
||||
);
|
||||
final modes = args['mode'] as List<String>;
|
||||
|
||||
_logger.info('Engine commit: $commit arch: $arch '
|
||||
'(host: ${host.machineArch}) modes: ${modes.join(", ")}');
|
||||
_logger.info(
|
||||
'Engine commit: $commit arch: $arch '
|
||||
'(host: ${host.machineArch}) modes: ${modes.join(", ")}',
|
||||
);
|
||||
|
||||
final engine = _engineFactory(workspace);
|
||||
var anyBuildNeeded = false;
|
||||
@@ -131,10 +136,12 @@ class EngineCommand extends Command<int> {
|
||||
if (anyBuildNeeded) {
|
||||
_logger
|
||||
..info('')
|
||||
..warn('One or more modes have no published prebuilt. '
|
||||
..warn(
|
||||
'One or more modes have no published prebuilt. '
|
||||
'Source-build (gclient + gn + autoninja) is not yet implemented in '
|
||||
'emb — run the legacy flutter_workspace.py engine build, or build '
|
||||
'from meta-flutter/flutter-engine, for now.');
|
||||
'from meta-flutter/flutter-engine, for now.',
|
||||
);
|
||||
return ExitCode.unavailable.code;
|
||||
}
|
||||
return ExitCode.success.code;
|
||||
|
||||
@@ -14,8 +14,8 @@ import 'package:path/path.dart' as p;
|
||||
class EnvCommand extends Command<int> {
|
||||
/// {@macro env_command}
|
||||
EnvCommand({required Logger logger, HostInfo? host})
|
||||
: _logger = logger,
|
||||
_host = host {
|
||||
: _logger = logger,
|
||||
_host = host {
|
||||
argParser
|
||||
..addOption(
|
||||
'workspace',
|
||||
@@ -61,7 +61,8 @@ class EnvCommand extends Command<int> {
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
final out = (args['output'] as String?) ??
|
||||
final out =
|
||||
(args['output'] as String?) ??
|
||||
p.join(workspace.root.path, 'setup_env.sh');
|
||||
File(out).writeAsStringSync(script);
|
||||
_logger
|
||||
|
||||
@@ -19,10 +19,9 @@ class FlutterCommand extends Command<int> {
|
||||
required Logger logger,
|
||||
HostInfo? host,
|
||||
FlutterSdk Function(Workspace ws, HostInfo host)? sdkFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_sdkFactory = sdkFactory ??
|
||||
((ws, host) => FlutterSdk(ws, host: host)) {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_sdkFactory = sdkFactory ?? ((ws, host) => FlutterSdk(ws, host: host)) {
|
||||
argParser
|
||||
..addOption(
|
||||
'workspace',
|
||||
@@ -31,7 +30,8 @@ class FlutterCommand extends Command<int> {
|
||||
)
|
||||
..addOption(
|
||||
'flutter-version',
|
||||
help: 'Flutter version/tag/branch to check out. Defaults to '
|
||||
help:
|
||||
'Flutter version/tag/branch to check out. Defaults to '
|
||||
"globals.json's flutter_version.",
|
||||
)
|
||||
..addMultiOption(
|
||||
@@ -42,7 +42,8 @@ class FlutterCommand extends Command<int> {
|
||||
)
|
||||
..addFlag(
|
||||
'configure',
|
||||
help: 'Run `flutter config` (desktop + custom devices) and '
|
||||
help:
|
||||
'Run `flutter config` (desktop + custom devices) and '
|
||||
'`flutter doctor` after install.',
|
||||
negatable: false,
|
||||
);
|
||||
@@ -53,8 +54,7 @@ class FlutterCommand extends Command<int> {
|
||||
final FlutterSdk Function(Workspace ws, HostInfo host) _sdkFactory;
|
||||
|
||||
@override
|
||||
String get description =>
|
||||
'Install the Flutter SDK into <workspace>/flutter.';
|
||||
String get description => 'Install the Flutter SDK into <workspace>/flutter.';
|
||||
|
||||
@override
|
||||
String get name => 'flutter';
|
||||
@@ -65,18 +65,22 @@ class FlutterCommand extends Command<int> {
|
||||
final host = _host ?? HostInfo.detect();
|
||||
final workspace = Workspace.resolve(override: args['workspace'] as String?);
|
||||
|
||||
final version = (args['flutter-version'] as String?) ??
|
||||
final version =
|
||||
(args['flutter-version'] as String?) ??
|
||||
_versionFromGlobals(args['config'] as List<String>);
|
||||
if (version == null || version.isEmpty) {
|
||||
_logger.err('No Flutter version. Pass --flutter-version or provide a '
|
||||
'globals.json with "flutter_version" via --config.');
|
||||
_logger.err(
|
||||
'No Flutter version. Pass --flutter-version or provide a '
|
||||
'globals.json with "flutter_version" via --config.',
|
||||
);
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
|
||||
final sdk = _sdkFactory(workspace, host);
|
||||
final progress =
|
||||
_logger.progress('Installing Flutter SDK $version into '
|
||||
'${workspace.flutterDir.path}');
|
||||
final progress = _logger.progress(
|
||||
'Installing Flutter SDK $version into '
|
||||
'${workspace.flutterDir.path}',
|
||||
);
|
||||
final result = await sdk.install(version);
|
||||
if (!result.success) {
|
||||
progress.fail('Flutter SDK install failed');
|
||||
|
||||
@@ -30,40 +30,63 @@ class SetupCommand extends Command<int> {
|
||||
HostProvisioner Function(HostInfo host)? provisionerFactory,
|
||||
FlutterSdk Function(Workspace ws, HostInfo host)? sdkFactory,
|
||||
EngineArtifacts Function(Workspace ws)? engineFactory,
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost,
|
||||
_sdkFactory =
|
||||
sdkFactory ?? ((ws, host) => FlutterSdk(ws, host: host)),
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
}) : _logger = logger,
|
||||
_host = host,
|
||||
_loader = loader,
|
||||
_provisionerFactory = provisionerFactory ?? HostProvisioner.forHost,
|
||||
_sdkFactory = sdkFactory ?? ((ws, host) => FlutterSdk(ws, host: host)),
|
||||
_engineFactory = engineFactory ?? EngineArtifacts.new {
|
||||
argParser
|
||||
..addMultiOption('config',
|
||||
abbr: 'c',
|
||||
help: 'Legacy JSON config directory.',
|
||||
defaultsTo: const ['configs'])
|
||||
..addMultiOption('packages',
|
||||
abbr: 'p', help: 'Directory to discover self-describing manifests.')
|
||||
..addOption('workspace',
|
||||
abbr: 'w',
|
||||
help: r'Workspace root (defaults to $FLUTTER_WORKSPACE or cwd).')
|
||||
..addOption('flutter-version',
|
||||
help: "Flutter version (defaults to globals.json's flutter_version).")
|
||||
..addMultiOption(
|
||||
'config',
|
||||
abbr: 'c',
|
||||
help: 'Legacy JSON config directory.',
|
||||
defaultsTo: const ['configs'],
|
||||
)
|
||||
..addMultiOption(
|
||||
'packages',
|
||||
abbr: 'p',
|
||||
help: 'Directory to discover self-describing manifests.',
|
||||
)
|
||||
..addOption(
|
||||
'workspace',
|
||||
abbr: 'w',
|
||||
help: r'Workspace root (defaults to $FLUTTER_WORKSPACE or cwd).',
|
||||
)
|
||||
..addOption(
|
||||
'flutter-version',
|
||||
help: "Flutter version (defaults to globals.json's flutter_version).",
|
||||
)
|
||||
..addOption('arch', help: 'Engine arch (defaults to host).')
|
||||
..addMultiOption('mode',
|
||||
abbr: 'm',
|
||||
help: 'Engine runtime modes to prefetch.',
|
||||
allowed: engineRuntimeModes,
|
||||
defaultsTo: const ['release'])
|
||||
..addFlag('yes',
|
||||
abbr: 'y', help: 'Skip the deps confirmation.', negatable: false)
|
||||
..addFlag('skip-deps', help: 'Skip host dependency install.',
|
||||
negatable: false)
|
||||
..addMultiOption(
|
||||
'mode',
|
||||
abbr: 'm',
|
||||
help: 'Engine runtime modes to prefetch.',
|
||||
allowed: engineRuntimeModes,
|
||||
defaultsTo: const ['release'],
|
||||
)
|
||||
..addFlag(
|
||||
'yes',
|
||||
abbr: 'y',
|
||||
help: 'Skip the deps confirmation.',
|
||||
negatable: false,
|
||||
)
|
||||
..addFlag(
|
||||
'skip-deps',
|
||||
help: 'Skip host dependency install.',
|
||||
negatable: false,
|
||||
)
|
||||
..addFlag('skip-sync', help: 'Skip repository sync.', negatable: false)
|
||||
..addFlag('skip-flutter', help: 'Skip Flutter SDK install.',
|
||||
negatable: false)
|
||||
..addFlag('skip-engine', help: 'Skip engine artifact fetch.',
|
||||
negatable: false);
|
||||
..addFlag(
|
||||
'skip-flutter',
|
||||
help: 'Skip Flutter SDK install.',
|
||||
negatable: false,
|
||||
)
|
||||
..addFlag(
|
||||
'skip-engine',
|
||||
help: 'Skip engine artifact fetch.',
|
||||
negatable: false,
|
||||
);
|
||||
}
|
||||
|
||||
final Logger _logger;
|
||||
@@ -95,8 +118,12 @@ class SetupCommand extends Command<int> {
|
||||
manifests.addAll(_loader.discoverPackages(Directory(dir)));
|
||||
}
|
||||
|
||||
_logger.info(styleBold.wrap('emb setup → ${workspace.root.path} '
|
||||
'(${host.os.name}/${host.machineArch})'));
|
||||
_logger.info(
|
||||
styleBold.wrap(
|
||||
'emb setup → ${workspace.root.path} '
|
||||
'(${host.os.name}/${host.machineArch})',
|
||||
),
|
||||
);
|
||||
workspace.ensureAppDir();
|
||||
|
||||
if (!(args['skip-deps'] as bool)) {
|
||||
@@ -128,11 +155,13 @@ class SetupCommand extends Command<int> {
|
||||
|
||||
// Emit setup_env.sh so the workspace's Flutter/Dart are on PATH.
|
||||
final envFile = File(p.join(workspace.root.path, 'setup_env.sh'))
|
||||
..writeAsStringSync(generateSetupEnv(
|
||||
workspace: workspace,
|
||||
host: host,
|
||||
engineVersion: workspace.engineCommit(),
|
||||
));
|
||||
..writeAsStringSync(
|
||||
generateSetupEnv(
|
||||
workspace: workspace,
|
||||
host: host,
|
||||
engineVersion: workspace.engineCommit(),
|
||||
),
|
||||
);
|
||||
|
||||
_logger
|
||||
..info(lightGreen.wrap('emb setup complete.'))
|
||||
@@ -164,8 +193,10 @@ class SetupCommand extends Command<int> {
|
||||
}
|
||||
_logger.info(' Missing (${missing.length}): ${missing.join(", ")}');
|
||||
if (!yes &&
|
||||
!_logger.confirm(' Install ${missing.length} package(s)?',
|
||||
defaultValue: true)) {
|
||||
!_logger.confirm(
|
||||
' Install ${missing.length} package(s)?',
|
||||
defaultValue: true,
|
||||
)) {
|
||||
_logger.info(' Skipped.');
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
@@ -200,8 +231,10 @@ class SetupCommand extends Command<int> {
|
||||
final results = await const RepoSyncer().syncAll(
|
||||
repos,
|
||||
workspace.appDir,
|
||||
onResult: (r) => progress.update(' [${++done}/${repos.length}] '
|
||||
'${r.folderName}${r.success ? "" : " FAILED"}'),
|
||||
onResult: (r) => progress.update(
|
||||
' [${++done}/${repos.length}] '
|
||||
'${r.folderName}${r.success ? "" : " FAILED"}',
|
||||
),
|
||||
);
|
||||
final failed = results.where((r) => !r.success).toList();
|
||||
if (failed.isEmpty) {
|
||||
@@ -224,8 +257,10 @@ class SetupCommand extends Command<int> {
|
||||
_logger.info(styleBold.wrap('▸ Flutter SDK'));
|
||||
final resolved = version ?? _versionFromGlobals(configDirs);
|
||||
if (resolved == null || resolved.isEmpty) {
|
||||
_logger.err(' No Flutter version: set --flutter-version or '
|
||||
'globals.json.');
|
||||
_logger.err(
|
||||
' No Flutter version: set --flutter-version or '
|
||||
'globals.json.',
|
||||
);
|
||||
return ExitCode.usage.code;
|
||||
}
|
||||
final progress = _logger.progress(' Installing Flutter SDK $resolved');
|
||||
@@ -236,8 +271,10 @@ class SetupCommand extends Command<int> {
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
final commit = result.engineCommit;
|
||||
progress.complete(' Flutter SDK $resolved'
|
||||
'${commit != null ? " (engine $commit)" : ""}');
|
||||
progress.complete(
|
||||
' Flutter SDK $resolved'
|
||||
'${commit != null ? " (engine $commit)" : ""}',
|
||||
);
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
@@ -259,8 +296,11 @@ class SetupCommand extends Command<int> {
|
||||
try {
|
||||
for (final mode in modes) {
|
||||
final progress = _logger.progress(' Engine $mode');
|
||||
final r =
|
||||
await engine.fetch(runtime: mode, arch: token, commit: commit);
|
||||
final r = await engine.fetch(
|
||||
runtime: mode,
|
||||
arch: token,
|
||||
commit: commit,
|
||||
);
|
||||
switch (r.status) {
|
||||
case EngineFetchStatus.fetched:
|
||||
case EngineFetchStatus.upToDate:
|
||||
|
||||
@@ -20,8 +20,8 @@ class SyncCommand extends Command<int> {
|
||||
SyncCommand({
|
||||
required Logger logger,
|
||||
ManifestLoader loader = const ManifestLoader(),
|
||||
}) : _logger = logger,
|
||||
_loader = loader {
|
||||
}) : _logger = logger,
|
||||
_loader = loader {
|
||||
argParser
|
||||
..addMultiOption(
|
||||
'config',
|
||||
@@ -36,7 +36,8 @@ class SyncCommand extends Command<int> {
|
||||
)
|
||||
..addMultiOption(
|
||||
'repos',
|
||||
help: 'A JSON file containing a bare array of repo entries '
|
||||
help:
|
||||
'A JSON file containing a bare array of repo entries '
|
||||
'(repeatable).',
|
||||
)
|
||||
..addOption(
|
||||
@@ -65,8 +66,7 @@ class SyncCommand extends Command<int> {
|
||||
@override
|
||||
Future<int> run() async {
|
||||
final args = argResults!;
|
||||
final workspace =
|
||||
Workspace.resolve(override: args['workspace'] as String?);
|
||||
final workspace = Workspace.resolve(override: args['workspace'] as String?);
|
||||
|
||||
// Collect repos from manifests' `src` lists.
|
||||
final manifests = <EmbManifest>[];
|
||||
@@ -95,13 +95,14 @@ class SyncCommand extends Command<int> {
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
final concurrency =
|
||||
int.tryParse(args['concurrency'] as String) ?? 4;
|
||||
final concurrency = int.tryParse(args['concurrency'] as String) ?? 4;
|
||||
final appDir = workspace.appDir;
|
||||
_logger
|
||||
..info('Workspace: ${workspace.root.path}')
|
||||
..info('Syncing ${unique.length} repo(s) into ${appDir.path} '
|
||||
'(concurrency: $concurrency)');
|
||||
..info(
|
||||
'Syncing ${unique.length} repo(s) into ${appDir.path} '
|
||||
'(concurrency: $concurrency)',
|
||||
);
|
||||
|
||||
final progress = _logger.progress('Syncing repositories');
|
||||
var done = 0;
|
||||
@@ -110,8 +111,10 @@ class SyncCommand extends Command<int> {
|
||||
appDir,
|
||||
onResult: (r) {
|
||||
done++;
|
||||
progress.update('[$done/${unique.length}] ${r.folderName}'
|
||||
'${r.success ? "" : " FAILED"}');
|
||||
progress.update(
|
||||
'[$done/${unique.length}] ${r.folderName}'
|
||||
'${r.success ? "" : " FAILED"}',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -11,11 +11,9 @@ import 'package:pub_updater/pub_updater.dart';
|
||||
/// {@endtemplate}
|
||||
class UpdateCommand extends Command<int> {
|
||||
/// {@macro update_command}
|
||||
UpdateCommand({
|
||||
required Logger logger,
|
||||
PubUpdater? pubUpdater,
|
||||
}) : _logger = logger,
|
||||
_pubUpdater = pubUpdater ?? PubUpdater();
|
||||
UpdateCommand({required Logger logger, PubUpdater? pubUpdater})
|
||||
: _logger = logger,
|
||||
_pubUpdater = pubUpdater ?? PubUpdater();
|
||||
|
||||
final Logger _logger;
|
||||
final PubUpdater _pubUpdater;
|
||||
|
||||
@@ -55,7 +55,7 @@ class EngineFetchResult {
|
||||
/// layout.
|
||||
class EngineArtifacts {
|
||||
EngineArtifacts(this.workspace, {HttpClient? httpClient})
|
||||
: _http = httpClient ?? HttpClient();
|
||||
: _http = httpClient ?? HttpClient();
|
||||
|
||||
final Workspace workspace;
|
||||
final HttpClient _http;
|
||||
@@ -132,8 +132,9 @@ class EngineArtifacts {
|
||||
..createSync(recursive: true);
|
||||
final archiveFile = File(p.join(cwdEngine.path, filename));
|
||||
final sha256File = File('${archiveFile.path}.sha256');
|
||||
final bundleDir =
|
||||
Directory(p.join(engineDir.path, 'bundle-$runtime-$arch'));
|
||||
final bundleDir = Directory(
|
||||
p.join(engineDir.path, 'bundle-$runtime-$arch'),
|
||||
);
|
||||
|
||||
// Download unless a verified copy already exists.
|
||||
if (!_sha256Matches(archiveFile, sha256File)) {
|
||||
@@ -160,12 +161,14 @@ class EngineArtifacts {
|
||||
|
||||
// Extract.
|
||||
final restoreDir = Directory(
|
||||
p.join(cwdEngine.path, 'engine-sdk-$runtime-$arch'))
|
||||
..createSync(recursive: true);
|
||||
final tar = await Process.run(
|
||||
'tar',
|
||||
['-xzf', archiveFile.path, '-C', restoreDir.path],
|
||||
);
|
||||
p.join(cwdEngine.path, 'engine-sdk-$runtime-$arch'),
|
||||
)..createSync(recursive: true);
|
||||
final tar = await Process.run('tar', [
|
||||
'-xzf',
|
||||
archiveFile.path,
|
||||
'-C',
|
||||
restoreDir.path,
|
||||
]);
|
||||
if (tar.exitCode != 0) {
|
||||
return EngineFetchResult(
|
||||
runtime: runtime,
|
||||
|
||||
@@ -82,20 +82,20 @@ class FlutterSdk {
|
||||
'--enable-custom-devices',
|
||||
...switch (h.os) {
|
||||
HostOs.linux => [
|
||||
'--enable-linux-desktop',
|
||||
'--no-enable-macos-desktop',
|
||||
'--no-enable-windows-desktop',
|
||||
],
|
||||
'--enable-linux-desktop',
|
||||
'--no-enable-macos-desktop',
|
||||
'--no-enable-windows-desktop',
|
||||
],
|
||||
HostOs.macos => [
|
||||
'--enable-macos-desktop',
|
||||
'--no-enable-linux-desktop',
|
||||
'--no-enable-windows-desktop',
|
||||
],
|
||||
'--enable-macos-desktop',
|
||||
'--no-enable-linux-desktop',
|
||||
'--no-enable-windows-desktop',
|
||||
],
|
||||
HostOs.windows => [
|
||||
'--enable-windows-desktop',
|
||||
'--no-enable-linux-desktop',
|
||||
'--no-enable-macos-desktop',
|
||||
],
|
||||
'--enable-windows-desktop',
|
||||
'--no-enable-linux-desktop',
|
||||
'--no-enable-macos-desktop',
|
||||
],
|
||||
},
|
||||
];
|
||||
final config = await Process.run(flutterBin, args);
|
||||
|
||||
+13
-11
@@ -14,10 +14,10 @@ enum HostOs {
|
||||
/// non-Linux operating systems. On Linux the distro id is used instead
|
||||
/// (see [HostInfo.hostType]).
|
||||
String get configToken => switch (this) {
|
||||
HostOs.linux => 'linux',
|
||||
HostOs.macos => 'darwin',
|
||||
HostOs.windows => 'windows',
|
||||
};
|
||||
HostOs.linux => 'linux',
|
||||
HostOs.macos => 'darwin',
|
||||
HostOs.windows => 'windows',
|
||||
};
|
||||
}
|
||||
|
||||
/// Immutable description of the machine `emb` is executing on.
|
||||
@@ -102,11 +102,11 @@ class HostInfo {
|
||||
/// The Flutter/Google architecture token (`x64`, `arm64`, `aarch64`).
|
||||
/// Mirrors `get_flutter_arch`.
|
||||
String get flutterArch => switch (machineArch) {
|
||||
'x86_64' || 'AMD64' || 'x64' => 'x64',
|
||||
'arm64' || 'ARM64' => 'arm64',
|
||||
'aarch64' => 'arm64',
|
||||
_ => machineArch,
|
||||
};
|
||||
'x86_64' || 'AMD64' || 'x64' => 'x64',
|
||||
'arm64' || 'ARM64' => 'arm64',
|
||||
'aarch64' => 'arm64',
|
||||
_ => machineArch,
|
||||
};
|
||||
|
||||
/// Whether any of [archs] matches this host's architecture.
|
||||
bool supportsArch(Iterable<String> archs) =>
|
||||
@@ -122,7 +122,8 @@ class HostInfo {
|
||||
if (Platform.isMacOS) return HostOs.macos;
|
||||
if (Platform.isWindows) return HostOs.windows;
|
||||
throw UnsupportedError(
|
||||
'Unsupported host operating system: ${Platform.operatingSystem}');
|
||||
'Unsupported host operating system: ${Platform.operatingSystem}',
|
||||
);
|
||||
}
|
||||
|
||||
/// Map the FFI [Abi] to the raw machine string the config files use. This
|
||||
@@ -185,7 +186,8 @@ class HostInfo {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'HostInfo(os: ${os.name}, arch: $machineArch, '
|
||||
String toString() =>
|
||||
'HostInfo(os: ${os.name}, arch: $machineArch, '
|
||||
'hostType: $hostType, versionId: $versionId)';
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,7 @@ class EmbManifest {
|
||||
/// Parse a manifest map. Detects structured vs legacy host-dep schemas
|
||||
/// automatically, so both `emb` manifests and legacy `configs/*.json`
|
||||
/// documents flow through one path.
|
||||
factory EmbManifest.fromMap(
|
||||
Map<String, dynamic> map, {
|
||||
String? sourcePath,
|
||||
}) {
|
||||
factory EmbManifest.fromMap(Map<String, dynamic> map, {String? sourcePath}) {
|
||||
final deps = _parseDeps(map);
|
||||
final srcList = (map['src'] ?? map['repos']) as List<dynamic>? ?? const [];
|
||||
|
||||
@@ -41,10 +38,12 @@ class EmbManifest {
|
||||
id: (map['id'] ?? '') as String,
|
||||
type: (map['type'] ?? 'app') as String,
|
||||
load: (map['load'] ?? true) as bool,
|
||||
supportedArchs:
|
||||
_stringList(map['supported_archs'] ?? map['supportedArchs']),
|
||||
supportedArchs: _stringList(
|
||||
map['supported_archs'] ?? map['supportedArchs'],
|
||||
),
|
||||
supportedHostTypes: _stringList(
|
||||
map['supported_host_types'] ?? map['supportedHostTypes']),
|
||||
map['supported_host_types'] ?? map['supportedHostTypes'],
|
||||
),
|
||||
env: _stringMap(map['env']),
|
||||
src: srcList
|
||||
.whereType<Map<dynamic, dynamic>>()
|
||||
@@ -128,6 +127,7 @@ class EmbManifest {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'EmbManifest($id, type: $type, '
|
||||
String toString() =>
|
||||
'EmbManifest($id, type: $type, '
|
||||
'deps: ${deps.rules.length} rules)';
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ class DepRule {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => 'DepRule(${os.name}'
|
||||
String toString() =>
|
||||
'DepRule(${os.name}'
|
||||
'${hostType != null ? "/$hostType" : ""}'
|
||||
'${versionId != null ? "/$versionId" : ""}'
|
||||
'${arch != null ? "@$arch" : ""}: ${packages.join(" ")})';
|
||||
@@ -79,11 +80,13 @@ class HostDeps {
|
||||
for (final sub in value.entries) {
|
||||
final pkgs = sub.value;
|
||||
if (pkgs is List) {
|
||||
rules.add(DepRule(
|
||||
os: os,
|
||||
hostType: sub.key.toString().toLowerCase(),
|
||||
packages: _stringList(pkgs),
|
||||
));
|
||||
rules.add(
|
||||
DepRule(
|
||||
os: os,
|
||||
hostType: sub.key.toString().toLowerCase(),
|
||||
packages: _stringList(pkgs),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,8 +113,9 @@ class HostDeps {
|
||||
// Distro-level cmds apply to all versions of this distro+arch.
|
||||
final distroPkgs = _packagesFromCmds(distroMap['cmds']);
|
||||
if (distroPkgs.isNotEmpty) {
|
||||
rules.add(DepRule(
|
||||
os: os, arch: arch, hostType: distro, packages: distroPkgs));
|
||||
rules.add(
|
||||
DepRule(os: os, arch: arch, hostType: distro, packages: distroPkgs),
|
||||
);
|
||||
}
|
||||
|
||||
// Version-specific nested cmds (keys that are version ids).
|
||||
@@ -122,13 +126,15 @@ class HostDeps {
|
||||
if (versionMap is! Map) continue;
|
||||
final versionPkgs = _packagesFromCmds(versionMap['cmds']);
|
||||
if (versionPkgs.isNotEmpty) {
|
||||
rules.add(DepRule(
|
||||
os: os,
|
||||
arch: arch,
|
||||
hostType: distro,
|
||||
versionId: key,
|
||||
packages: versionPkgs,
|
||||
));
|
||||
rules.add(
|
||||
DepRule(
|
||||
os: os,
|
||||
arch: arch,
|
||||
hostType: distro,
|
||||
versionId: key,
|
||||
packages: versionPkgs,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user