1#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
14
15pub mod auto_register;
16pub mod autostart;
17pub mod cli;
18pub mod config;
19pub mod engine;
20pub mod http;
21pub mod runtime;
22pub mod service;
23pub mod sys;
24pub mod telemetry;
25#[doc(hidden)]
26pub mod test_support;
27pub mod types;
28#[cfg(feature = "ui")]
29pub mod ui;
30pub mod update;
31pub mod ws;
32
33pub const AGENT_VERSION: &str = env!("CARGO_PKG_VERSION");
34
35pub const RELEASE_NAME: &str = concat!(env!("CARGO_PKG_NAME"), "@", env!("CARGO_PKG_VERSION"));
40
41const CLI_TRACE_TARGET: &str = "studio_worker::cli";
44
45fn log_cli_startup(command: &cli::Command) {
51 tracing::info!(
52 target: CLI_TRACE_TARGET,
53 op = "startup",
54 version = AGENT_VERSION,
55 command = command.name(),
56 "studio-worker starting"
57 );
58}
59
60pub async fn run_cli(args: cli::Cli) -> anyhow::Result<()> {
63 log_cli_startup(&args.command);
64 match args.command {
65 cli::Command::Run => runtime::run(args.config.as_deref()).await,
66 cli::Command::Register {
67 api_base_url,
68 reset,
69 } => {
70 runtime::register(
71 args.config.as_deref(),
72 runtime::RegisterArgs {
73 api_base_url,
74 reset,
75 },
76 )
77 .await
78 }
79 cli::Command::Status => runtime::status(args.config.as_deref()).await,
80 cli::Command::InstallService => service::install(args.config.as_deref()),
81 cli::Command::UninstallService => service::uninstall(),
82 cli::Command::SetThreshold { gb } => runtime::set_threshold(args.config.as_deref(), gb),
83 cli::Command::Config => runtime::show_config(args.config.as_deref()),
84 cli::Command::CheckUpdate => runtime::check_update(args.config.as_deref()).await,
85 cli::Command::Ui => run_ui(args.config.as_deref()).await,
86 }
87}
88
89#[cfg(feature = "ui")]
90async fn run_ui(config_path: Option<&str>) -> anyhow::Result<()> {
91 ui::run(config_path)
92}
93
94#[cfg(not(feature = "ui"))]
95async fn run_ui(_config_path: Option<&str>) -> anyhow::Result<()> {
96 anyhow::bail!(
97 "this build of studio-worker was compiled without the `ui` cargo feature \
98 (it is on by default \u{2014} you built with `--no-default-features`).\n\
99 Reinstall with `cargo install studio-worker` (UI is the default), or use \
100 the desktop installer from the releases page, to enable the native UI."
101 )
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::test_support::capture;
108
109 #[test]
110 fn startup_breadcrumb_names_version_and_command() {
111 let logs = capture(|| log_cli_startup(&cli::Command::Run));
112 assert!(logs.contains("INFO"), "expected INFO event, got: {logs}");
113 assert!(
114 logs.contains("studio_worker::cli"),
115 "expected the cli target, got: {logs}"
116 );
117 assert!(
118 logs.contains("op=\"startup\""),
119 "expected op=startup, got: {logs}"
120 );
121 assert!(
122 logs.contains("command=\"run\""),
123 "expected command field, got: {logs}"
124 );
125 assert!(
126 logs.contains(AGENT_VERSION),
127 "expected agent version, got: {logs}"
128 );
129 }
130}