feat: Implement config file
This commit is contained in:
parent
4438a11437
commit
402513b11d
4 changed files with 72 additions and 12 deletions
|
@ -7,7 +7,7 @@ use color_eyre::Result;
|
||||||
|
|
||||||
use crate::Request;
|
use crate::Request;
|
||||||
|
|
||||||
pub fn handle(runtime_dir: PathBuf) -> Result<()> {
|
pub fn handle(runtime_dir: PathBuf, session: String) -> Result<()> {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
stdin()
|
stdin()
|
||||||
.read_to_string(&mut buf)
|
.read_to_string(&mut buf)
|
||||||
|
@ -17,7 +17,7 @@ pub fn handle(runtime_dir: PathBuf) -> Result<()> {
|
||||||
|
|
||||||
tracing::trace!("Received request: {:?}", req);
|
tracing::trace!("Received request: {:?}", req);
|
||||||
|
|
||||||
let path = runtime_dir.join(&req.session).with_extension("s");
|
let path = runtime_dir.join(session).with_extension("s");
|
||||||
tracing::debug!(path = %path.display());
|
tracing::debug!(path = %path.display());
|
||||||
|
|
||||||
let mut socket = UnixStream::connect(&path)
|
let mut socket = UnixStream::connect(&path)
|
||||||
|
|
51
src/config.rs
Normal file
51
src/config.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::{env, fs};
|
||||||
|
|
||||||
|
use color_eyre::eyre::Context;
|
||||||
|
use color_eyre::Result;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
/// The number of worker threads to spawn
|
||||||
|
pub workers: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn load(path: Option<PathBuf>) -> Result<Self> {
|
||||||
|
let buf = if let Some(path) = path {
|
||||||
|
tracing::debug!("Reading config file '{}'", path.display());
|
||||||
|
fs::read(&path).wrap_err_with(|| format!("Failed to read file '{}'", path.display()))?
|
||||||
|
} else {
|
||||||
|
let path = default_config_path();
|
||||||
|
tracing::debug!("Reading config file '{}'", path.display());
|
||||||
|
match fs::read(&path) {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(err) if err.kind() == ErrorKind::NotFound => {
|
||||||
|
tracing::debug!("Default config file does not exist, using default values");
|
||||||
|
return Ok(Config::default());
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return Err(err)
|
||||||
|
.wrap_err_with(|| format!("Failed to read file '{}'", path.display()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let buf = String::from_utf8_lossy(&buf);
|
||||||
|
toml::from_str(&buf).wrap_err("Failed to deserialize config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { workers: 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_config_path() -> PathBuf {
|
||||||
|
env::var("XDG_CONFIG_HOME")
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or_else(|_| PathBuf::from(env::var("HOME").unwrap()).join(".config"))
|
||||||
|
.join("kak-highlight.toml")
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ use signal_hook::consts::{SIGINT, TERM_SIGNALS};
|
||||||
use signal_hook::flag;
|
use signal_hook::flag;
|
||||||
use signal_hook::iterator::Signals;
|
use signal_hook::iterator::Signals;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::daemon::worker::TaskScheduler;
|
use crate::daemon::worker::TaskScheduler;
|
||||||
|
|
||||||
use self::listener::Listener;
|
use self::listener::Listener;
|
||||||
|
@ -19,7 +20,7 @@ mod listener;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub fn handle(runtime_dir: PathBuf, session: String, workers: u8) -> Result<()> {
|
pub fn handle(runtime_dir: PathBuf, config_path: Option<PathBuf>, session: String) -> Result<()> {
|
||||||
// Ensure that sending a termination signal twice will immediately kill
|
// Ensure that sending a termination signal twice will immediately kill
|
||||||
{
|
{
|
||||||
let term_now = Arc::new(AtomicBool::new(false));
|
let term_now = Arc::new(AtomicBool::new(false));
|
||||||
|
@ -29,6 +30,9 @@ pub fn handle(runtime_dir: PathBuf, session: String, workers: u8) -> Result<()>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let config = Config::load(config_path).wrap_err("Failed to load config")?;
|
||||||
|
tracing::debug!(?config);
|
||||||
|
|
||||||
let rx_signals = {
|
let rx_signals = {
|
||||||
let mut signals = Signals::new([SIGINT])?;
|
let mut signals = Signals::new([SIGINT])?;
|
||||||
let (tx, rx) = bounded(1);
|
let (tx, rx) = bounded(1);
|
||||||
|
@ -42,10 +46,13 @@ pub fn handle(runtime_dir: PathBuf, session: String, workers: u8) -> Result<()>
|
||||||
})
|
})
|
||||||
.wrap_err("Failed to start signal handler")?;
|
.wrap_err("Failed to start signal handler")?;
|
||||||
|
|
||||||
|
tracing::trace!("Started signal handler");
|
||||||
|
|
||||||
rx
|
rx
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut scheduler = TaskScheduler::new(workers).wrap_err("Failed to create task scheduler")?;
|
let mut scheduler =
|
||||||
|
TaskScheduler::new(config.workers).wrap_err("Failed to create task scheduler")?;
|
||||||
let listener = Listener::new(runtime_dir, session).wrap_err("Failed to create listener")?;
|
let listener = Listener::new(runtime_dir, session).wrap_err("Failed to create listener")?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -12,6 +12,7 @@ use tracing_subscriber::fmt;
|
||||||
use tracing_subscriber::prelude::*;
|
use tracing_subscriber::prelude::*;
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
|
mod config;
|
||||||
mod daemon;
|
mod daemon;
|
||||||
mod kakoune;
|
mod kakoune;
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ struct Cli {
|
||||||
/// File to write log events to
|
/// File to write log events to
|
||||||
#[arg(long, value_name = "FILENAME")]
|
#[arg(long, value_name = "FILENAME")]
|
||||||
log: Option<PathBuf>,
|
log: Option<PathBuf>,
|
||||||
|
/// Config file. Defaults to `$XDG_CONFIG_HOME/kak-highlight.toml`.
|
||||||
|
#[arg(short, long, value_name = "FILENAME")]
|
||||||
|
config: Option<PathBuf>,
|
||||||
/// The command to run
|
/// The command to run
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Command,
|
command: Command,
|
||||||
|
@ -32,21 +36,19 @@ struct Cli {
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Command {
|
enum Command {
|
||||||
/// Send a request payload to a running daemon and wait for the response
|
/// Send a request payload to a running daemon and wait for the response
|
||||||
Request,
|
Request {
|
||||||
|
/// The Kakoune session this daemon belongs to
|
||||||
|
session: String,
|
||||||
|
},
|
||||||
/// Start a daemon
|
/// Start a daemon
|
||||||
Daemon {
|
Daemon {
|
||||||
/// The Kakoune session this daemon belongs to
|
/// The Kakoune session this daemon belongs to
|
||||||
session: String,
|
session: String,
|
||||||
/// The number of worker threads to spawn
|
|
||||||
#[arg(short = 'n', long, default_value = "2", action = clap::ArgAction::Count)]
|
|
||||||
workers: u8,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
struct Request {
|
struct Request {
|
||||||
/// The Kakoune session this request came from
|
|
||||||
session: String,
|
|
||||||
/// The command FIFO provided by Kakoune
|
/// The command FIFO provided by Kakoune
|
||||||
fifo: String,
|
fifo: String,
|
||||||
}
|
}
|
||||||
|
@ -91,7 +93,7 @@ fn main() -> Result<()> {
|
||||||
.join("kak-highlight");
|
.join("kak-highlight");
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Command::Daemon { session, workers } => daemon::handle(runtime_dir, session, workers),
|
Command::Daemon { session } => daemon::handle(runtime_dir, cli.config, session),
|
||||||
Command::Request => client::handle(runtime_dir),
|
Command::Request { session } => client::handle(runtime_dir, session),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue