update cli

This commit is contained in:
John Smith 2022-06-26 17:00:05 -04:00
parent 6daa913c68
commit dc9a5ddad2
8 changed files with 236 additions and 407 deletions

486
Cargo.lock generated

File diff suppressed because it is too large Load Diff

2
external/cursive vendored

@ -1 +1 @@
Subproject commit 74c9d6977af86b2a57d4415c71eacda26f28c6b4 Subproject commit f29f750aade5a669d90ac9ea3a96e8299c4c66c0

@ -1 +1 @@
Subproject commit 1e1542b1bb45ba590e604cb9904ef08e5e6bd55d Subproject commit a1ff362346bd93955d9126893e4f6afb21f00881

@ -1 +1 @@
Subproject commit 5a093be753db1251c2451e7e0e55d548af4abe1d Subproject commit c4a7301b865d5af525fad30e76c2c5d121189943

View File

@ -23,23 +23,23 @@ cursive_buffered_backend = { path = "../external/cursive_buffered_backend" }
# cursive-tabs = "0.5.0" # cursive-tabs = "0.5.0"
clap = "^3" clap = "^3"
directories = "^4" directories = "^4"
log = "^0.4" log = "^0"
futures = "^0.3" futures = "^0"
serde = "^1.0.122" serde = "^1"
serde_derive = "^1.0.122" serde_derive = "^1"
parking_lot = "^0.11" parking_lot = "^0"
cfg-if = "^1" cfg-if = "^1"
capnp = "^0.14" capnp = "^0"
capnp-rpc = "^0.14" capnp-rpc = "^0"
config = { version = "0.10.1", features = ["yaml"] } config = { version = "^0", features = ["yaml"] }
bugsalot = "^0.2" bugsalot = "^0"
flexi_logger = "0.17" flexi_logger = "^0"
thiserror = "^1.0" thiserror = "^1"
crossbeam-channel = "0.5" crossbeam-channel = "^0"
veilid-core = { path = "../veilid-core" } veilid-core = { path = "../veilid-core" }
[dev-dependencies] [dev-dependencies]
serial_test = "^0.4" serial_test = "^0"
[build-dependencies] [build-dependencies]
capnpc = "^0.14" capnpc = "^0"

View File

@ -8,6 +8,7 @@ use clap::{Arg, ColorChoice, Command};
use flexi_logger::*; use flexi_logger::*;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use std::path::Path;
mod client_api_connection; mod client_api_connection;
mod command_processor; mod command_processor;
@ -49,9 +50,9 @@ fn parse_command_line(default_config_path: &OsStr) -> Result<clap::ArgMatches, S
Arg::new("config-file") Arg::new("config-file")
.short('c') .short('c')
.takes_value(true) .takes_value(true)
.allow_invalid_utf8(true)
.value_name("FILE") .value_name("FILE")
.default_value_os(default_config_path) .default_value_os(default_config_path)
.allow_invalid_utf8(true)
.help("Specify a configuration file to use"), .help("Specify a configuration file to use"),
) )
.get_matches(); .get_matches();
@ -70,11 +71,18 @@ async fn main() -> Result<(), String> {
} }
// Attempt to load configuration // Attempt to load configuration
let mut settings = settings::Settings::new( let settings_path = if let Some(config_file) = matches.value_of_os("config-file") {
matches.occurrences_of("config-file") == 0, if Path::new(config_file).exists() {
matches.value_of_os("config-file").unwrap(), Some(config_file)
) } else {
.map_err(map_to_string)?; None
}
} else {
None
};
let mut settings = settings::Settings::new(settings_path)
.map_err(|e| format!("configuration is invalid: {}", e))?;
// Set config from command line // Set config from command line
if matches.occurrences_of("debug") != 0 { if matches.occurrences_of("debug") != 0 {
@ -108,17 +116,17 @@ async fn main() -> Result<(), String> {
std::fs::create_dir_all(settings.logging.file.directory.clone()) std::fs::create_dir_all(settings.logging.file.directory.clone())
.map_err(map_to_string)?; .map_err(map_to_string)?;
logger logger
.log_target(LogTarget::FileAndWriter(flv)) .log_to_file_and_writer(
.suppress_timestamp() FileSpec::default()
// .format(flexi_logger::colored_default_format) .directory(settings.logging.file.directory.clone())
.directory(settings.logging.file.directory.clone()) .suppress_timestamp(),
flv,
)
.start() .start()
.expect("failed to initialize logger!"); .expect("failed to initialize logger!");
} else { } else {
logger logger
.log_target(LogTarget::Writer(flv)) .log_to_writer(flv)
.suppress_timestamp()
.format(flexi_logger::colored_default_format)
.start() .start()
.expect("failed to initialize logger!"); .expect("failed to initialize logger!");
} }
@ -126,9 +134,11 @@ async fn main() -> Result<(), String> {
std::fs::create_dir_all(settings.logging.file.directory.clone()) std::fs::create_dir_all(settings.logging.file.directory.clone())
.map_err(map_to_string)?; .map_err(map_to_string)?;
logger logger
.log_target(LogTarget::File) .log_to_file(
.suppress_timestamp() FileSpec::default()
.directory(settings.logging.file.directory.clone()) .directory(settings.logging.file.directory.clone())
.suppress_timestamp(),
)
.start() .start()
.expect("failed to initialize logger!"); .expect("failed to initialize logger!");
} }

View File

