Add automatic Systemd service path update after changing espanso path (for example after an update). Fix #199

This commit is contained in:
Federico Terzi 2020-03-16 22:16:12 +01:00
parent 1db3aee017
commit f95457f769
2 changed files with 75 additions and 17 deletions

View File

@ -47,6 +47,7 @@ use crate::package::{PackageManager, InstallResult, UpdateResult, RemoveResult,
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use crate::package::git::GitPackageResolver; use crate::package::git::GitPackageResolver;
use crate::package::zip::ZipPackageResolver; use crate::package::zip::ZipPackageResolver;
use crate::sysdaemon::{verify, VerifyResult};
mod ui; mod ui;
mod edit; mod edit;
@ -452,25 +453,33 @@ fn start_daemon(config_set: ConfigSet) {
if config_set.default.use_system_agent && !force_unmanaged { if config_set.default.use_system_agent && !force_unmanaged {
// Make sure espanso is currently registered in systemd // Make sure espanso is currently registered in systemd
let res = Command::new("systemctl") let res = verify();
.args(&["--user", "is-enabled", "espanso.service"]) match res {
.output(); VerifyResult::EnabledAndValid => {
if !res.unwrap().status.success() { // Do nothing, everything is ok!
use dialoguer::Confirmation; },
if Confirmation::new() VerifyResult::EnabledButInvalidPath => {
.with_text("espanso must be registered to systemd (user level) first. Do you want to proceed?") eprintln!("Updating espanso service file with new path...");
.default(true) unregister_main(config_set.clone());
.show_default(true)
.interact().expect("Unable to read user answer") {
register_main(config_set); register_main(config_set);
}else{ },
eprintln!("Please register espanso to systemd with this command:"); VerifyResult::NotEnabled => {
eprintln!(" espanso register"); use dialoguer::Confirmation;
// TODO: enable flag to use non-managed daemon mode if Confirmation::new()
.with_text("espanso must be registered to systemd (user level) first. Do you want to proceed?")
.default(true)
.show_default(true)
.interact().expect("Unable to read user answer") {
std::process::exit(4); register_main(config_set);
} }else{
eprintln!("Please register espanso to systemd with this command:");
eprintln!(" espanso register");
// TODO: enable flag to use non-managed daemon mode
std::process::exit(4);
}
},
} }
// Start the espanso service // Start the espanso service

View File

@ -20,6 +20,7 @@
// This functions are used to register/unregister espanso from the system daemon manager. // This functions are used to register/unregister espanso from the system daemon manager.
use crate::config::ConfigSet; use crate::config::ConfigSet;
use crate::sysdaemon::VerifyResult::{EnabledAndValid, NotEnabled, EnabledButInvalidPath};
// INSTALLATION // INSTALLATION
@ -181,6 +182,54 @@ pub fn register(config_set: ConfigSet) {
} }
} }
pub enum VerifyResult {
EnabledAndValid,
EnabledButInvalidPath,
NotEnabled,
}
#[cfg(target_os = "linux")]
pub fn verify() -> VerifyResult {
use regex::Regex;
use std::process::{Command, ExitStatus};
// Check if espanso service is already registered
let res = Command::new("systemctl")
.args(&["--user", "is-enabled", "espanso"])
.output();
if let Ok(res) = res {
let output = String::from_utf8_lossy(res.stdout.as_slice());
let output = output.trim();
if !res.status.success() || output != "enabled" {
return NotEnabled
}
}
lazy_static! {
static ref ExecPathRegex: Regex = Regex::new("ExecStart=(?P<path>.*?)\\s").unwrap();
}
// Check if the currently registered path is valid
let res = Command::new("systemctl")
.args(&["--user", "cat", "espanso"])
.output();
if let Ok(res) = res {
let output = String::from_utf8_lossy(res.stdout.as_slice());
let output = output.trim();
if res.status.success() {
let caps = ExecPathRegex.captures(output).unwrap();
let path = caps.get(1).map_or("", |m| m.as_str());
let espanso_path = std::env::current_exe().expect("Could not get espanso executable path");
if espanso_path.to_string_lossy() != path {
return EnabledButInvalidPath
}
}
}
EnabledAndValid
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub fn unregister(config_set: ConfigSet) { pub fn unregister(config_set: ConfigSet) {
use std::process::{Command, ExitStatus}; use std::process::{Command, ExitStatus};