blob: 6e3ee983bbef4e63835075021febfbd1da2ce5d5 [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use anyhow::{anyhow, Context as _};
use fidl_fuchsia_dash as fdash;
use fuchsia_component::client::connect_to_protocol;
use futures::stream::StreamExt as _;
mod args;
pub async fn exec() -> anyhow::Result<()> {
let args: args::PackageArgs = argh::from_env();
match args.subcommand {
crate::args::PackageSubcommand::Explore(args) => {
// TODO(https://fxbug.dev/42177573): Verify that the optional Launcher protocol is
// available before connecting.
let dash_launcher = connect_to_protocol::<fdash::LauncherMarker>()?;
// TODO(https://fxbug.dev/42077838): Use Stdout::raw when a command is not provided.
let stdout = socket_to_stdio::Stdout::buffered();
#[allow(clippy::large_futures)]
explore_cmd(args, dash_launcher, stdout).await
}
}
}
async fn explore_cmd(
args: crate::args::ExploreArgs,
dash_launcher: fdash::LauncherProxy,
stdout: socket_to_stdio::Stdout<'_>,
) -> anyhow::Result<()> {
let crate::args::ExploreArgs { url, subpackages, tools, command, fuchsia_pkg_resolver } = args;
let (client, server) = fidl::Socket::create_stream();
let () = dash_launcher
.explore_package_over_socket2(
fuchsia_pkg_resolver,
&url,
&subpackages,
server,
&tools,
command.as_deref(),
)
.await
.context("fuchsia.dash/Launcher.ExplorePackageOverSocket2 fidl error")?
.map_err(|e| match e {
fdash::LauncherError::ResolveTargetPackage => {
anyhow!("No package found matching '{url}' {}.", subpackages.join(" "))
}
e => anyhow!("Error exploring package: {e:?}"),
})?;
#[allow(clippy::large_futures)]
let () = socket_to_stdio::connect_socket_to_stdio(client, stdout).await?;
let exit_code = wait_for_shell_exit(&dash_launcher).await?;
std::process::exit(exit_code);
}
async fn wait_for_shell_exit(launcher_proxy: &fdash::LauncherProxy) -> anyhow::Result<i32> {
match launcher_proxy.take_event_stream().next().await {
Some(Ok(fdash::LauncherEvent::OnTerminated { return_code })) => Ok(return_code),
Some(Err(e)) => Err(anyhow!("OnTerminated event error: {e:?}")),
None => Err(anyhow!("didn't receive an expected OnTerminated event")),
}
}