feat(core): create /usr/local/bin folder on macOS if it doesn't exist when adding espanso to the path. Fix #814
This commit is contained in:
parent
665790e8f5
commit
30de95adef
|
@ -17,11 +17,11 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::io::ErrorKind;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{fs::create_dir_all, io::ErrorKind};
|
||||
use thiserror::Error;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use log::{error, warn};
|
||||
|
||||
pub fn is_espanso_in_path() -> bool {
|
||||
|
@ -32,35 +32,33 @@ pub fn add_espanso_to_path(prompt_when_necessary: bool) -> Result<()> {
|
|||
let target_link_dir = PathBuf::from("/usr/local/bin");
|
||||
let exec_path = std::env::current_exe()?;
|
||||
|
||||
if !target_link_dir.is_dir() {
|
||||
return Err(PathError::UsrLocalBinDirDoesNotExist.into());
|
||||
}
|
||||
|
||||
let target_link_path = target_link_dir.join("espanso");
|
||||
|
||||
if !target_link_dir.is_dir() {
|
||||
warn!("/usr/local/bin folder does not exist, attempting to create one...");
|
||||
|
||||
if let Err(error) = create_dir_all(&target_link_dir) {
|
||||
match error.kind() {
|
||||
ErrorKind::PermissionDenied if prompt_when_necessary => {
|
||||
warn!("target link file can't be accessed with current permissions, requesting elevated ones through AppleScript.");
|
||||
|
||||
create_link_with_applescript(&exec_path, &target_link_path)
|
||||
.context("unable to create link with AppleScript")?;
|
||||
}
|
||||
_other_error => {
|
||||
return Err(PathError::SymlinkError(error).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(error) = std::os::unix::fs::symlink(&exec_path, &target_link_path) {
|
||||
match error.kind() {
|
||||
ErrorKind::PermissionDenied => {
|
||||
if prompt_when_necessary {
|
||||
warn!("target link file can't be accessed with current permissions, requesting elevated ones through AppleScript.");
|
||||
ErrorKind::PermissionDenied if prompt_when_necessary => {
|
||||
warn!("target link file can't be accessed with current permissions, requesting elevated ones through AppleScript.");
|
||||
|
||||
let params = format!(
|
||||
r##"do shell script "mkdir -p /usr/local/bin && ln -sf '{}' '{}'" with administrator privileges"##,
|
||||
exec_path.to_string_lossy(),
|
||||
target_link_path.to_string_lossy(),
|
||||
);
|
||||
|
||||
let mut child = std::process::Command::new("osascript")
|
||||
.args(&["-e", ¶ms])
|
||||
.spawn()?;
|
||||
|
||||
let result = child.wait()?;
|
||||
if !result.success() {
|
||||
return Err(PathError::ElevationRequestFailure.into());
|
||||
}
|
||||
} else {
|
||||
return Err(PathError::SymlinkError(error).into());
|
||||
}
|
||||
create_link_with_applescript(&exec_path, &target_link_path)
|
||||
.context("unable to create link with AppleScript")?;
|
||||
}
|
||||
_other_error => {
|
||||
return Err(PathError::SymlinkError(error).into());
|
||||
|
@ -71,6 +69,26 @@ pub fn add_espanso_to_path(prompt_when_necessary: bool) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn create_link_with_applescript(exec_path: &Path, target_link_path: &Path) -> Result<()> {
|
||||
let params = format!(
|
||||
r##"do shell script "mkdir -p /usr/local/bin && ln -sf '{}' '{}'" with administrator privileges"##,
|
||||
exec_path.to_string_lossy(),
|
||||
target_link_path.to_string_lossy(),
|
||||
);
|
||||
|
||||
let mut child = std::process::Command::new("osascript")
|
||||
.args(&["-e", ¶ms])
|
||||
.spawn()?;
|
||||
|
||||
let result = child.wait()?;
|
||||
|
||||
if !result.success() {
|
||||
return Err(PathError::ElevationRequestFailure.into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_espanso_from_path(prompt_when_necessary: bool) -> Result<()> {
|
||||
let target_link_path = PathBuf::from("/usr/local/bin/espanso");
|
||||
|
||||
|
@ -112,9 +130,6 @@ pub fn remove_espanso_from_path(prompt_when_necessary: bool) -> Result<()> {
|
|||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PathError {
|
||||
#[error("/usr/local/bin directory doesn't exist")]
|
||||
UsrLocalBinDirDoesNotExist,
|
||||
|
||||
#[error("symlink error: `{0}`")]
|
||||
SymlinkError(std::io::Error),
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user