Skip to content

Commit

Permalink
refactor: environment variable initialization (#243)
Browse files Browse the repository at this point in the history
* Refactor file path handling and environment variable initialization
  • Loading branch information
newtoallofthis123 authored Feb 27, 2024
1 parent 34b9619 commit 994b74f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 47 deletions.
84 changes: 84 additions & 0 deletions swhks/src/environ.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! Environ.rs
//! Defines modules and structs for handling environment variables and paths.
use std::{env::VarError, path::PathBuf};

use nix::unistd;

// The main struct for handling environment variables.
// Contains the values of the environment variables in the form of PathBuffers.
pub struct Env {
pub data_home: PathBuf,
pub home: PathBuf,
pub runtime_dir: PathBuf,
}

/// Error type for the Env struct.
/// Contains all the possible errors that can occur when trying to get an environment variable.
#[derive(Debug)]
pub enum EnvError {
DataHomeNotSet,
HomeNotSet,
RuntimeDirNotSet,
GenericError(String),
}

impl Env {
/// Constructs a new Env struct.
/// This function is called only once and the result is stored in a static variable.
pub fn construct() -> Self {
let home = match Self::get_env("HOME") {
Ok(val) => val,
Err(_) => {
eprintln!("HOME Variable is not set, cannot fall back on hardcoded path for XDG_DATA_HOME.");
std::process::exit(1);
}
};

let data_home = match Self::get_env("XDG_DATA_HOME") {
Ok(val) => val,
Err(e) => match e {
EnvError::DataHomeNotSet => {
log::warn!(
"XDG_DATA_HOME Variable is not set, falling back on hardcoded path."
);
home.join(".local/share")
}
_ => panic!("Unexpected error: {:#?}", e),
},
};

let runtime_dir = match Self::get_env("XDG_RUNTIME_DIR") {
Ok(val) => val,
Err(e) => match e {
EnvError::RuntimeDirNotSet => {
log::warn!(
"XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path."
);
PathBuf::from(format!("/run/user/{}", unistd::Uid::current()))
}
_ => panic!("Unexpected error: {:#?}", e),
},
};

Self { data_home, home, runtime_dir }
}

/// Actual interface to get the environment variable.
fn get_env(name: &str) -> Result<PathBuf, EnvError> {
match std::env::var(name) {
Ok(val) => Ok(PathBuf::from(val)),
Err(e) => match e {
VarError::NotPresent => match name {
"XDG_DATA_HOME" => Err(EnvError::DataHomeNotSet),
"HOME" => Err(EnvError::HomeNotSet),
"XDG_RUNTIME_DIR" => Err(EnvError::RuntimeDirNotSet),
_ => Err(EnvError::GenericError(format!("{} not set", name))),
},
VarError::NotUnicode(_) => {
Err(EnvError::GenericError(format!("{} not unicode", name)))
}
},
}
}
}
61 changes: 14 additions & 47 deletions swhks/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
use clap::arg;
use environ::Env;
use nix::{
sys::stat::{umask, Mode},
unistd,
unistd::daemon,
};
use std::io::Read;
use std::time::{SystemTime, UNIX_EPOCH};
use std::{
env, fs,
fs::OpenOptions,
io::prelude::*,
os::unix::net::UnixListener,
path::Path,
process::{exit, id, Command, Stdio},
time::{SystemTime, UNIX_EPOCH},
};
use sysinfo::{ProcessExt, System, SystemExt};

mod environ;

fn main() -> std::io::Result<()> {
let app = clap::Command::new("swhks")
.version(env!("CARGO_PKG_VERSION"))
Expand All @@ -38,7 +40,10 @@ fn main() -> std::io::Result<()> {
log::trace!("Setting process umask.");
umask(Mode::S_IWGRP | Mode::S_IWOTH);

let (pid_file_path, sock_file_path) = get_file_paths();
// This is used to initialize the environment variables only once
let environment = environ::Env::construct();

let (pid_file_path, sock_file_path) = get_file_paths(&environment);

let log_file_name = if let Some(val) = args.value_of("log") {
val.to_string()
Expand All @@ -51,29 +56,7 @@ fn main() -> std::io::Result<()> {
}
};

match env::var("XDG_DATA_HOME") {
Ok(val) => {
log::info!(
"XDG_DATA_HOME Variable is present, using it's value for default file path."
);
format!("{}/swhks/swhks-{}.log", val, time)
}
Err(e) => {
log::trace!(
"XDG_DATA_HOME Variable is not set, falling back on hardcoded path.\nError: {:#?}",
e
);
match env::var("HOME") {
Ok(val) => format!("{}/.local/share/swhks/swhks-{}.log", val, time),
Err(_) => {
log::error!(
"HOME Variable is not set, cannot fall back on hardcoded path for XDG_DATA_HOME."
);
exit(1);
}
}
}
}
format!("{}/swhks/swhks-{}.log", environment.data_home.to_string_lossy(), time)
};

let log_path = Path::new(&log_file_name);
Expand Down Expand Up @@ -142,27 +125,11 @@ fn main() -> std::io::Result<()> {
}
}

fn get_file_paths() -> (String, String) {
match env::var("XDG_RUNTIME_DIR") {
Ok(val) => {
log::info!(
"XDG_RUNTIME_DIR Variable is present, using it's value as default file path."
);

let pid_file_path = format!("{}/swhks.pid", val);
let sock_file_path = format!("{}/swhkd.sock", val);
fn get_file_paths(env: &Env) -> (String, String) {
let pid_file_path = format!("{}/swhks.pid", env.runtime_dir.to_string_lossy());
let sock_file_path = format!("{}/swhkd.sock", env.runtime_dir.to_string_lossy());

(pid_file_path, sock_file_path)
}
Err(e) => {
log::trace!("XDG_RUNTIME_DIR Variable is not set, falling back on hardcoded path.\nError: {:#?}", e);

let pid_file_path = format!("/run/user/{}/swhks.pid", unistd::Uid::current());
let sock_file_path = format!("/run/user/{}/swhkd.sock", unistd::Uid::current());

(pid_file_path, sock_file_path)
}
}
(pid_file_path, sock_file_path)
}

fn run_system_command(command: &str, log_path: &Path) {
Expand Down

0 comments on commit 994b74f

Please sign in to comment.