aboutsummaryrefslogtreecommitdiffstats
path: root/ui/backend/src
diff options
context:
space:
mode:
authorEllie Huxtable <ellie@elliehuxtable.com>2024-06-17 15:36:38 +0100
committerGitHub <noreply@github.com>2024-06-17 15:36:38 +0100
commit88633b8994437180afdd66068cc2c8f02aea1db1 (patch)
tree6df7ead44d8cb3c219dd43d0ee86256f4a6025ef /ui/backend/src
parentchore(deps): bump lucide-react from 0.394.0 to 0.395.0 in /ui (#2148) (diff)
downloadatuin-88633b8994437180afdd66068cc2c8f02aea1db1.zip
feat(gui): automatically install and setup the cli/shell (#2139)
* feat(gui): automatically install and setup the cli/shell * add shell config and toasts
Diffstat (limited to 'ui/backend/src')
-rw-r--r--ui/backend/src/install.rs67
-rw-r--r--ui/backend/src/main.rs4
-rw-r--r--ui/backend/src/update.rs51
3 files changed, 71 insertions, 51 deletions
diff --git a/ui/backend/src/install.rs b/ui/backend/src/install.rs
new file mode 100644
index 00000000..55877c4b
--- /dev/null
+++ b/ui/backend/src/install.rs
@@ -0,0 +1,67 @@
+// Handle installing the Atuin CLI
+// We can use the standard install script for this
+
+use std::process::Command;
+
+use tokio::{
+ fs::{read_to_string, OpenOptions},
+ io::AsyncWriteExt,
+};
+
+use atuin_common::shell::Shell;
+
+#[tauri::command]
+pub(crate) async fn install_cli() -> Result<(), String> {
+ let output = Command::new("sh")
+ .arg("-c")
+ .arg("curl --proto '=https' --tlsv1.2 -LsSf https://github.com/atuinsh/atuin/releases/latest/download/atuin-installer.sh | sh")
+ .output().map_err(|e|format!("Failed to execute Atuin installer: {e}"));
+
+ Ok(())
+}
+
+#[tauri::command]
+pub(crate) async fn is_cli_installed() -> Result<bool, String> {
+ let shell = Shell::default_shell().map_err(|e| format!("Failed to get default shell: {e}"))?;
+ let output = shell
+ .run_interactive(&["atuin --version && echo 'ATUIN FOUND'"])
+ .map_err(|e| format!("Failed to run interactive command"))?;
+
+ Ok(output.contains("ATUIN FOUND"))
+}
+
+#[tauri::command]
+pub(crate) async fn setup_cli() -> Result<(), String> {
+ let shell = Shell::default_shell().map_err(|e| format!("Failed to get default shell: {e}"))?;
+ let config_file_path = shell.config_file();
+
+ if config_file_path.is_none() {
+ return Err("Failed to fetch default config file".to_string());
+ }
+
+ let config_file_path = config_file_path.unwrap();
+ let config_file = read_to_string(config_file_path.clone())
+ .await
+ .map_err(|e| format!("Failed to read config file: {e}"))?;
+
+ if config_file.contains("atuin init") {
+ return Ok(());
+ }
+
+ let mut file = OpenOptions::new()
+ .write(true)
+ .append(true)
+ .open(config_file_path)
+ .await
+ .unwrap();
+
+ let config = format!(
+ "if [ -x \"$(command -v atuin)\" ]; then eval \"$(atuin init {})\"; fi",
+ shell.to_string()
+ );
+ file.write_all(config.as_bytes())
+ .await
+ .map_err(|e| format!("Failed to write Atuin shell init: {e}"));
+
+ Ok(())
+}
diff --git a/ui/backend/src/main.rs b/ui/backend/src/main.rs
index f07e0c95..f03bccda 100644
--- a/ui/backend/src/main.rs
+++ b/ui/backend/src/main.rs
@@ -8,6 +8,7 @@ use time::format_description::well_known::Rfc3339;
mod db;
mod dotfiles;
+mod install;
mod store;
use atuin_client::settings::Settings;
@@ -189,6 +190,9 @@ fn main() {
session,
login,
register,
+ install::install_cli,
+ install::is_cli_installed,
+ install::setup_cli,
dotfiles::aliases::import_aliases,
dotfiles::aliases::delete_alias,
dotfiles::aliases::set_alias,
diff --git a/ui/backend/src/update.rs b/ui/backend/src/update.rs
deleted file mode 100644
index d8cd2255..00000000
--- a/ui/backend/src/update.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// While technically using a "self update" crate, we can actually use the same method
-// for managing a CLI install. Neat!
-// This should still be locked to the same version as the UI. Drift there could lead to issues.
-// In the future we can follow semver and allow for minor version drift.
-
-// If you'd like to follow the conventions of your OS, distro, etc, then I would suggest
-// following the CLI install instructions. This is intended to streamline install UX
-use eyre::{eyre, Result};
-use std::{
- ffi::{OsStr, OsString},
- path::Path,
-};
-
-pub fn install(version: &str, path: &str) -> Result<()> {
- let dir = std::path::PathBuf::from(path);
- std::fs::create_dir_all(path)?;
- let bin = dir.join("atuin");
-
- let releases = self_update::backends::github::ReleaseList::configure()
- .repo_owner("atuinsh")
- .repo_name("atuin")
- .build()?
- .fetch()?;
-
- let release = releases
- .iter()
- .find(|r| r.version == version)
- .ok_or_else(|| eyre!("No release found for version: {}", version))?;
-
- let asset = release
- .asset_for(&self_update::get_target(), None)
- .ok_or_else(|| eyre!("No asset found for target"))?;
-
- let tmp_dir = tempfile::Builder::new().prefix("atuin").tempdir()?;
- let tmp_tarball_path = tmp_dir.path().join(&asset.name);
- let tmp_tarball = std::fs::File::create(&tmp_tarball_path)?;
- println!("{:?}", tmp_tarball_path);
-
- self_update::Download::from_url(&asset.download_url).download_to(&tmp_tarball)?;
-
- let root = asset.name.replace(".tar.gz", "");
- let bin_name = std::path::PathBuf::from(format!("{}/atuin", root,));
-
- self_update::Extract::from_source(&tmp_tarball_path)
- .archive(self_update::ArchiveKind::Tar(Some(
- self_update::Compression::Gz,
- )))
- .extract_file(&bin, &bin_name)?;
-
- Ok(())
-}