|
@@ -11,9 +11,9 @@ use crate::{
|
|
|
interface::{AppInterface, DevProcess, ExitReason, Interface},
|
|
|
CommandExt, Result,
|
|
|
};
|
|
|
-use clap::{ArgAction, Parser};
|
|
|
|
|
|
use anyhow::{bail, Context};
|
|
|
+use clap::{ArgAction, Parser};
|
|
|
use log::{error, info, warn};
|
|
|
use once_cell::sync::OnceCell;
|
|
|
use shared_child::SharedChild;
|
|
@@ -88,7 +88,34 @@ fn command_internal(mut options: Options) -> Result<()> {
|
|
|
|
|
|
fn local_ip_address() -> &'static IpAddr {
|
|
|
static LOCAL_IP: OnceCell<IpAddr> = OnceCell::new();
|
|
|
- LOCAL_IP.get_or_init(|| local_ip_address::local_ip().expect("failed to resolve local IP address"))
|
|
|
+ LOCAL_IP.get_or_init(|| {
|
|
|
+ let addresses: Vec<IpAddr> = local_ip_address::list_afinet_netifas()
|
|
|
+ .expect("failed to list networks")
|
|
|
+ .into_iter()
|
|
|
+ .map(|(_, ipaddr)| ipaddr)
|
|
|
+ .filter(|ipaddr| match ipaddr {
|
|
|
+ IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
|
|
|
+ _ => false,
|
|
|
+ })
|
|
|
+ .collect();
|
|
|
+ match addresses.len() {
|
|
|
+ 0 => panic!("No external IP detected."),
|
|
|
+ 1 => {
|
|
|
+ let ipaddr = addresses.first().unwrap();
|
|
|
+ log::info!("Detected external IP {ipaddr}.");
|
|
|
+ *ipaddr
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
|
|
|
+ .with_prompt("What external IP should we use for your development server?")
|
|
|
+ .items(&addresses)
|
|
|
+ .default(0)
|
|
|
+ .interact()
|
|
|
+ .expect("failed to select external IP");
|
|
|
+ *addresses.get(selected).unwrap()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
pub fn setup(options: &mut Options, mobile: bool) -> Result<AppInterface> {
|