From 79e772f88ba4b7505487e74a72d32d1d8ddb0184 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Thu, 21 Dec 2023 15:13:54 +0100 Subject: [PATCH] Add util module, with functions for handling install-id --- Cargo.lock | 21 ++++++++++++++++++ Cargo.toml | 1 + src/util.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 src/util.rs diff --git a/Cargo.lock b/Cargo.lock index ddfb849..0a28d56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,7 @@ dependencies = [ "signal-hook", "signal-hook-mio", "termion", + "uuid", ] [[package]] @@ -135,6 +136,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.4.1" @@ -332,6 +344,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index b652b47..e1236c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ serde_json = "1.0.107" clap = { version = "4.4.7", features = ["derive"] } signal-hook-mio = { version = "0.2.3", features = ["support-v0_8"] } signal-hook = "0.3.17" +uuid = { version = "1.6.1", features = ["v4"] } diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..e793258 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,63 @@ +use anyhow::{anyhow, bail, Result}; +use std::{env, fs, io::ErrorKind, path::Path, path::PathBuf}; +use uuid::Uuid; + +pub fn get_install_id() -> Result { + let default_path = state_home()?.join("install-id"); + let legacy_path = config_home()?.join("install-id"); + + if let Some(install_id) = read_install_id(&default_path)? { + Ok(install_id) + } else if let Some(install_id) = read_install_id(&legacy_path)? { + Ok(install_id) + } else { + create_install_id(&default_path) + } +} + +fn read_install_id(path: &PathBuf) -> Result> { + match fs::read_to_string(path) { + Ok(s) => Ok(Some(s.trim().to_string())), + + Err(e) => { + if e.kind() == ErrorKind::NotFound { + Ok(None) + } else { + bail!(e) + } + } + } +} + +fn create_install_id(path: &PathBuf) -> Result { + let id = Uuid::new_v4().to_string(); + + if let Some(dir) = path.parent() { + fs::create_dir_all(dir)?; + } + + fs::write(path, &id)?; + + Ok(id) +} + +fn config_home() -> Result { + env::var("ASCIINEMA_CONFIG_HOME") + .map(PathBuf::from) + .or(env::var("XDG_CONFIG_HOME").map(|home| Path::new(&home).join("asciinema"))) + .or(env::var("HOME").map(|home| Path::new(&home).join(".config").join("asciinema"))) + .map_err(|_| anyhow!("need $HOME or $XDG_CONFIG_HOME or $ASCIINEMA_CONFIG_HOME")) +} + +fn state_home() -> Result { + env::var("ASCIINEMA_STATE_HOME") + .map(PathBuf::from) + .or(env::var("XDG_STATE_HOME").map(|home| Path::new(&home).join("asciinema"))) + .or(env::var("HOME").map(|home| { + Path::new(&home) + .join(".local") + .join("state") + .join("asciinema") + })) + .map_err(|_| anyhow!("need $HOME or $XDG_STATE_HOME or $ASCIINEMA_STATE_HOME")) +}