resolveTargets method

Future<({int exitCode, List<LiveApp> targets})> resolveTargets(
  1. LiveOptions options
)

Resolves the apps a command runs on, printing why when there are none.

Returns the targets and the exit code to use when the list is empty.

Implementation

Future<({List<LiveApp> targets, int exitCode})> resolveTargets(
  LiveOptions options,
) async {
  final LiveSession? session = this.session;
  if (session != null) return session.resolve(options, output);

  final String? address = options.uri;
  if (address != null) {
    final Uri? uri = LiveDiscovery.normalizeVmServiceUri(address);
    if (uri == null) {
      _error(options, 'Not a VM service address: $address');
      return (targets: <LiveApp>[], exitCode: 1);
    }
    String packageName = 'app';
    try {
      packageName = project.packageName;
    } on LiveCommandException {
      // --uri works outside a project too.
    }
    try {
      final LiveApp app = await LiveApp.connect(
        uri,
        device: uri.hasPort ? '${uri.host}:${uri.port}' : uri.host,
        package: packageName,
        timeout: options.timeout,
      );
      return (targets: [app], exitCode: 0);
    } on LiveCommandException catch (e) {
      _error(options, e.message);
      return (targets: <LiveApp>[], exitCode: 1);
    }
  }

  final LiveDiscoveryResult discovered;
  try {
    discovered = await discover(options);
  } on LiveDiscoveryException catch (e) {
    _error(options, e.message);
    return (targets: <LiveApp>[], exitCode: 1);
  } on LiveCommandException catch (e) {
    _error(options, e.message);
    return (targets: <LiveApp>[], exitCode: 1);
  }

  final LiveTargetSelection<LiveApp> selection = selectLiveTargets(
    discovered.apps,
    deviceOf: (app) => app.device,
    device: options.device,
    all: options.all,
    packageName: project.packageName,
  );

  if (!selection.isSuccess) {
    if (options.json) {
      output.json({
        'error': selection.error,
        'apps': [
          for (final LiveApp app in selection.candidates)
            {'index': discovered.apps.indexOf(app) + 1, 'device': app.device},
        ],
      });
    } else {
      output.error(selection.error!);
      for (final LiveApp app in selection.candidates) {
        output.line('  ${discovered.apps.indexOf(app) + 1}  ${app.device}');
      }
      printSkipped(discovered.skipped);
    }
    await Future.wait(discovered.apps.map((app) => app.close()));
    return (targets: <LiveApp>[], exitCode: selection.exitCode);
  }

  await Future.wait(
    discovered.apps
        .where((app) => !selection.targets.contains(app))
        .map((app) => app.close()),
  );
  return (targets: selection.targets, exitCode: 0);
}