@ -5,7 +5,7 @@ use std::ffi::OsStr;
use std::net::{SocketAddr, ToSocketAddrs}; use std::net::{SocketAddr, ToSocketAddrs};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub fn load_default_config(cfg: &mut config::Config) -> Result<(), config::ConfigError> { pub fn load_default_config() -> Result<config::Config, config::ConfigError> {
let default_config = r###"--- let default_config = r###"---
address: "localhost:5959" address: "localhost:5959"
autoconnect: true autoconnect: true
@ -16,7 +16,7 @@ logging:
enabled: false enabled: false
file: file:
enabled: true enabled: true
directory: "" directory: "%LOGGING_FILE_DIRECTORY%"
append: true append: true
interface: interface:
node_log: node_log:
@ -44,21 +44,29 @@ interface:
info : "#5cd3c6" info : "#5cd3c6"
warn : "#fedc50" warn : "#fedc50"
error : "#ff4a15" error : "#ff4a15"
"###; "###
cfg.merge(config::File::from_str( .replace(
default_config, "%LOGGING_FILE_DIRECTORY%",
config::FileFormat::Yaml, &Settings::get_default_log_directory().to_string_lossy(),
)) );
.map(drop)
config::Config::builder()
.add_source(config::File::from_str(
&default_config,
config::FileFormat::Yaml,
))
.build()
} }
pub fn load_config( pub fn load_config(
cfg: &mut config::Config, cfg: config::Config,
config_file: &Path, config_file: &Path,
) -> Result<(), config::ConfigError> { ) -> Result<config::Config, config::ConfigError> {
if let Some(config_file_str) = config_file.to_str() { if let Some(config_file_str) = config_file.to_str() {
cfg.merge(config::File::new(config_file_str, config::FileFormat::Yaml)) config::Config::builder()
.map(drop) .add_source(cfg)
.add_source(config::File::new(config_file_str, config::FileFormat::Yaml))
.build()
} else { } else {
Err(config::ConfigError::Message( Err(config::ConfigError::Message(
"config file path is not valid UTF-8".to_owned(), "config file path is not valid UTF-8".to_owned(),
@ -226,38 +234,26 @@ impl Settings {
default_log_directory default_log_directory
} }
pub fn new( pub fn new(config_file: Option<&OsStr>) -> Result<Self, config::ConfigError> {
config_file_is_default: bool,
config_file: &OsStr,
) -> Result<Self, config::ConfigError> {
// Create a config
let mut cfg = config::Config::default();
// Load the default config // Load the default config
load_default_config(&mut cfg)?; let mut cfg = load_default_config()?;
// Use default log directory for logs
cfg.set(
"logging.file.directory",
Settings::get_default_log_directory().to_str(),
)?;
// Merge in the config file if we have one // Merge in the config file if we have one
let config_file_path = Path::new(config_file); if let Some(config_file) = config_file {
if !config_file_is_default || config_file_path.exists() { let config_file_path = Path::new(config_file);
// If the user specifies a config file on the command line then it must exist // If the user specifies a config file on the command line then it must exist
load_config(&mut cfg, config_file_path)?; cfg = load_config(cfg, config_file_path)?;
} }
cfg.try_into()
// Generate config
cfg.try_deserialize()
} }
} }
#[test] #[test]
fn test_default_config() { fn test_default_config() {
let mut cfg = config::Config::default(); let cfg = load_default_config().unwrap();
let settings = cfg.try_deserialize::<Settings>().unwrap();
load_default_config(&mut cfg).unwrap();
let settings = cfg.try_into::<Settings>().unwrap();
println!("default settings: {:?}", settings); println!("default settings: {:?}", settings);
} }

View File

@ -14,6 +14,7 @@ use log::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use std::rc::Rc; use std::rc::Rc;
use thiserror::Error;
use veilid_core::*; use veilid_core::*;
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
@ -87,6 +88,12 @@ pub struct UI {
inner: Handle<UIInner>, inner: Handle<UIInner>,
} }
#[derive(Error, Debug)]
pub enum DumbError {
// #[error("{0}")]
// Message(String),
}
impl UI { impl UI {
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Private functions // Private functions
@ -642,10 +649,10 @@ impl UI {
cursive_flexi_logger_view::resize(node_log_scrollback); cursive_flexi_logger_view::resize(node_log_scrollback);
// Instantiate the cursive runnable // Instantiate the cursive runnable
/*
// reduces flicker, but it costs cpu // reduces flicker, but it costs cpu
let mut runnable = CursiveRunnable::new( let runnable = CursiveRunnable::new(
|| -> Result<Box<dyn cursive_buffered_backend::Backend>, UIError> { || -> Result<Box<dyn cursive_buffered_backend::Backend>, Box<DumbError>> {
let crossterm_backend = cursive::backends::crossterm::Backend::init().unwrap(); let crossterm_backend = cursive::backends::crossterm::Backend::init().unwrap();
let buffered_backend = let buffered_backend =
cursive_buffered_backend::BufferedBackend::new(crossterm_backend); cursive_buffered_backend::BufferedBackend::new(crossterm_backend);
@ -653,8 +660,8 @@ impl UI {
Ok(Box::new(buffered_backend)) Ok(Box::new(buffered_backend))
}, },
); );
*/ //let runnable = cursive::default();
let runnable = cursive::default();
// Make the callback mechanism easily reachable // Make the callback mechanism easily reachable
let cb_sink = runnable.cb_sink().clone(); let cb_sink = runnable.cb_sink().clone();