use anyhow::Context;
use tracing::warn;
use crate::{
__internals::{Loader, Runner},
alpha, rt,
};
#[derive(Default)]
struct Args {
beta: bool,
port: Option<u16>,
}
impl Args {
fn parse() -> anyhow::Result<Self> {
let mut args = Self::default();
let mut args_iter = std::env::args().skip(1);
while let Some(arg) = args_iter.next() {
if arg.as_str() == "--port" {
let port = args_iter
.next()
.context("missing port value")?
.parse()
.context("invalid port value")?;
args.port = Some(port);
}
}
args.beta = std::env::var("SHUTTLE_BETA").is_ok();
if args.beta {
if std::env::var("SHUTTLE_ENV").is_err() {
return Err(anyhow::anyhow!(
"SHUTTLE_ENV is required to be set on shuttle.dev"
));
}
} else if args.port.is_none() {
return Err(anyhow::anyhow!("--port is required"));
}
Ok(args)
}
}
pub async fn start(loader: impl Loader + Send + 'static, runner: impl Runner + Send + 'static) {
if std::env::args().any(|arg| arg == "--version") {
println!("{}", crate::VERSION_STRING);
return;
}
println!("{} starting", crate::VERSION_STRING);
let args = match Args::parse() {
Ok(args) => args,
Err(e) => {
eprintln!("ERROR: Runtime failed to parse args: {e}");
let help_str = "[HINT]: Run your Shuttle app with `shuttle run` or `cargo shuttle run`";
let wrapper_str = "-".repeat(help_str.len());
eprintln!("{wrapper_str}\n{help_str}\n{wrapper_str}");
return;
}
};
#[cfg(feature = "setup-tracing")]
{
use tracing_subscriber::{fmt, prelude::*, registry, EnvFilter};
registry()
.with(fmt::layer().without_time())
.with(
EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info,shuttle=trace"))
.unwrap(),
)
.init();
if args.beta {
warn!("Default tracing subscriber initialized (https://docs.shuttle.dev/docs/logs)");
} else {
warn!("Default tracing subscriber initialized (https://docs.shuttle.rs/configuration/logs)");
}
}
if args.beta {
rt::start(loader, runner).await
} else {
alpha::start(args.port.unwrap(), loader, runner).await
}
}