|
| 1 | +use anyhow::Result; |
1 | 2 | use serde::{Deserialize, Serialize}; |
2 | 3 | use std::{fmt::format, path::Path}; |
3 | 4 |
|
@@ -146,6 +147,75 @@ pub struct Terminal { |
146 | 147 | pub command: String, |
147 | 148 | } |
148 | 149 |
|
| 150 | +const DEFAULT_PORT: u16 = 3000; |
| 151 | + |
| 152 | +fn print_help() { |
| 153 | + println!("anycode - Code editor server"); |
| 154 | + println!(); |
| 155 | + println!("USAGE:"); |
| 156 | + println!(" anycode [OPTIONS]"); |
| 157 | + println!(); |
| 158 | + println!("OPTIONS:"); |
| 159 | + println!(" -h, --help Print help information"); |
| 160 | + println!(" --version Print version information"); |
| 161 | + println!(" -p, --port <PORT> Port to listen on"); |
| 162 | + println!(); |
| 163 | + println!("ENVIRONMENT:"); |
| 164 | + println!(" ANYCODE_PORT Port to listen on (default: 3000)"); |
| 165 | + println!(" ANYCODE_HOME Path to configuration directory"); |
| 166 | + println!(" ANYCODE_ACP_PERMISSION_MODE ACP permission mode: full_access (default) or ask"); |
| 167 | + println!(); |
| 168 | + println!("Start the anycode server. The server will be available at http://localhost:<port>"); |
| 169 | +} |
| 170 | + |
| 171 | +fn parse_port(value: &str, source: &str) -> Result<u16> { |
| 172 | + value |
| 173 | + .parse::<u16>() |
| 174 | + .map_err(|_| anyhow::anyhow!("Invalid {source}: {value}")) |
| 175 | +} |
| 176 | + |
| 177 | +pub fn resolve_server_port() -> Result<u16> { |
| 178 | + let mut args = std::env::args().skip(1); |
| 179 | + let mut cli_port: Option<u16> = None; |
| 180 | + |
| 181 | + while let Some(arg) = args.next() { |
| 182 | + match arg.as_str() { |
| 183 | + "--help" | "-h" => { |
| 184 | + print_help(); |
| 185 | + std::process::exit(0); |
| 186 | + } |
| 187 | + "--version" | "-V" => { |
| 188 | + println!("anycode {}", env!("CARGO_PKG_VERSION")); |
| 189 | + std::process::exit(0); |
| 190 | + } |
| 191 | + "--port" | "-p" => { |
| 192 | + let value = args |
| 193 | + .next() |
| 194 | + .ok_or_else(|| anyhow::anyhow!("Missing value for {arg}"))?; |
| 195 | + cli_port = Some(parse_port(&value, "CLI port")?); |
| 196 | + } |
| 197 | + _ if arg.starts_with("--port=") => { |
| 198 | + cli_port = Some(parse_port(&arg["--port=".len()..], "CLI port")?); |
| 199 | + } |
| 200 | + _ if arg.starts_with('-') => { |
| 201 | + anyhow::bail!("Unknown option: {arg}"); |
| 202 | + } |
| 203 | + _ => { |
| 204 | + anyhow::bail!("Unknown positional argument: {arg}"); |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + if let Some(port) = cli_port { |
| 210 | + return Ok(port); |
| 211 | + } |
| 212 | + |
| 213 | + match std::env::var("ANYCODE_PORT") { |
| 214 | + Ok(value) => parse_port(&value, "ANYCODE_PORT"), |
| 215 | + Err(_) => Ok(DEFAULT_PORT), |
| 216 | + } |
| 217 | +} |
| 218 | + |
149 | 219 | #[cfg(test)] |
150 | 220 | mod congif_tests { |
151 | 221 | use super::*; |
|
0 commit comments