Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: better handle different installation methods #191

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 32 additions & 26 deletions linkup-cli/src/commands/uninstall.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
use std::{fs, process};

use crate::{commands, linkup_dir_path, CliError};
use crate::{commands, linkup_dir_path, linkup_exe_path, CliError, InstallationMethod};

#[derive(clap::Args)]
pub struct Args {}

pub fn uninstall(_args: &Args) -> Result<(), CliError> {
commands::stop(&commands::StopArgs {}, true)?;

let exe_path = linkup_exe_path();

log::debug!("Linkup exe path: {:?}", &exe_path);
match InstallationMethod::current() {
InstallationMethod::Brew => {
log::debug!("Uninstalling linkup from Homebrew");

process::Command::new("brew")
.args(["uninstall", "linkup"])
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.status()?;
}
InstallationMethod::Cargo => {
log::debug!("Uninstalling linkup from Cargo");

process::Command::new("cargo")
.args(["uninstall", "linkup-cli"])
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.status()?;
}
InstallationMethod::Manual => {
log::debug!("Uninstalling linkup");

fs::remove_file(&exe_path)?;
}
}

let linkup_dir = linkup_dir_path();

log::debug!("Removing linkup folder: {}", linkup_dir.display());
fs::remove_dir_all(linkup_dir)?;

let exe_path = fs::canonicalize(std::env::current_exe()?)?
.display()
.to_string();

log::debug!("Linkup exe path: {}", &exe_path);
if exe_path.contains("homebrew") {
log::debug!("Uninstalling linkup from Homebrew");

process::Command::new("brew")
.args(["uninstall", "linkup"])
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.status()?;
} else if exe_path.contains(".cargo") {
log::debug!("Uninstalling linkup from Cargo");

process::Command::new("cargo")
.args(["uninstall", "linkup-cli"])
.stdin(process::Stdio::null())
.stdout(process::Stdio::null())
.stderr(process::Stdio::null())
.status()?;
}

println!("linkup uninstalled!");

Ok(())
Expand Down
15 changes: 9 additions & 6 deletions linkup-cli/src/commands/update.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{current_version, release, CliError};
use crate::{current_version, linkup_exe_path, release, CliError};
use std::{fs, path::PathBuf};

#[derive(clap::Args)]
Expand All @@ -19,7 +19,7 @@ pub async fn update(args: &Args) -> Result<(), CliError> {
Some(update) => {
let new_linkup_path = update.linkup.download_decompressed("linkup").await.unwrap();

let current_linkup_path = get_exe_path().expect("failed to get the current exe path");
let current_linkup_path = linkup_exe_path();
let bkp_linkup_path = current_linkup_path.with_extension("bkp");

fs::rename(&current_linkup_path, &bkp_linkup_path)
Expand Down Expand Up @@ -53,10 +53,13 @@ pub async fn new_version_available() -> bool {
.is_some()
}

// Get the current exe path. Using canonicalize ensure that we follow the symlink in case it is one.
// This is important in case the version is one installed with Homebrew.
fn get_exe_path() -> Result<PathBuf, std::io::Error> {
fs::canonicalize(std::env::current_exe()?)
pub fn update_command() -> String {
match crate::InstallationMethod::current() {
crate::InstallationMethod::Brew => "brew upgrade linkup".to_string(),
crate::InstallationMethod::Manual | crate::InstallationMethod::Cargo => {
"linkup update".to_string()
}
}
}

fn get_caddy_path() -> PathBuf {
Expand Down
36 changes: 32 additions & 4 deletions linkup-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ const LINKUP_LOCALSERVER_PORT: u16 = 9066;
const LINKUP_DIR: &str = ".linkup";
const LINKUP_STATE_FILE: &str = "state";

pub enum InstallationMethod {
Brew,
Cargo,
Manual,
}

impl InstallationMethod {
fn current() -> Self {
for component in linkup_exe_path().components() {
if component.as_os_str() == "Cellar" {
return Self::Brew;
} else if component.as_os_str() == ".cargo" {
return Self::Cargo;
}
}

return Self::Manual;
}
}

pub fn linkup_exe_path() -> PathBuf {
fs::canonicalize(std::env::current_exe().expect("current exe to be accessible"))
.expect("exe path to be valid")
}

pub fn linkup_dir_path() -> PathBuf {
let storage_dir = match env::var("HOME") {
Ok(val) => val,
Expand Down Expand Up @@ -246,10 +271,13 @@ async fn main() -> Result<()> {
if !matches!(cli.command, Commands::Update(_))
&& commands::update::new_version_available().await
{
println!(
"{}",
"⚠️ New version of linkup is available! Run `linkup update` to update it.".yellow()
);
let message = format!(
"⚠️ New version of linkup is available! Run `{}` to update it.",
commands::update::update_command()
)
.yellow();

println!("{}", message);
}

match &cli.command {
Expand Down
Loading