diff --git a/Cargo.lock b/Cargo.lock index 53a6c495..31af5cfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,15 +430,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "directories" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" -dependencies = [ - "dirs-sys", -] - [[package]] name = "dirs" version = "4.0.0" @@ -528,6 +519,17 @@ dependencies = [ "syn 2.0.12", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -2062,7 +2064,7 @@ dependencies = [ "clap_mangen", "color-eyre", "console", - "directories", + "etcetera", "futures", "glob", "home", @@ -2070,6 +2072,7 @@ dependencies = [ "libc", "nix 0.24.3", "notify-rust", + "once_cell", "parselnk", "regex", "rust-ini", @@ -2448,12 +2451,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] @@ -2463,7 +2466,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -2472,21 +2484,42 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.2", "windows_aarch64_msvc 0.42.2", "windows_i686_gnu 0.42.2", "windows_i686_msvc 0.42.2", "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.2", "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.39.0" @@ -2499,6 +2532,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.39.0" @@ -2511,6 +2550,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.39.0" @@ -2523,6 +2568,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.39.0" @@ -2535,12 +2586,24 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.39.0" @@ -2553,6 +2616,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winnow" version = "0.3.5" diff --git a/Cargo.toml b/Cargo.toml index b727995d..f8f678a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ path = "src/main.rs" [dependencies] home = "~0.5" -directories = "~4.0" +etcetera = "~0.8" +once_cell = "~1.17" serde = { version = "~1.0", features = ["derive"] } toml = "0.5" which_crate = { version = "~4.1", package = "which" } diff --git a/src/config.rs b/src/config.rs index 42f052bb..278345e3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,7 +10,7 @@ use clap_complete::Shell; use color_eyre::eyre; use color_eyre::eyre::Context; use color_eyre::eyre::Result; -use directories::BaseDirs; +use etcetera::base_strategy::BaseStrategy; use regex::Regex; use serde::Deserialize; use strum::{EnumIter, EnumString, EnumVariantNames, IntoEnumIterator}; @@ -340,17 +340,17 @@ pub struct ConfigFile { no_self_update: Option, } -fn config_directory(base_dirs: &BaseDirs) -> PathBuf { - #[cfg(not(target_os = "macos"))] - return base_dirs.config_dir().to_owned(); +fn config_directory() -> PathBuf { + #[cfg(unix)] + return crate::XDG_DIRS.config_dir(); - #[cfg(target_os = "macos")] - return base_dirs.home_dir().join(".config"); + #[cfg(windows)] + return crate::WINDOWS_DIRS.config_dir(); } impl ConfigFile { - fn ensure(base_dirs: &BaseDirs) -> Result { - let config_directory = config_directory(base_dirs); + fn ensure() -> Result { + let config_directory = config_directory(); let config_path = config_directory.join("topgrade.toml"); @@ -374,11 +374,11 @@ impl ConfigFile { /// Read the configuration file. /// /// If the configuration file does not exist the function returns the default ConfigFile. - fn read(base_dirs: &BaseDirs, config_path: Option) -> Result { + fn read(config_path: Option) -> Result { let config_path = if let Some(path) = config_path { path } else { - Self::ensure(base_dirs)? + Self::ensure()? }; let contents = fs::read_to_string(&config_path).map_err(|e| { @@ -412,8 +412,8 @@ impl ConfigFile { Ok(result) } - fn edit(base_dirs: &BaseDirs) -> Result<()> { - let config_path = Self::ensure(base_dirs)?; + fn edit() -> Result<()> { + let config_path = Self::ensure()?; let editor = editor(); debug!("Editor: {:?}", editor); @@ -567,10 +567,10 @@ impl Config { /// Load the configuration. /// /// The function parses the command line arguments and reading the configuration file. - pub fn load(base_dirs: &BaseDirs, opt: CommandLineArgs) -> Result { - let config_directory = config_directory(base_dirs); + pub fn load(opt: CommandLineArgs) -> Result { + let config_directory = config_directory(); let config_file = if config_directory.is_dir() { - ConfigFile::read(base_dirs, opt.config.clone()).unwrap_or_else(|e| { + ConfigFile::read(opt.config.clone()).unwrap_or_else(|e| { // Inform the user about errors when loading the configuration, // but fallback to the default config to at least attempt to do something tracing::error!("failed to load configuration: {}", e); @@ -597,8 +597,8 @@ impl Config { } /// Launch an editor to edit the configuration - pub fn edit(base_dirs: &BaseDirs) -> Result<()> { - ConfigFile::edit(base_dirs) + pub fn edit() -> Result<()> { + ConfigFile::edit() } /// The list of commands to run before performing any step. diff --git a/src/execution_context.rs b/src/execution_context.rs index 757418c4..b44dbcd2 100644 --- a/src/execution_context.rs +++ b/src/execution_context.rs @@ -5,7 +5,6 @@ use crate::sudo::Sudo; use crate::utils::require_option; use crate::{config::Config, executor::Executor}; use color_eyre::eyre::Result; -use directories::BaseDirs; use std::path::Path; use std::sync::Mutex; @@ -14,7 +13,6 @@ pub struct ExecutionContext<'a> { sudo: Option, git: &'a Git, config: &'a Config, - base_dirs: &'a BaseDirs, /// Name of a tmux session to execute commands in, if any. /// This is used in `./steps/remote/ssh.rs`, where we want to run `topgrade` in a new /// tmux window for each remote. @@ -22,19 +20,12 @@ pub struct ExecutionContext<'a> { } impl<'a> ExecutionContext<'a> { - pub fn new( - run_type: RunType, - sudo: Option, - git: &'a Git, - config: &'a Config, - base_dirs: &'a BaseDirs, - ) -> Self { + pub fn new(run_type: RunType, sudo: Option, git: &'a Git, config: &'a Config) -> Self { Self { run_type, sudo, git, config, - base_dirs, tmux_session: Mutex::new(None), } } @@ -60,10 +51,6 @@ impl<'a> ExecutionContext<'a> { self.config } - pub fn base_dirs(&self) -> &BaseDirs { - self.base_dirs - } - pub fn set_tmux_session(&self, session_name: String) { self.tmux_session.lock().unwrap().replace(session_name); } diff --git a/src/main.rs b/src/main.rs index 1d0652ce..8ffd39c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,19 @@ use std::env; use std::io; +use std::path::PathBuf; use std::process::exit; use std::time::Duration; use clap::CommandFactory; use clap::{crate_version, Parser}; use color_eyre::eyre::Context; -use color_eyre::eyre::{eyre, Result}; +use color_eyre::eyre::Result; use console::Key; +#[cfg(windows)] +use etcetera::base_strategy::Windows; +use etcetera::base_strategy::{BaseStrategy, Xdg}; +use once_cell::sync::Lazy; use tracing::debug; use self::config::{CommandLineArgs, Config, Step}; @@ -36,12 +41,15 @@ mod sudo; mod terminal; mod utils; +pub static HOME_DIR: Lazy = Lazy::new(|| home::home_dir().expect("No home directory")); +pub static XDG_DIRS: Lazy = Lazy::new(|| Xdg::new().expect("No home directory")); +#[cfg(windows)] +pub static WINDOWS_DIRS: Lazy = Lazy::new(|| Windows::new().expect("No home directory")); + fn run() -> Result<()> { color_eyre::install()?; ctrlc::set_handler(); - let base_dirs = directories::BaseDirs::new().ok_or_else(|| eyre!("No base directories"))?; - let opt = CommandLineArgs::parse(); if let Some(shell) = opt.gen_completion { @@ -66,7 +74,7 @@ fn run() -> Result<()> { } if opt.edit_config() { - Config::edit(&base_dirs)?; + Config::edit()?; return Ok(()); }; @@ -75,7 +83,7 @@ fn run() -> Result<()> { return Ok(()); } - let config = Config::load(&base_dirs, opt)?; + let config = Config::load(opt)?; terminal::set_title(config.set_title()); terminal::display_time(config.display_time()); terminal::set_desktop_notifications(config.notify_each_step()); @@ -110,7 +118,7 @@ For more information about this issue see https://askubuntu.com/questions/110969 let sudo = config.sudo_command().map_or_else(sudo::Sudo::detect, sudo::Sudo::new); let run_type = executor::RunType::new(config.dry_run()); - let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config, &base_dirs); + let ctx = execution_context::ExecutionContext::new(run_type, sudo, &git, &config); let mut runner = runner::Runner::new(&ctx); @@ -249,7 +257,7 @@ For more information about this issue see https://askubuntu.com/questions/110969 #[cfg(target_os = "android")] runner.execute(Step::Pkg, "Termux Packages", || android::upgrade_packages(&ctx))?; - let emacs = emacs::Emacs::new(&base_dirs); + let emacs = emacs::Emacs::new(); if config.use_predefined_git_repos() { if config.should_run(Step::Emacs) { if !emacs.is_doom() { @@ -257,43 +265,43 @@ For more information about this issue see https://askubuntu.com/questions/110969 git_repos.insert_if_repo(directory); } } - git_repos.insert_if_repo(base_dirs.home_dir().join(".doom.d")); + git_repos.insert_if_repo(HOME_DIR.join(".doom.d")); } if config.should_run(Step::Vim) { - git_repos.insert_if_repo(base_dirs.home_dir().join(".vim")); - git_repos.insert_if_repo(base_dirs.home_dir().join(".config/nvim")); + git_repos.insert_if_repo(HOME_DIR.join(".vim")); + git_repos.insert_if_repo(HOME_DIR.join(".config/nvim")); } - git_repos.insert_if_repo(base_dirs.home_dir().join(".ideavimrc")); - git_repos.insert_if_repo(base_dirs.home_dir().join(".intellimacs")); + git_repos.insert_if_repo(HOME_DIR.join(".ideavimrc")); + git_repos.insert_if_repo(HOME_DIR.join(".intellimacs")); if config.should_run(Step::Rcm) { - git_repos.insert_if_repo(base_dirs.home_dir().join(".dotfiles")); + git_repos.insert_if_repo(HOME_DIR.join(".dotfiles")); } #[cfg(unix)] { - git_repos.insert_if_repo(zsh::zshrc(&base_dirs)); + git_repos.insert_if_repo(zsh::zshrc()); if config.should_run(Step::Tmux) { - git_repos.insert_if_repo(base_dirs.home_dir().join(".tmux")); + git_repos.insert_if_repo(HOME_DIR.join(".tmux")); } - git_repos.insert_if_repo(base_dirs.home_dir().join(".config/fish")); - git_repos.insert_if_repo(base_dirs.config_dir().join("openbox")); - git_repos.insert_if_repo(base_dirs.config_dir().join("bspwm")); - git_repos.insert_if_repo(base_dirs.config_dir().join("i3")); - git_repos.insert_if_repo(base_dirs.config_dir().join("sway")); + git_repos.insert_if_repo(HOME_DIR.join(".config/fish")); + git_repos.insert_if_repo(XDG_DIRS.config_dir().join("openbox")); + git_repos.insert_if_repo(XDG_DIRS.config_dir().join("bspwm")); + git_repos.insert_if_repo(XDG_DIRS.config_dir().join("i3")); + git_repos.insert_if_repo(XDG_DIRS.config_dir().join("sway")); } #[cfg(windows)] git_repos.insert_if_repo( - base_dirs - .data_local_dir() + WINDOWS_DIRS + .cache_dir() .join("Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState"), ); #[cfg(windows)] - windows::insert_startup_scripts(&ctx, &mut git_repos).ok(); + windows::insert_startup_scripts(&mut git_repos).ok(); if let Some(profile) = powershell.profile() { git_repos.insert_if_repo(profile); @@ -319,31 +327,29 @@ For more information about this issue see https://askubuntu.com/questions/110969 #[cfg(unix)] { - runner.execute(Step::Shell, "zr", || zsh::run_zr(&base_dirs, run_type))?; + runner.execute(Step::Shell, "zr", || zsh::run_zr(run_type))?; runner.execute(Step::Shell, "antibody", || zsh::run_antibody(run_type))?; runner.execute(Step::Shell, "antidote", || zsh::run_antidote(&ctx))?; - runner.execute(Step::Shell, "antigen", || zsh::run_antigen(&base_dirs, run_type))?; - runner.execute(Step::Shell, "zgenom", || zsh::run_zgenom(&base_dirs, run_type))?; - runner.execute(Step::Shell, "zplug", || zsh::run_zplug(&base_dirs, run_type))?; - runner.execute(Step::Shell, "zinit", || zsh::run_zinit(&base_dirs, run_type))?; - runner.execute(Step::Shell, "zi", || zsh::run_zi(&base_dirs, run_type))?; - runner.execute(Step::Shell, "zim", || zsh::run_zim(&base_dirs, run_type))?; + runner.execute(Step::Shell, "antigen", || zsh::run_antigen(run_type))?; + runner.execute(Step::Shell, "zgenom", || zsh::run_zgenom(run_type))?; + runner.execute(Step::Shell, "zplug", || zsh::run_zplug(run_type))?; + runner.execute(Step::Shell, "zinit", || zsh::run_zinit(run_type))?; + runner.execute(Step::Shell, "zi", || zsh::run_zi(run_type))?; + runner.execute(Step::Shell, "zim", || zsh::run_zim(run_type))?; runner.execute(Step::Shell, "oh-my-zsh", || zsh::run_oh_my_zsh(&ctx))?; runner.execute(Step::Shell, "fisher", || unix::run_fisher(run_type))?; runner.execute(Step::Shell, "bash-it", || unix::run_bashit(&ctx))?; runner.execute(Step::Shell, "oh-my-fish", || unix::run_oh_my_fish(&ctx))?; runner.execute(Step::Shell, "fish-plug", || unix::run_fish_plug(&ctx))?; runner.execute(Step::Shell, "fundle", || unix::run_fundle(&ctx))?; - runner.execute(Step::Tmux, "tmux", || tmux::run_tpm(&base_dirs, run_type))?; + runner.execute(Step::Tmux, "tmux", || tmux::run_tpm(run_type))?; runner.execute(Step::Tldr, "TLDR", || unix::run_tldr(run_type))?; runner.execute(Step::Pearl, "pearl", || unix::run_pearl(run_type))?; #[cfg(not(any(target_os = "macos", target_os = "android")))] runner.execute(Step::GnomeShellExtensions, "Gnome Shell Extensions", || { unix::upgrade_gnome_extensions(&ctx) })?; - runner.execute(Step::Sdkman, "SDKMAN!", || { - unix::run_sdkman(&base_dirs, config.cleanup(), run_type) - })?; + runner.execute(Step::Sdkman, "SDKMAN!", || unix::run_sdkman(config.cleanup(), run_type))?; runner.execute(Step::Rcm, "rcm", || unix::run_rcm(&ctx))?; } @@ -356,7 +362,7 @@ For more information about this issue see https://askubuntu.com/questions/110969 runner.execute(Step::Atom, "apm", || generic::run_apm(run_type))?; runner.execute(Step::Fossil, "fossil", || generic::run_fossil(run_type))?; runner.execute(Step::Rustup, "rustup", || generic::run_rustup(&ctx))?; - runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(&base_dirs, run_type))?; + runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(run_type))?; runner.execute(Step::Dotnet, ".NET", || generic::run_dotnet_upgrade(&ctx))?; runner.execute(Step::Choosenim, "choosenim", || generic::run_choosenim(&ctx))?; runner.execute(Step::Cargo, "cargo", || generic::run_cargo_update(&ctx))?; @@ -375,17 +381,13 @@ For more information about this issue see https://askubuntu.com/questions/110969 runner.execute(Step::Ghcup, "ghcup", || generic::run_ghcup_update(run_type))?; runner.execute(Step::Stack, "stack", || generic::run_stack_update(run_type))?; runner.execute(Step::Tlmgr, "tlmgr", || generic::run_tlmgr_update(&ctx))?; - runner.execute(Step::Myrepos, "myrepos", || { - generic::run_myrepos_update(&base_dirs, run_type) - })?; - runner.execute(Step::Chezmoi, "chezmoi", || { - generic::run_chezmoi_update(&base_dirs, run_type) - })?; + runner.execute(Step::Myrepos, "myrepos", || generic::run_myrepos_update(run_type))?; + runner.execute(Step::Chezmoi, "chezmoi", || generic::run_chezmoi_update(run_type))?; runner.execute(Step::Jetpack, "jetpack", || generic::run_jetpack(run_type))?; - runner.execute(Step::Vim, "vim", || vim::upgrade_vim(&base_dirs, &ctx))?; - runner.execute(Step::Vim, "Neovim", || vim::upgrade_neovim(&base_dirs, &ctx))?; + runner.execute(Step::Vim, "vim", || vim::upgrade_vim(&ctx))?; + runner.execute(Step::Vim, "Neovim", || vim::upgrade_neovim(&ctx))?; runner.execute(Step::Vim, "The Ultimate vimrc", || vim::upgrade_ultimate_vimrc(&ctx))?; - runner.execute(Step::Vim, "voom", || vim::run_voom(&base_dirs, run_type))?; + runner.execute(Step::Vim, "voom", || vim::run_voom(run_type))?; runner.execute(Step::Kakoune, "Kakoune", || kakoune::upgrade_kak_plug(&ctx))?; runner.execute(Step::Helix, "helix", || generic::run_helix_grammars(&ctx))?; runner.execute(Step::Node, "npm", || node::run_npm_upgrade(&ctx))?; @@ -396,7 +398,7 @@ For more information about this issue see https://askubuntu.com/questions/110969 runner.execute(Step::Composer, "composer", || generic::run_composer_update(&ctx))?; runner.execute(Step::Krew, "krew", || generic::run_krew_upgrade(run_type))?; runner.execute(Step::Helm, "helm", || generic::run_helm_repo_update(run_type))?; - runner.execute(Step::Gem, "gem", || generic::run_gem(&base_dirs, run_type))?; + runner.execute(Step::Gem, "gem", || generic::run_gem(run_type))?; runner.execute(Step::RubyGems, "rubygems", || generic::run_rubygems(&ctx))?; runner.execute(Step::Julia, "julia", || generic::update_julia_packages(&ctx))?; runner.execute(Step::Haxelib, "haxelib", || generic::run_haxelib_update(&ctx))?; diff --git a/src/steps/emacs.rs b/src/steps/emacs.rs index 89e04885..4819ad75 100644 --- a/src/steps/emacs.rs +++ b/src/steps/emacs.rs @@ -1,9 +1,9 @@ -#[cfg(any(windows, target_os = "macos"))] +#[cfg(any(windows))] use std::env; use std::path::{Path, PathBuf}; use color_eyre::eyre::Result; -use directories::BaseDirs; +use etcetera::base_strategy::BaseStrategy; use crate::command::CommandExt; use crate::execution_context::ExecutionContext; @@ -23,20 +23,12 @@ pub struct Emacs { } impl Emacs { - fn directory_path(base_dirs: &BaseDirs) -> Option { + fn directory_path() -> Option { #[cfg(unix)] - cfg_if::cfg_if! { - if #[cfg(target_os = "macos")] { - let emacs_xdg_dir = env::var("XDG_CONFIG_HOME") - .ok() - .and_then(|config| PathBuf::from(config).join("emacs").if_exists()) - .or_else(|| base_dirs.home_dir().join(".config/emacs").if_exists()); - } else { - let emacs_xdg_dir = base_dirs.config_dir().join("emacs").if_exists(); - } - } - #[cfg(unix)] - return base_dirs.home_dir().join(".emacs.d").if_exists().or(emacs_xdg_dir); + return { + let emacs_xdg_dir = crate::XDG_DIRS.config_dir().join("emacs").if_exists(); + crate::HOME_DIR.join(".emacs.d").if_exists().or(emacs_xdg_dir) + }; #[cfg(windows)] return env::var("HOME") @@ -47,11 +39,11 @@ impl Emacs { .if_exists() .or_else(|| PathBuf::from(&home).join(".config\\emacs").if_exists()) }) - .or_else(|| base_dirs.data_dir().join(".emacs.d").if_exists()); + .or_else(|| crate::WINDOWS_DIRS.data_dir().join(".emacs.d").if_exists()); } - pub fn new(base_dirs: &BaseDirs) -> Self { - let directory = Emacs::directory_path(base_dirs); + pub fn new() -> Self { + let directory = Emacs::directory_path(); let doom = directory.as_ref().and_then(|d| d.join(DOOM_PATH).if_exists()); Self { directory, doom } } diff --git a/src/steps/generic.rs b/src/steps/generic.rs index d75d46a9..ed1ff033 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -8,7 +8,6 @@ use std::{fs, io::Write}; use color_eyre::eyre::eyre; use color_eyre::eyre::Context; use color_eyre::eyre::Result; -use directories::BaseDirs; use tempfile::tempfile_in; use tracing::{debug, error}; @@ -18,6 +17,7 @@ use crate::executor::{ExecutorOutput, RunType}; use crate::terminal::{print_separator, shell}; use crate::utils::{self, require, require_option, which, PathExt}; use crate::Step; +use crate::HOME_DIR; use crate::{ error::{SkipStep, StepFailed, TopgradeError}, terminal::print_warning, @@ -26,7 +26,7 @@ use crate::{ pub fn run_cargo_update(ctx: &ExecutionContext) -> Result<()> { let cargo_dir = env::var_os("CARGO_HOME") .map(PathBuf::from) - .unwrap_or_else(|| ctx.base_dirs().home_dir().join(".cargo")) + .unwrap_or_else(|| HOME_DIR.join(".cargo")) .require()?; utils::require("cargo").or_else(|_| { require_option( @@ -84,9 +84,9 @@ pub fn run_flutter_upgrade(run_type: RunType) -> Result<()> { run_type.execute(flutter).arg("upgrade").status_checked() } -pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_gem(run_type: RunType) -> Result<()> { let gem = utils::require("gem")?; - base_dirs.home_dir().join(".gem").require()?; + HOME_DIR.join(".gem").require()?; print_separator("Gems"); @@ -102,7 +102,7 @@ pub fn run_gem(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { } pub fn run_rubygems(ctx: &ExecutionContext) -> Result<()> { - ctx.base_dirs().home_dir().join(".gem").require()?; + HOME_DIR.join(".gem").require()?; let gem = require("gem")?; print_separator("RubyGems"); @@ -214,12 +214,12 @@ pub fn run_rustup(ctx: &ExecutionContext) -> Result<()> { ctx.run_type().execute(rustup).arg("update").status_checked() } -pub fn run_juliaup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_juliaup(run_type: RunType) -> Result<()> { let juliaup = utils::require("juliaup")?; print_separator("juliaup"); - if juliaup.canonicalize()?.is_descendant_of(base_dirs.home_dir()) { + if juliaup.canonicalize()?.is_descendant_of(&HOME_DIR) { run_type.execute(&juliaup).args(["self", "update"]).status_checked()?; } @@ -493,31 +493,31 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> { command.status_checked() } -pub fn run_chezmoi_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_chezmoi_update(run_type: RunType) -> Result<()> { let chezmoi = utils::require("chezmoi")?; - base_dirs.home_dir().join(".local/share/chezmoi").require()?; + HOME_DIR.join(".local/share/chezmoi").require()?; print_separator("chezmoi"); run_type.execute(chezmoi).arg("update").status_checked() } -pub fn run_myrepos_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_myrepos_update(run_type: RunType) -> Result<()> { let myrepos = utils::require("mr")?; - base_dirs.home_dir().join(".mrconfig").require()?; + HOME_DIR.join(".mrconfig").require()?; print_separator("myrepos"); run_type .execute(&myrepos) .arg("--directory") - .arg(base_dirs.home_dir()) + .arg(&*HOME_DIR) .arg("checkout") .status_checked()?; run_type .execute(&myrepos) .arg("--directory") - .arg(base_dirs.home_dir()) + .arg(&*HOME_DIR) .arg("update") .status_checked() } @@ -544,7 +544,7 @@ pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> { .map(|s| PathBuf::from(s.stdout.trim()))? .require()?; - if !composer_home.is_descendant_of(ctx.base_dirs().home_dir()) { + if !composer_home.is_descendant_of(&HOME_DIR) { return Err(SkipStep(format!( "Composer directory {} isn't a decandent of the user's home directory", composer_home.display() diff --git a/src/steps/node.rs b/src/steps/node.rs index f1e2e89d..371683b4 100644 --- a/src/steps/node.rs +++ b/src/steps/node.rs @@ -5,6 +5,7 @@ use std::path::PathBuf; use std::process::Command; use crate::utils::require_option; +use crate::HOME_DIR; use color_eyre::eyre::Result; #[cfg(target_os = "linux")] use nix::unistd::Uid; @@ -265,7 +266,7 @@ pub fn run_yarn_upgrade(ctx: &ExecutionContext) -> Result<()> { pub fn deno_upgrade(ctx: &ExecutionContext) -> Result<()> { let deno = require("deno")?; - let deno_dir = ctx.base_dirs().home_dir().join(".deno"); + let deno_dir = HOME_DIR.join(".deno"); if !deno.canonicalize()?.is_descendant_of(&deno_dir) { let skip_reason = SkipStep("Deno installed outside of .deno directory".to_string()); diff --git a/src/steps/os/unix.rs b/src/steps/os/unix.rs index b96631f0..6f5b6a70 100644 --- a/src/steps/os/unix.rs +++ b/src/steps/os/unix.rs @@ -5,9 +5,8 @@ use std::process::Command; use std::{env, path::Path}; use crate::command::CommandExt; -use crate::Step; +use crate::{Step, HOME_DIR}; use color_eyre::eyre::Result; -use directories::BaseDirs; use home; use ini::Ini; use tracing::debug; @@ -127,7 +126,7 @@ pub fn run_fisher(run_type: RunType) -> Result<()> { } pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> { - ctx.base_dirs().home_dir().join(".bash_it").require()?; + HOME_DIR.join(".bash_it").require()?; print_separator("Bash-it"); @@ -139,10 +138,7 @@ pub fn run_bashit(ctx: &ExecutionContext) -> Result<()> { pub fn run_oh_my_fish(ctx: &ExecutionContext) -> Result<()> { let fish = require("fish")?; - ctx.base_dirs() - .home_dir() - .join(".local/share/omf/pkg/omf/functions/omf.fish") - .require()?; + HOME_DIR.join(".local/share/omf/pkg/omf/functions/omf.fish").require()?; print_separator("oh-my-fish"); @@ -171,8 +167,7 @@ pub fn run_pkgin(ctx: &ExecutionContext) -> Result<()> { pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> { let fish = require("fish")?; - ctx.base_dirs() - .home_dir() + HOME_DIR .join(".local/share/fish/plug/kidonng/fish-plug/functions/plug.fish") .require()?; @@ -191,7 +186,7 @@ pub fn run_fish_plug(ctx: &ExecutionContext) -> Result<()> { /// See: pub fn run_fundle(ctx: &ExecutionContext) -> Result<()> { let fish = require("fish")?; - ctx.base_dirs().home_dir().join(".config/fish/fundle").require()?; + HOME_DIR.join(".config/fish/fundle").require()?; print_separator("fundle"); @@ -335,6 +330,7 @@ pub fn run_nix(ctx: &ExecutionContext) -> Result<()> { let nix = require("nix")?; let nix_channel = require("nix-channel")?; let nix_env = require("nix-env")?; + // TODO: Is None possible here? let profile_path = match home::home_dir() { Some(home) => Path::new(&home).join(".nix-profile"), None => Path::new("/nix/var/nix/profiles/per-user/default").into(), @@ -435,12 +431,12 @@ pub fn run_pearl(run_type: RunType) -> Result<()> { run_type.execute(pearl).arg("update").status_checked() } -pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Result<()> { +pub fn run_sdkman(cleanup: bool, run_type: RunType) -> Result<()> { let bash = require("bash")?; let sdkman_init_path = env::var("SDKMAN_DIR") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".sdkman")) + .unwrap_or_else(|_| HOME_DIR.join(".sdkman")) .join("bin") .join("sdkman-init.sh") .require() @@ -450,7 +446,7 @@ pub fn run_sdkman(base_dirs: &BaseDirs, cleanup: bool, run_type: RunType) -> Res let sdkman_config_path = env::var("SDKMAN_DIR") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".sdkman")) + .unwrap_or_else(|_| HOME_DIR.join(".sdkman")) .join("etc") .join("config") .require()?; diff --git a/src/steps/os/windows.rs b/src/steps/os/windows.rs index 911a0d2f..dc43b3e4 100644 --- a/src/steps/os/windows.rs +++ b/src/steps/os/windows.rs @@ -3,6 +3,7 @@ use std::path::Path; use std::{ffi::OsStr, process::Command}; use color_eyre::eyre::Result; +use etcetera::base_strategy::BaseStrategy; use tracing::debug; use crate::command::CommandExt; @@ -164,9 +165,8 @@ pub fn reboot() -> Result<()> { Command::new("shutdown").args(["/R", "/T", "0"]).status_checked() } -pub fn insert_startup_scripts(ctx: &ExecutionContext, git_repos: &mut Repositories) -> Result<()> { - let startup_dir = ctx - .base_dirs() +pub fn insert_startup_scripts(git_repos: &mut Repositories) -> Result<()> { + let startup_dir = crate::WINDOWS_DIRS .data_dir() .join("Microsoft\\Windows\\Start Menu\\Programs\\Startup"); for entry in std::fs::read_dir(&startup_dir)?.flatten() { diff --git a/src/steps/tmux.rs b/src/steps/tmux.rs index 61d3bb46..984e1557 100644 --- a/src/steps/tmux.rs +++ b/src/steps/tmux.rs @@ -5,11 +5,11 @@ use std::process::Command; use color_eyre::eyre::eyre; use color_eyre::eyre::Context; use color_eyre::eyre::Result; -use directories::BaseDirs; use crate::command::CommandExt; use crate::executor::RunType; use crate::terminal::print_separator; +use crate::HOME_DIR; use crate::{ execution_context::ExecutionContext, utils::{which, PathExt}, @@ -18,11 +18,8 @@ use crate::{ #[cfg(unix)] use std::os::unix::process::CommandExt as _; -pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { - let tpm = base_dirs - .home_dir() - .join(".tmux/plugins/tpm/bin/update_plugins") - .require()?; +pub fn run_tpm(run_type: RunType) -> Result<()> { + let tpm = HOME_DIR.join(".tmux/plugins/tpm/bin/update_plugins").require()?; print_separator("tmux plugins"); diff --git a/src/steps/vim.rs b/src/steps/vim.rs index 42b1a389..be9e87d3 100644 --- a/src/steps/vim.rs +++ b/src/steps/vim.rs @@ -1,6 +1,8 @@ use crate::command::CommandExt; use crate::error::{SkipStep, TopgradeError}; +use crate::HOME_DIR; use color_eyre::eyre::Result; +use etcetera::base_strategy::BaseStrategy; use crate::executor::{Executor, ExecutorOutput, RunType}; use crate::terminal::print_separator; @@ -8,7 +10,6 @@ use crate::{ execution_context::ExecutionContext, utils::{require, PathExt}, }; -use directories::BaseDirs; use std::path::PathBuf; use std::{ io::{self, Write}, @@ -18,22 +19,19 @@ use tracing::debug; const UPGRADE_VIM: &str = include_str!("upgrade.vim"); -pub fn vimrc(base_dirs: &BaseDirs) -> Result { - base_dirs - .home_dir() +pub fn vimrc() -> Result { + HOME_DIR .join(".vimrc") .require() - .or_else(|_| base_dirs.home_dir().join(".vim/vimrc").require()) + .or_else(|_| HOME_DIR.join(".vim/vimrc").require()) } -fn nvimrc(base_dirs: &BaseDirs) -> Result { +fn nvimrc() -> Result { #[cfg(unix)] - let base_dir = - // Bypass directories crate as nvim doesn't use the macOS-specific directories. - std::env::var_os("XDG_CONFIG_HOME").map_or_else(|| base_dirs.home_dir().join(".config"), PathBuf::from); + let base_dir = crate::XDG_DIRS.config_dir(); #[cfg(windows)] - let base_dir = base_dirs.cache_dir(); + let base_dir = crate::WINDOWS_DIRS.cache_dir(); base_dir .join("nvim/init.vim") @@ -74,7 +72,7 @@ fn upgrade(command: &mut Executor, ctx: &ExecutionContext) -> Result<()> { } pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> { - let config_dir = ctx.base_dirs().home_dir().join(".vim_runtime").require()?; + let config_dir = HOME_DIR.join(".vim_runtime").require()?; let git = require("git")?; let python = require("python3")?; let update_plugins = config_dir.join("update_plugins.py").require()?; @@ -105,7 +103,7 @@ pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> { Ok(()) } -pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> { +pub fn upgrade_vim(ctx: &ExecutionContext) -> Result<()> { let vim = require("vim")?; let output = Command::new(&vim).arg("--version").output_checked_utf8()?; @@ -113,7 +111,7 @@ pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> { return Err(SkipStep(String::from("vim binary might be actually nvim")).into()); } - let vimrc = vimrc(base_dirs)?; + let vimrc = vimrc()?; print_separator("Vim"); upgrade( @@ -127,9 +125,9 @@ pub fn upgrade_vim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> { ) } -pub fn upgrade_neovim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<()> { +pub fn upgrade_neovim(ctx: &ExecutionContext) -> Result<()> { let nvim = require("nvim")?; - let nvimrc = nvimrc(base_dirs)?; + let nvimrc = nvimrc()?; print_separator("Neovim"); upgrade( @@ -143,7 +141,7 @@ pub fn upgrade_neovim(base_dirs: &BaseDirs, ctx: &ExecutionContext) -> Result<() ) } -pub fn run_voom(_base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_voom(run_type: RunType) -> Result<()> { let voom = require("voom")?; print_separator("voom"); diff --git a/src/steps/zsh.rs b/src/steps/zsh.rs index 9f4c7251..2b34f0ba 100644 --- a/src/steps/zsh.rs +++ b/src/steps/zsh.rs @@ -3,7 +3,6 @@ use std::path::PathBuf; use std::process::Command; use color_eyre::eyre::Result; -use directories::BaseDirs; use tracing::debug; use walkdir::WalkDir; @@ -13,31 +12,32 @@ use crate::executor::RunType; use crate::git::Repositories; use crate::terminal::print_separator; use crate::utils::{require, PathExt}; +use crate::HOME_DIR; -pub fn run_zr(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zr(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; require("zr")?; print_separator("zr"); - let cmd = format!("source {} && zr --update", zshrc(base_dirs).display()); + let cmd = format!("source {} && zr --update", zshrc().display()); run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked() } -fn zdotdir(base_dirs: &BaseDirs) -> PathBuf { +fn zdotdir() -> PathBuf { env::var("ZDOTDIR") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().to_path_buf()) + .unwrap_or_else(|_| HOME_DIR.clone()) } -pub fn zshrc(base_dirs: &BaseDirs) -> PathBuf { - zdotdir(base_dirs).join(".zshrc") +pub fn zshrc() -> PathBuf { + zdotdir().join(".zshrc") } pub fn run_antidote(ctx: &ExecutionContext) -> Result<()> { let zsh = require("zsh")?; - let mut antidote = zdotdir(ctx.base_dirs()).join(".antidote").require()?; + let mut antidote = zdotdir().join(".antidote").require()?; antidote.push("antidote.zsh"); print_separator("antidote"); @@ -58,12 +58,12 @@ pub fn run_antibody(run_type: RunType) -> Result<()> { run_type.execute(antibody).arg("update").status_checked() } -pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_antigen(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; - let zshrc = zshrc(base_dirs).require()?; + let zshrc = zshrc().require()?; env::var("ADOTDIR") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join("antigen.zsh")) + .unwrap_or_else(|_| HOME_DIR.join("antigen.zsh")) .require()?; print_separator("antigen"); @@ -72,12 +72,12 @@ pub fn run_antigen(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked() } -pub fn run_zgenom(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zgenom(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; - let zshrc = zshrc(base_dirs).require()?; + let zshrc = zshrc().require()?; env::var("ZGEN_SOURCE") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".zgenom")) + .unwrap_or_else(|_| HOME_DIR.join(".zgenom")) .require()?; print_separator("zgenom"); @@ -86,13 +86,13 @@ pub fn run_zgenom(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { run_type.execute(zsh).args(["-l", "-c", cmd.as_str()]).status_checked() } -pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zplug(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; - zshrc(base_dirs).require()?; + zshrc().require()?; env::var("ZPLUG_HOME") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".zplug")) + .unwrap_or_else(|_| HOME_DIR.join(".zplug")) .require()?; print_separator("zplug"); @@ -103,13 +103,13 @@ pub fn run_zplug(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { .status_checked() } -pub fn run_zinit(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zinit(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; - let zshrc = zshrc(base_dirs).require()?; + let zshrc = zshrc().require()?; env::var("ZINIT_HOME") .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".zinit")) + .unwrap_or_else(|_| HOME_DIR.join(".zinit")) .require()?; print_separator("zinit"); @@ -118,11 +118,11 @@ pub fn run_zinit(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { run_type.execute(zsh).args(["-i", "-c", cmd.as_str()]).status_checked() } -pub fn run_zi(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zi(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; - let zshrc = zshrc(base_dirs).require()?; + let zshrc = zshrc().require()?; - base_dirs.home_dir().join(".zi").require()?; + HOME_DIR.join(".zi").require()?; print_separator("zi"); @@ -130,7 +130,7 @@ pub fn run_zi(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { run_type.execute(zsh).args(["-i", "-c", &cmd]).status_checked() } -pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { +pub fn run_zim(run_type: RunType) -> Result<()> { let zsh = require("zsh")?; env::var("ZIM_HOME") .or_else(|_| { @@ -141,7 +141,7 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { .map(|o| o.stdout) }) .map(PathBuf::from) - .unwrap_or_else(|_| base_dirs.home_dir().join(".zim")) + .unwrap_or_else(|_| HOME_DIR.join(".zim")) .require()?; print_separator("zim"); @@ -154,7 +154,7 @@ pub fn run_zim(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> { pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> { require("zsh")?; - let oh_my_zsh = ctx.base_dirs().home_dir().join(".oh-my-zsh").require()?; + let oh_my_zsh = HOME_DIR.join(".oh-my-zsh").require()?; print_separator("oh-my-zsh");