netsky 0.1.6

netsky CLI: the viable system launcher and subcommand dispatcher
Documentation
//! netsky CLI entry point. Parses argv with clap, dispatches to
//! [`cmd`] submodules. Each subcommand owns a small file there.

pub mod cli;
pub mod cmd;
pub mod observability;
pub mod ui;

use clap::Parser;

pub fn run<I, T>(args: I) -> netsky_core::Result<()>
where
    I: IntoIterator<Item = T>,
    T: Into<std::ffi::OsString> + Clone,
{
    load_home_dotenv();
    let cli = cli::Cli::parse_from(args);
    cli::dispatch(cli)
}

fn load_home_dotenv() {
    let path = netsky_core::paths::home().join(".env");
    let Ok(contents) = std::fs::read_to_string(path) else {
        return;
    };
    for line in contents.lines() {
        let Some((key, value)) = parse_dotenv_line(line) else {
            continue;
        };
        if std::env::var_os(&key).is_some() {
            continue;
        }
        // SAFETY: netsky calls this at CLI startup before it spawns worker
        // threads. Existing environment values win, so the loader cannot
        // race with later code that intentionally set a variable.
        unsafe {
            std::env::set_var(key, value);
        }
    }
}

fn parse_dotenv_line(line: &str) -> Option<(String, String)> {
    let mut s = line.trim();
    if s.is_empty() || s.starts_with('#') {
        return None;
    }
    if let Some(rest) = s.strip_prefix("export ") {
        s = rest.trim_start();
    }
    let (key, raw_value) = s.split_once('=')?;
    let key = key.trim();
    if key.is_empty()
        || !key
            .chars()
            .all(|ch| ch == '_' || ch.is_ascii_alphanumeric())
        || key.chars().next().is_some_and(|ch| ch.is_ascii_digit())
    {
        return None;
    }
    let value = parse_dotenv_value(raw_value.trim());
    Some((key.to_string(), value))
}

fn parse_dotenv_value(value: &str) -> String {
    if value.len() >= 2 {
        let bytes = value.as_bytes();
        let quote = bytes[0] as char;
        if (quote == '"' || quote == '\'') && bytes[value.len() - 1] as char == quote {
            let inner = &value[1..value.len() - 1];
            if quote == '"' {
                return unescape_double_quoted(inner);
            }
            return inner.to_string();
        }
    }

    strip_inline_comment(value).trim_end().to_string()
}

fn strip_inline_comment(value: &str) -> &str {
    let mut escaped = false;
    for (idx, ch) in value.char_indices() {
        if escaped {
            escaped = false;
            continue;
        }
        if ch == '\\' {
            escaped = true;
            continue;
        }
        if ch == '#'
            && value[..idx]
                .chars()
                .next_back()
                .is_some_and(char::is_whitespace)
        {
            return &value[..idx];
        }
    }
    value
}

fn unescape_double_quoted(value: &str) -> String {
    let mut out = String::with_capacity(value.len());
    let mut chars = value.chars();
    while let Some(ch) = chars.next() {
        if ch != '\\' {
            out.push(ch);
            continue;
        }
        match chars.next() {
            Some('n') => out.push('\n'),
            Some('r') => out.push('\r'),
            Some('t') => out.push('\t'),
            Some('"') => out.push('"'),
            Some('\\') => out.push('\\'),
            Some(other) => {
                out.push('\\');
                out.push(other);
            }
            None => out.push('\\'),
        }
    }
    out
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn dotenv_line_parses_export_and_quotes() {
        assert_eq!(
            parse_dotenv_line("export NETSKY_IROH_PEER_WORK_NODEID=\"abc\""),
            Some((
                "NETSKY_IROH_PEER_WORK_NODEID".to_string(),
                "abc".to_string()
            ))
        );
        assert_eq!(
            parse_dotenv_line("NETSKY_EMAIL_AUTO_SEND='1'"),
            Some(("NETSKY_EMAIL_AUTO_SEND".to_string(), "1".to_string()))
        );
    }

    #[test]
    fn dotenv_line_ignores_comments_and_invalid_keys() {
        assert_eq!(parse_dotenv_line("# x"), None);
        assert_eq!(parse_dotenv_line("1BAD=x"), None);
        assert_eq!(
            parse_dotenv_line("NETSKY_IROH_LABEL=work # local peer"),
            Some(("NETSKY_IROH_LABEL".to_string(), "work".to_string()))
        );
    }
}